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
45c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbarnamespace {
46bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// FIXME: We should find a nicer way to make the labels for metadata, string
486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// concatenation is lame.
496efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
50ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass ObjCCommonTypesHelper {
51a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Andersonprotected:
52a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  llvm::LLVMContext &VMContext;
536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
54d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanianprivate:
550774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  // The types of these functions don't really matter because we
560774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  // should always bitcast before calling them.
570774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall
580774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// id objc_msgSend (id, SEL, ...)
590774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
600774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The default messenger, used for sends whose ABI is unchanged from
610774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// the all-integer/pointer case.
62d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendFn() const {
63f85e193739c953358c865005855253af4f68a497John McCall    // Add the non-lazy-bind attribute, since objc_msgSend is likely to
64f85e193739c953358c865005855253af4f68a497John McCall    // be called a lot.
659cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
660774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
670774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
68f85e193739c953358c865005855253af4f68a497John McCall                                     "objc_msgSend",
69f85e193739c953358c865005855253af4f68a497John McCall                                     llvm::Attribute::NonLazyBind);
70d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
720774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// void objc_msgSend_stret (id, SEL, ...)
730774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
740774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The messenger used when the return value is an aggregate returned
750774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// by indirect reference in the first argument, and therefore the
760774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// self and selector parameters are shifted over by one.
77d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendStretFn() const {
789cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
790774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
800774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
810774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "objc_msgSend_stret");
826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
83d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
850774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
860774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
870774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The messenger used when the return value is returned on the x87
880774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// floating-point stack; without a special entrypoint, the nil case
890774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// would be unbalanced.
90d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendFpretFn() const {
919cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
928b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
938b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner                                                             params, true),
940774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "objc_msgSend_fpret");
956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
96d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
98eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
99eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  ///
100eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  /// The messenger used when the return value is returned in two values on the
101eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  /// x87 floating point stack; without a special entrypoint, the nil case
102eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  /// would be unbalanced. Only used on 64-bit X86.
103eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  llvm::Constant *getMessageSendFp2retFn() const {
104eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
105eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson    llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
106eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson    llvm::Type *resultType =
107eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson      llvm::StructType::get(longDoubleType, longDoubleType, NULL);
108eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson
109eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
110eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson                                                             params, true),
111eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson                                     "objc_msgSend_fp2ret");
112eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  }
113eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson
1140774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
1150774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
1160774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The messenger used for super calls, which have different dispatch
1170774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// semantics.  The class passed is the superclass of the current
1180774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// class.
119d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperFn() const {
1209cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
12196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
1220774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
1230774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "objc_msgSendSuper");
124d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1260774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
1270774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
1280774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// A slightly different messenger used for super calls.  The class
1290774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// passed is the current class.
130d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperFn2() const {
1319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
13296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
1330774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
1340774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                     "objc_msgSendSuper2");
135d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1370774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
1380774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///                              SEL op, ...)
1390774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
1400774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// The messenger used for super calls which return an aggregate indirectly.
141d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperStretFn() const {
1429cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
143a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return CGM.CreateRuntimeFunction(
1440774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, params, true),
1456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_msgSendSuper_stret");
146d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1480774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
1490774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///                               SEL op, ...)
1500774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ///
1510774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  /// objc_msgSendSuper_stret with the super2 semantics.
152d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperStretFn2() const {
1539cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
154a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return CGM.CreateRuntimeFunction(
1550774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, params, true),
1566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_msgSendSuper2_stret");
157d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
159d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperFpretFn() const {
160d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    // There is no objc_msgSendSuper_fpret? How can that work?
161d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return getMessageSendSuperFn();
162d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
164d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getMessageSendSuperFpretFn2() const {
165d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    // There is no objc_msgSendSuper_fpret? How can that work?
166d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return getMessageSendSuperFn2();
167d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
1686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
169ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprotected:
170ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  CodeGen::CodeGenModule &CGM;
1716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
172bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarpublic:
1739cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
174dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
1756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1762bedbf8549bb33293c6a53e5da6cbd8de290d014Daniel Dunbar  /// ObjectPtrTy - LLVM type for object handles (typeof(id))
1779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ObjectPtrTy;
1786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1796d657c4809d9128be88705d32768de007b988212Fariborz Jahanian  /// PtrObjectPtrTy - LLVM type for id *
1809cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *PtrObjectPtrTy;
1816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1824e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
1839cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *SelectorPtrTy;
1844c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor
1854c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregorprivate:
1866efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolPtrTy - LLVM type for external protocol handles
1876efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// (typeof(Protocol))
1889cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ExternalProtocolPtrTy;
1894c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor
1904c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregorpublic:
1914c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor  llvm::Type *getExternalProtocolPtrTy() {
1924c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor    if (!ExternalProtocolPtrTy) {
1934c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor      // FIXME: It would be nice to unify this with the opaque type, so that the
1944c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor      // IR comes out a bit cleaner.
1954c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor      CodeGen::CodeGenTypes &Types = CGM.getTypes();
1964c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor      ASTContext &Ctx = CGM.getContext();
1974c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor      llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1984c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor      ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
1994c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor    }
2004c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor
2014c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor    return ExternalProtocolPtrTy;
2024c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor  }
2034c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor
20419cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  // SuperCTy - clang type for struct objc_super.
20519cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  QualType SuperCTy;
20619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  // SuperPtrCTy - clang type for struct objc_super *.
20719cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  QualType SuperPtrCTy;
2086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
209e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar  /// SuperTy - LLVM type for struct objc_super.
2109cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *SuperTy;
21114c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar  /// SuperPtrTy - LLVM type for struct objc_super *.
2129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *SuperPtrTy;
2136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
21430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
21530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// in GCC parlance).
2169cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *PropertyTy;
2176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
21830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// PropertyListTy - LLVM type for struct objc_property_list
21930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// (_prop_list_t in GCC parlance).
2209cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *PropertyListTy;
22130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
2229cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *PropertyListPtrTy;
2236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
22430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // MethodTy - LLVM type for struct objc_method.
2259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MethodTy;
2266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
227d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  /// CacheTy - LLVM type for struct objc_cache.
2289cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *CacheTy;
229d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  /// CachePtrTy - LLVM type for struct objc_cache *.
2309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *CachePtrTy;
2319d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
23272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Constant *getGetPropertyFn() {
23372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    CodeGen::CodeGenTypes &Types = CGM.getTypes();
23472db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    ASTContext &Ctx = CGM.getContext();
23572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    // id objc_getProperty (id, SEL, ptrdiff_t, bool)
2365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CanQualType,4> Params;
237ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
238ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
23972db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(IdType);
24072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(SelType);
241ab5824e97666ca7a91ed3013524cee18420866f1David Chisnall    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
24272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(Ctx.BoolTy);
2432acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *FTy =
2440f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(IdType, Params,
2450f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                    FunctionType::ExtInfo(),
2460f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                          RequiredArgs::All));
24772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
24872db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  }
2496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
25072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Constant *getSetPropertyFn() {
25172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    CodeGen::CodeGenTypes &Types = CGM.getTypes();
25272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    ASTContext &Ctx = CGM.getContext();
25372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
2545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CanQualType,6> Params;
255ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
256ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
25772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(IdType);
25872db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(SelType);
259ab5824e97666ca7a91ed3013524cee18420866f1David Chisnall    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
26072db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(IdType);
26172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(Ctx.BoolTy);
26272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    Params.push_back(Ctx.BoolTy);
2632acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *FTy =
2640f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
2650f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                     FunctionType::ExtInfo(),
2660f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                          RequiredArgs::All));
26772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
26872db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  }
2696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
270ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
271ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    CodeGen::CodeGenTypes &Types = CGM.getTypes();
272ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    ASTContext &Ctx = CGM.getContext();
273ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // void objc_setProperty_atomic(id self, SEL _cmd,
274ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    //                              id newValue, ptrdiff_t offset);
275ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // void objc_setProperty_nonatomic(id self, SEL _cmd,
276ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    //                                 id newValue, ptrdiff_t offset);
277ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // void objc_setProperty_atomic_copy(id self, SEL _cmd,
278ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    //                                   id newValue, ptrdiff_t offset);
279ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
280ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    //                                      id newValue, ptrdiff_t offset);
281ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
282ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    SmallVector<CanQualType,4> Params;
283ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
284ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
285ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    Params.push_back(IdType);
286ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    Params.push_back(SelType);
287ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    Params.push_back(IdType);
288ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
289ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    llvm::FunctionType *FTy =
2900f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
2910f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                        FunctionType::ExtInfo(),
2920f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                        RequiredArgs::All));
293ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    const char *name;
294ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (atomic && copy)
295ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      name = "objc_setProperty_atomic_copy";
296ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    else if (atomic && !copy)
297ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      name = "objc_setProperty_atomic";
298ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    else if (!atomic && copy)
299ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      name = "objc_setProperty_nonatomic_copy";
300ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    else
301ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      name = "objc_setProperty_nonatomic";
302ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
303ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return CGM.CreateRuntimeFunction(FTy, name);
304ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  }
3056cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
3066cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian  llvm::Constant *getCopyStructFn() {
3076cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    CodeGen::CodeGenTypes &Types = CGM.getTypes();
3086cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    ASTContext &Ctx = CGM.getContext();
3096cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    // void objc_copyStruct (void *, const void *, size_t, bool, bool)
3105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CanQualType,5> Params;
3116cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.VoidPtrTy);
3126cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.VoidPtrTy);
3136cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.LongTy);
3146cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.BoolTy);
3156cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    Params.push_back(Ctx.BoolTy);
3162acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *FTy =
3170f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
3180f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                     FunctionType::ExtInfo(),
3190f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                          RequiredArgs::All));
3206cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
3216cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian  }
3226cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
323e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  /// This routine declares and returns address of:
324e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  /// void objc_copyCppObjectAtomic(
325e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  ///         void *dest, const void *src,
326e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  ///         void (*copyHelper) (void *dest, const void *source));
327e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  llvm::Constant *getCppAtomicObjectFunction() {
328e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    CodeGen::CodeGenTypes &Types = CGM.getTypes();
329e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    ASTContext &Ctx = CGM.getContext();
330e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
331e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    SmallVector<CanQualType,3> Params;
332e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    Params.push_back(Ctx.VoidPtrTy);
333e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    Params.push_back(Ctx.VoidPtrTy);
334e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    Params.push_back(Ctx.VoidPtrTy);
335e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    llvm::FunctionType *FTy =
3360f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
3370f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                     FunctionType::ExtInfo(),
3380f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                                          RequiredArgs::All));
339e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
340e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  }
341e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian
34272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Constant *getEnumerationMutationFn() {
343c1ab900fa5e9b8a09b042992eeca29f413b1d595Daniel Dunbar    CodeGen::CodeGenTypes &Types = CGM.getTypes();
344c1ab900fa5e9b8a09b042992eeca29f413b1d595Daniel Dunbar    ASTContext &Ctx = CGM.getContext();
34572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    // void objc_enumerationMutation (id)
3465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CanQualType,1> Params;
347ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
3482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *FTy =
3490f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
350de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall                                                      FunctionType::ExtInfo(),
351de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall                                                      RequiredArgs::All));
35272db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
35372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  }
3546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
355db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
35672db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Constant *getGcReadWeakFn() {
35772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    // id objc_read_weak (id *)
3589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
3596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::FunctionType *FTy =
3600774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
36172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
3626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  }
3636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
364db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcAssignWeakFn -- LLVM objc_assign_weak function.
36596508e1fea58347b6401ca9a4728c0b268174603Chris Lattner  llvm::Constant *getGcAssignWeakFn() {
36696508e1fea58347b6401ca9a4728c0b268174603Chris Lattner    // id objc_assign_weak (id, id *)
3679cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
36896508e1fea58347b6401ca9a4728c0b268174603Chris Lattner    llvm::FunctionType *FTy =
3690774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
37096508e1fea58347b6401ca9a4728c0b268174603Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
37196508e1fea58347b6401ca9a4728c0b268174603Chris Lattner  }
3726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
373db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcAssignGlobalFn -- LLVM objc_assign_global function.
374bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getGcAssignGlobalFn() {
375bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    // id objc_assign_global(id, id *)
3769cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
377a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::FunctionType *FTy =
3780774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
379bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
380bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
3816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
382021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
383021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  llvm::Constant *getGcAssignThreadLocalFn() {
384021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    // id objc_assign_threadlocal(id src, id * dest)
3859cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
386021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    llvm::FunctionType *FTy =
3870774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
388021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
389021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  }
390021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian
391db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
392bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getGcAssignIvarFn() {
3936c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian    // id objc_assign_ivar(id, id *, ptrdiff_t)
3949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
3959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                           CGM.PtrDiffTy };
396a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::FunctionType *FTy =
3970774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
398bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
399bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
4006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
401082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
402082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  llvm::Constant *GcMemmoveCollectableFn() {
403082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian    // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
4049cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
4050774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
406082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
407082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  }
4086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
409db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
410bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getGcAssignStrongCastFn() {
411021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    // id objc_assign_strongCast(id, id *)
4129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
413a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::FunctionType *FTy =
4140774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(ObjectPtrTy, args, false);
415bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
416bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
417f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson
418f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson  /// ExceptionThrowFn - LLVM objc_exception_throw function.
419bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getExceptionThrowFn() {
420bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    // void objc_exception_throw(id)
4219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy };
422bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    llvm::FunctionType *FTy =
4230774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, args, false);
424bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
425bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
4266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
42769677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian  /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
42869677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian  llvm::Constant *getExceptionRethrowFn() {
42969677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian    // void objc_exception_rethrow(void)
4300774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
43169677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian    return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
43269677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian  }
43369677eadf881ba02d1a36e55c3b9a520769aa3c3Fariborz Jahanian
4341c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  /// SyncEnterFn - LLVM object_sync_enter function.
435b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner  llvm::Constant *getSyncEnterFn() {
4362d234d73f687428c89f8a99af94f123012f05551Aaron Ballman    // int objc_sync_enter (id)
4379cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy };
438b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner    llvm::FunctionType *FTy =
4392d234d73f687428c89f8a99af94f123012f05551Aaron Ballman      llvm::FunctionType::get(CGM.IntTy, args, false);
440b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
441b02e53b5a859f12ad1e3f90a22b6fb711901a172Chris Lattner  }
4426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4431c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  /// SyncExitFn - LLVM object_sync_exit function.
444bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  llvm::Constant *getSyncExitFn() {
4452d234d73f687428c89f8a99af94f123012f05551Aaron Ballman    // int objc_sync_exit (id)
4469cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *args[] = { ObjectPtrTy };
447bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    llvm::FunctionType *FTy =
4482d234d73f687428c89f8a99af94f123012f05551Aaron Ballman      llvm::FunctionType::get(CGM.IntTy, args, false);
449bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner    return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
450bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  }
4516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
452d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendFn(bool IsSuper) const {
453d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
4544176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
4556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
456d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendFn2(bool IsSuper) const {
457d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
4584176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
4596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
460d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendStretFn(bool IsSuper) const {
461d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
4624176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
4636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
464d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendStretFn2(bool IsSuper) const {
465d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
4664176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
4676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
468d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendFpretFn(bool IsSuper) const {
469d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
4704176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
4716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
472d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *getSendFpretFn2(bool IsSuper) const {
473d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
4744176b0c632b166548f5d0437efff10a748cd62c4Chris Lattner  }
4756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
476eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  llvm::Constant *getSendFp2retFn(bool IsSuper) const {
477eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson    return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
478eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  }
479eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson
480eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
481eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
482eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  }
483eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson
484d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
485d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  ~ObjCCommonTypesHelper(){}
486d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian};
487ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian
488d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// ObjCTypesHelper - Helper class that encapsulates lazy
489d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// construction of varies types used during ObjC generation.
490d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanianclass ObjCTypesHelper : public ObjCCommonTypesHelper {
491ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic:
4924e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// SymtabTy - LLVM type for struct objc_symtab.
4939cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *SymtabTy;
49427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// SymtabPtrTy - LLVM type for struct objc_symtab *.
4959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *SymtabPtrTy;
4964e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// ModuleTy - LLVM type for struct objc_module.
4979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ModuleTy;
498259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
4996efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolTy - LLVM type for struct objc_protocol.
5009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolTy;
5016efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
5029cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolPtrTy;
5036efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolExtensionTy - LLVM type for struct
5046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_protocol_extension.
5059cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolExtensionTy;
5066efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolExtensionTy - LLVM type for struct
5076efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_protocol_extension *.
5089cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolExtensionPtrTy;
5096efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// MethodDescriptionTy - LLVM type for struct
5106efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_method_description.
5119cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MethodDescriptionTy;
5126efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// MethodDescriptionListTy - LLVM type for struct
5136efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_method_description_list.
5149cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MethodDescriptionListTy;
5156efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// MethodDescriptionListPtrTy - LLVM type for struct
5166efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// objc_method_description_list *.
5179cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MethodDescriptionListPtrTy;
5186efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolListTy - LLVM type for struct objc_property_list.
5199cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolListTy;
5206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
5219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolListPtrTy;
52286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  /// CategoryTy - LLVM type for struct objc_category.
5239cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *CategoryTy;
52427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassTy - LLVM type for struct objc_class.
5259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ClassTy;
52627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassPtrTy - LLVM type for struct objc_class *.
5279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ClassPtrTy;
52827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassExtensionTy - LLVM type for struct objc_class_ext.
5299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ClassExtensionTy;
53027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
5319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ClassExtensionPtrTy;
53227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // IvarTy - LLVM type for struct objc_ivar.
5339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *IvarTy;
53427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// IvarListTy - LLVM type for struct objc_ivar_list.
5359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *IvarListTy;
53627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
5379cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *IvarListPtrTy;
53827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// MethodListTy - LLVM type for struct objc_method_list.
5399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MethodListTy;
54027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// MethodListPtrTy - LLVM type for struct objc_method_list *.
5419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MethodListPtrTy;
5426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
543124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
5449cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ExceptionDataTy;
5459d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
546124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
54734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getExceptionTryEnterFn() {
5489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
549a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return CGM.CreateRuntimeFunction(
5500774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, params, false),
5516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_exception_try_enter");
55234b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
553124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson
554124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
55534b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getExceptionTryExitFn() {
5569cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
557a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return CGM.CreateRuntimeFunction(
5580774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.VoidTy, params, false),
5596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_exception_try_exit");
56034b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
561124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson
562124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionExtractFn - LLVM objc_exception_extract function.
56334b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getExceptionExtractFn() {
5649cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
56596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
5660774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, false),
56734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner                                     "objc_exception_extract");
56834b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
5696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
570124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// ExceptionMatchFn - LLVM objc_exception_match function.
57134b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getExceptionMatchFn() {
5729cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
5736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    return CGM.CreateRuntimeFunction(
5740774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall      llvm::FunctionType::get(CGM.Int32Ty, params, false),
5756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "objc_exception_match");
5766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
57734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
5786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
579124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  /// SetJmpFn - LLVM _setjmp function.
58034b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  llvm::Constant *getSetJmpFn() {
5810774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    // This is specifically the prototype for x86.
5829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
5830774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
5840774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, false),
585a9e269e661ca7def681b69f2b88acf0c1fa3e654Bill Wendling                                     "_setjmp",
586a9e269e661ca7def681b69f2b88acf0c1fa3e654Bill Wendling                                     llvm::Attribute::ReturnsTwice);
58734b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner  }
5886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
589bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarpublic:
590bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
591ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  ~ObjCTypesHelper() {}
592bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar};
593bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
59430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
595ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian/// modern abi
59630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanianclass ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
59783a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanianpublic:
5986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
599d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // MethodListnfABITy - LLVM for struct _method_list_t
6009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MethodListnfABITy;
6016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
602d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
6039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MethodListnfABIPtrTy;
6046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
605d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ProtocolnfABITy = LLVM for struct _protocol_t
6069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolnfABITy;
6076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
608948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
6099cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolnfABIPtrTy;
610948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar
611d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
6129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ProtocolListnfABITy;
6136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
614d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
6159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ProtocolListnfABIPtrTy;
6166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
617d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ClassnfABITy - LLVM for struct _class_t
6189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ClassnfABITy;
6196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
620aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  // ClassnfABIPtrTy - LLVM for struct _class_t*
6219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ClassnfABIPtrTy;
6226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
623d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // IvarnfABITy - LLVM for struct _ivar_t
6249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *IvarnfABITy;
6256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
626d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // IvarListnfABITy - LLVM for struct _ivar_list_t
6279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *IvarListnfABITy;
6286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
629d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
6309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *IvarListnfABIPtrTy;
6316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
632d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ClassRonfABITy - LLVM for struct _class_ro_t
6339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *ClassRonfABITy;
6346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
635d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6369cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *ImpnfABITy;
6376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
638d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // CategorynfABITy - LLVM for struct _category_t
6399cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *CategorynfABITy;
6406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6412e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // New types for nonfragile abi messaging.
6426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6432e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // MessageRefTy - LLVM for:
6442e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // struct _message_ref_t {
6452e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   IMP messenger;
6462e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SEL name;
6472e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // };
6489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *MessageRefTy;
64983a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  // MessageRefCTy - clang type for struct _message_ref_t
65083a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  QualType MessageRefCTy;
6516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6522e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // MessageRefPtrTy - LLVM for struct _message_ref_t*
6539cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *MessageRefPtrTy;
65483a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  // MessageRefCPtrTy - clang type for struct _message_ref_t*
65583a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  QualType MessageRefCPtrTy;
6566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
657ef163782d227f064df5988d46487609324a0169eFariborz Jahanian  // MessengerTy - Type of the messenger (shown as IMP above)
6589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::FunctionType *MessengerTy;
6596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6602e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // SuperMessageRefTy - LLVM for:
6612e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // struct _super_message_ref_t {
6622e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SUPER_IMP messenger;
6632e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SEL name;
6642e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // };
6659cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *SuperMessageRefTy;
6666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6672e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
6689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *SuperMessageRefPtrTy;
6698ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar
6701c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendFixupFn() {
6711c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
6729cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
67396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
6740774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
6751c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                     "objc_msgSend_fixup");
6761c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
6776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6781c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendFpretFixupFn() {
6791c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
6809cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
68196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
6820774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
6831c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                     "objc_msgSend_fpret_fixup");
6841c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
6856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6861c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendStretFixupFn() {
6871c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
6889cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
68996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
6900774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, true),
6911c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                     "objc_msgSend_stret_fixup");
6921c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
6936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6941c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendSuper2FixupFn() {
6956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    // id objc_msgSendSuper2_fixup (struct objc_super *,
6961c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    //                              struct _super_message_ref_t*, ...)
6979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
69896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
6990774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                              params, true),
7001c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                      "objc_msgSendSuper2_fixup");
7011c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
7026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7031c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  llvm::Constant *getMessageSendSuper2StretFixupFn() {
7046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
7051c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner    //                                   struct _super_message_ref_t*, ...)
7069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
70796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
7080774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                              params, true),
7091c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner                                      "objc_msgSendSuper2_stret_fixup");
7101c02f86f5be46f36d6c5facb88c2d15e0e19266cChris Lattner  }
7116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7128a56911956aa875922a5faa3787c6829e7f7011fChris Lattner  llvm::Constant *getObjCEndCatchFn() {
7130774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
7148a56911956aa875922a5faa3787c6829e7f7011fChris Lattner                                     "objc_end_catch");
7156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7168a56911956aa875922a5faa3787c6829e7f7011fChris Lattner  }
7176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7188a56911956aa875922a5faa3787c6829e7f7011fChris Lattner  llvm::Constant *getObjCBeginCatchFn() {
7199cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *params[] = { Int8PtrTy };
72096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
7210774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                                                             params, false),
7228a56911956aa875922a5faa3787c6829e7f7011fChris Lattner                                     "objc_begin_catch");
7238a56911956aa875922a5faa3787c6829e7f7011fChris Lattner  }
724e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
7259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *EHTypeTy;
7269cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *EHTypePtrTy;
7279d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
72830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
72930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  ~ObjCNonFragileABITypesHelper(){}
730ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian};
7316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
732ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass CGObjCCommonMac : public CodeGen::CGObjCRuntime {
7339397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanianpublic:
7349397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // FIXME - accessibility
735a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian  class GC_IVAR {
736820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  public:
7378b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned ivar_bytepos;
7388b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned ivar_size;
7398b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
7406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : ivar_bytepos(bytepos), ivar_size(size) {}
7410941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar
7420941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar    // Allow sorting based on byte pos.
7430941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar    bool operator<(const GC_IVAR &b) const {
7440941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar      return ivar_bytepos < b.ivar_bytepos;
7450941b49af3b7204ddb69ed21f07c966b8d949cf4Daniel Dunbar    }
746a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian  };
7476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7489397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  class SKIP_SCAN {
7498b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar  public:
7508b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned skip;
7518b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned scan;
7526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
7538b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar      : skip(_skip), scan(_scan) {}
7549397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  };
7556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
756ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprotected:
75769243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson  llvm::LLVMContext &VMContext;
758ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // FIXME! May not be needing this after all.
759bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  unsigned ObjCABI;
7606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7619397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // gc ivar layout bitmap calculation helper caches.
7625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<GC_IVAR, 16> SkipIvars;
7635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<GC_IVAR, 16> IvarsInfo;
7646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
765242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// LazySymbols - Symbols to generate a lazy reference for. See
766242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// DefinedSymbols and FinishModule().
767330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  llvm::SetVector<IdentifierInfo*> LazySymbols;
7686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
769242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// DefinedSymbols - External symbols which are defined by this
770242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// module. The symbols in this list and LazySymbols are used to add
771242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// special linker symbols which ensure that Objective-C modules are
772242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  /// linked properly.
773330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  llvm::SetVector<IdentifierInfo*> DefinedSymbols;
7746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
7754e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// ClassNames - uniqued class names.
7766efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
7776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
778259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  /// MethodVarNames - uniqued method variable names.
779259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
7806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
781b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian  /// DefinedCategoryNames - list of category names in form Class_Category.
782b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian  llvm::SetVector<std::string> DefinedCategoryNames;
783b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian
7846efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// MethodVarTypes - uniqued method type signatures. We have to use
7856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// a StringMap here because have no other unique reference.
7866efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
7876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
788c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  /// MethodDefinitions - map of methods which have been defined in
789c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  /// this translation unit.
790c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
7916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
792c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  /// PropertyNames - uniqued method variable names.
793c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
7946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
79527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// ClassReferences - uniqued class references.
79627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
7976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
798259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  /// SelectorReferences - uniqued selector references.
799259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
8006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
8016efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// Protocols - Protocols for which an objc_protocol structure has
8026efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// been emitted. Forward declarations are handled by creating an
8036efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// empty structure whose initializer is filled in when/if defined.
8046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
8056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
8060c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// DefinedProtocols - Protocols which have actually been
8070c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// defined. We should not need this, see FIXME in GenerateProtocol.
8080c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
8096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
81027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// DefinedClasses - List of defined classes.
8111e01ac4e4b8981942514ca8e1916bccef99a7ae2Bill Wendling  llvm::SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
81274d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
81374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
8141e01ac4e4b8981942514ca8e1916bccef99a7ae2Bill Wendling  llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
8156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
81627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// DefinedCategories - List of defined categories.
8171e01ac4e4b8981942514ca8e1916bccef99a7ae2Bill Wendling  llvm::SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
8186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
81974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
8201e01ac4e4b8981942514ca8e1916bccef99a7ae2Bill Wendling  llvm::SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
8216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
82256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// GetNameForMethod - Return a name for the given method.
82356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// \param[out] NameOut - The return value.
82456210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  void GetNameForMethod(const ObjCMethodDecl *OMD,
82556210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian                        const ObjCContainerDecl *CD,
8265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                        SmallVectorImpl<char> &NameOut);
8276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
82856210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// GetMethodVarName - Return a unique constant for the given
82956210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// selector's name. The return value has type char *.
83056210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetMethodVarName(Selector Sel);
83156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
8326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
83356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// GetMethodVarType - Return a unique constant for the given
834dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  /// method's type encoding string. The return value has type char *.
8356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
83656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  // FIXME: This is a horrible name.
837dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
838dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                                   bool Extended = false);
8393e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar  llvm::Constant *GetMethodVarType(const FieldDecl *D);
8406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
84156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// GetPropertyName - Return a unique constant for the given
84256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  /// name. The return value has type char *.
84356210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
8446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
84556210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  // FIXME: This can be dropped once string functions are unified.
84656210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian  llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
84756210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian                                        const Decl *Container);
8486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
849058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  /// GetClassName - Return a unique constant for the given selector's
850058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  /// name. The return value has type char *.
851058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  llvm::Constant *GetClassName(IdentifierInfo *Ident);
8526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
8539d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
8549d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis
855d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian  /// BuildIvarLayout - Builds ivar layout bitmap for the class
856d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian  /// implementation for the __strong or __weak case.
857d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian  ///
858c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian  llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
859c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian                                  bool ForStrongLayout);
86093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
861b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
8626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
863d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar  void BuildAggrIvarRecordLayout(const RecordType *RT,
8646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                 unsigned int BytePos, bool ForStrongLayout,
8656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                 bool &HasUnion);
8665a5a803df8a8e3e567278fdfd8a6c1aff8dc6b82Daniel Dunbar  void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
867c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian                           const llvm::StructLayout *Layout,
868a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian                           const RecordDecl *RD,
869795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling                           ArrayRef<const FieldDecl*> RecFields,
870d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian                           unsigned int BytePos, bool ForStrongLayout,
87181adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian                           bool &HasUnion);
872c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian
873d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian  /// GetIvarLayoutName - Returns a unique constant for the given
874d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian  /// ivar layout bitmap.
875d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian  llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
876d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian                                    const ObjCCommonTypesHelper &ObjCTypes);
8776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
8785de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian  /// EmitPropertyList - Emit the given property list. The return
8795de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian  /// value has type PropertyListPtrTy.
8805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitPropertyList(Twine Name,
8816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                   const Decl *Container,
8825de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian                                   const ObjCContainerDecl *OCD,
8835de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian                                   const ObjCCommonTypesHelper &ObjCTypes);
8846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
885dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  /// EmitProtocolMethodTypes - Generate the array of extended method type
886dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  /// strings. The return value has type Int8PtrPtrTy.
887dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  llvm::Constant *EmitProtocolMethodTypes(Twine Name,
888bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                          ArrayRef<llvm::Constant*> MethodTypes,
889dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                                       const ObjCCommonTypesHelper &ObjCTypes);
890dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson
891191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  /// PushProtocolProperties - Push protocol's property on the input stack.
8923964e62786b0912fecc82d776daac236e05fc792Bill Wendling  void PushProtocolProperties(
8933964e62786b0912fecc82d776daac236e05fc792Bill Wendling    llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
8943964e62786b0912fecc82d776daac236e05fc792Bill Wendling    llvm::SmallVectorImpl<llvm::Constant*> &Properties,
8953964e62786b0912fecc82d776daac236e05fc792Bill Wendling    const Decl *Container,
8963964e62786b0912fecc82d776daac236e05fc792Bill Wendling    const ObjCProtocolDecl *PROTO,
8973964e62786b0912fecc82d776daac236e05fc792Bill Wendling    const ObjCCommonTypesHelper &ObjCTypes);
898191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian
899da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetProtocolRef - Return a reference to the internal protocol
900da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// description, creating an empty one if it has not been
901da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// defined. The return value has type ProtocolPtrTy.
902da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
903b21f07e056b6c9918bf938f19ca561c60f778695Fariborz Jahanian
904fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  /// CreateMetadataVar - Create a global variable with internal
905fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  /// linkage for use by the Objective-C runtime.
906fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  ///
907fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  /// This is a convenience wrapper which not only creates the
908fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  /// variable, but also sets the section and alignment and adds the
909ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  /// global to the "llvm.used" list.
91035bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  ///
91135bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param Name - The variable name.
91235bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param Init - The variable initializer; this is also used to
91335bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// define the type of the variable.
91435bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param Section - The section the variable should go into, or 0.
91535bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param Align - The alignment for the variable, or 0.
91635bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  /// \param AddToUsed - Whether the variable should be added to
917c15830694f2bd01080e6c39a88c5b8ff2288af18Daniel Dunbar  /// "llvm.used".
9185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::GlobalVariable *CreateMetadataVar(Twine Name,
919fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar                                          llvm::Constant *Init,
920fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar                                          const char *Section,
92135bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar                                          unsigned Align,
92235bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar                                          bool AddToUsed);
923fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar
924944c84313da15477eb18d90babb0890d10d98082John McCall  CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
925944c84313da15477eb18d90babb0890d10d98082John McCall                                  ReturnValueSlot Return,
926944c84313da15477eb18d90babb0890d10d98082John McCall                                  QualType ResultType,
927944c84313da15477eb18d90babb0890d10d98082John McCall                                  llvm::Value *Sel,
928944c84313da15477eb18d90babb0890d10d98082John McCall                                  llvm::Value *Arg0,
929944c84313da15477eb18d90babb0890d10d98082John McCall                                  QualType Arg0Ty,
930944c84313da15477eb18d90babb0890d10d98082John McCall                                  bool IsSuper,
931944c84313da15477eb18d90babb0890d10d98082John McCall                                  const CallArgList &CallArgs,
932944c84313da15477eb18d90babb0890d10d98082John McCall                                  const ObjCMethodDecl *OMD,
933944c84313da15477eb18d90babb0890d10d98082John McCall                                  const ObjCCommonTypesHelper &ObjCTypes);
9343e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar
935fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  /// EmitImageInfo - Emit the image info marker used to encode some module
936fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  /// level information.
937fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  void EmitImageInfo();
938fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar
939ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic:
94069243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson  CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
941de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
9426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
9430d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall  virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
944ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
945493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
946493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian                                         const ObjCContainerDecl *CD=0);
9476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
948da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
9496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
950da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetOrEmitProtocol - Get the protocol object for the given
951da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// declaration, emitting it if necessary. The return value has type
952da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// ProtocolPtrTy.
953da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
9546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
955da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
956da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// object for the given declaration, emitting it if needed. These
957da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// forward references will be filled in with empty bodies if no
958da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// definition is seen. The return value has type ProtocolPtrTy.
959da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
9606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
9616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall                                             const CGBlockInfo &blockInfo);
96289ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian
963ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian};
9646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
965ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianclass CGObjCMac : public CGObjCCommonMac {
966ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprivate:
967ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  ObjCTypesHelper ObjCTypes;
968f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
9694e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  /// EmitModuleInfo - Another marker encoding module level
9706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  /// information.
9714e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  void EmitModuleInfo();
9724e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
97327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitModuleSymols - Emit module symbols, the list of defined
97427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// classes and categories. The result has type SymtabPtrTy.
9754e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  llvm::Constant *EmitModuleSymbols();
9764e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
977f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  /// FinishModule - Write out global data structures at the end of
978f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  /// processing a translation unit.
979f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  void FinishModule();
9806efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
98127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitClassExtension - Generate the class extension structure used
98227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// to store the weak ivar layout and properties. The return value
98327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// has type ClassExtensionPtrTy.
98427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
98527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
98627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
98727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// for the given class.
9886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *EmitClassRef(CGBuilderTy &Builder,
98927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                            const ObjCInterfaceDecl *ID);
990b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian
991f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
992f85e193739c953358c865005855253af4f68a497John McCall                                  IdentifierInfo *II);
993f85e193739c953358c865005855253af4f68a497John McCall
994f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
995f85e193739c953358c865005855253af4f68a497John McCall
996b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  /// EmitSuperClassRef - Emits reference to class's main metadata class.
997b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
99827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
99927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitIvarList - Emit the ivar list for the given
100027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// implementation. If ForClass is true the list of class ivars
100127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// (i.e. metaclass ivars) is emitted, otherwise the list of
100227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// interface ivars will be emitted. The return value has type
100327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// IvarListPtrTy.
100427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
100546b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian                               bool ForClass);
10066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1007f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  /// EmitMetaClass - Emit a forward reference to the class structure
1008f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  /// for the metaclass of the given interface. The return value has
1009f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  /// type ClassPtrTy.
1010f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1011f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
101227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitMetaClass - Emit a class structure for the metaclass of the
1013f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  /// given implementation. The return value has type ClassPtrTy.
101427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
101527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                llvm::Constant *Protocols,
1016bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                ArrayRef<llvm::Constant*> Methods);
10176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1018ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
10196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1020ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
102127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
102227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitMethodList - Emit the method list for the given
1023af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// implementation. The return value has type MethodListPtrTy.
10245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitMethodList(Twine Name,
102586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar                                 const char *Section,
1026bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                 ArrayRef<llvm::Constant*> Methods);
102727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
102827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitMethodDescList - Emit a method description list for a list of
10296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  /// method declarations.
10306efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - TypeName: The name for the type containing the methods.
10316efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - IsProtocol: True iff these methods are for a protocol.
10326efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - ClassMethds: True iff these are class methods.
10336efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - Required: When true, only "required" methods are
10346efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///    listed. Similarly, when false only "optional" methods are
10356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///    listed. For classes this should always be true.
10366efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///  - begin, end: The method list to output.
10376efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  ///
10386efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// The return value has type MethodDescriptionListPtrTy.
10395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitMethodDescList(Twine Name,
1040ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                     const char *Section,
1041bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                     ArrayRef<llvm::Constant*> Methods);
10426efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
10430c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// GetOrEmitProtocol - Get the protocol object for the given
10440c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// declaration, emitting it if necessary. The return value has type
10450c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// ProtocolPtrTy.
1046da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
10470c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
10480c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
10490c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// object for the given declaration, emitting it if needed. These
10500c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// forward references will be filled in with empty bodies if no
10510c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  /// definition is seen. The return value has type ProtocolPtrTy.
1052da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
10530c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
10546efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// EmitProtocolExtension - Generate the protocol extension
10556efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// structure used to store optional instance and class methods, and
10566efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// protocol properties. The return value has type
10576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// ProtocolExtensionPtrTy.
1058ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  llvm::Constant *
1059ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  EmitProtocolExtension(const ObjCProtocolDecl *PD,
1060bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                        ArrayRef<llvm::Constant*> OptInstanceMethods,
1061bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                        ArrayRef<llvm::Constant*> OptClassMethods,
1062bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                        ArrayRef<llvm::Constant*> MethodTypesExt);
10636efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
10646efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// EmitProtocolList - Generate the list of referenced
10656efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  /// protocols. The return value has type ProtocolListPtrTy.
10665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitProtocolList(Twine Name,
1067dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                                   ObjCProtocolDecl::protocol_iterator begin,
1068dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                                   ObjCProtocolDecl::protocol_iterator end);
10696efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
107027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
107127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  /// for the given selector.
107203b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
107303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                            bool lval=false);
10746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
10756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarpublic:
1076c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar  CGObjCMac(CodeGen::CodeGenModule &cgm);
1077c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1078aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Function *ModuleInitFunction();
10796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
10808f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1081ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                              ReturnValueSlot Return,
10827f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                              QualType ResultType,
10837f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                              Selector Sel,
1084f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                              llvm::Value *Receiver,
1085df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                              const CallArgList &CallArgs,
1086c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                              const ObjCInterfaceDecl *Class,
1087df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                              const ObjCMethodDecl *Method);
10888f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar
10896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  virtual CodeGen::RValue
10908f2926b73ed635afecd020da787af6a837601a2bDaniel Dunbar  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1091ef072fd2f3347cfd857d6eb787b245b950771430John McCall                           ReturnValueSlot Return,
10927f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                           QualType ResultType,
10937f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                           Selector Sel,
1094f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                           const ObjCInterfaceDecl *Class,
10957ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian                           bool isCategoryImpl,
1096f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                           llvm::Value *Receiver,
109719cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar                           bool IsClassMessage,
1098d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                           const CallArgList &CallArgs,
1099d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                           const ObjCMethodDecl *Method);
11006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
110145d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
110227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                const ObjCInterfaceDecl *ID);
1103c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
110403b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
110503b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                   bool lval = false);
1106df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian
1107df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1108df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  /// untyped one.
1109df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1110df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                   const ObjCMethodDecl *Method);
1111df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian
1112cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  virtual llvm::Constant *GetEHType(QualType T);
11135a180397870944548aaadeaebf58e415885b9489John McCall
11147ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
11157ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar
11167ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1117c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
111885fdea03687e45dfde025867fe98ea24ac74c501Daniel Dunbar  virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
111929254f4dd114fe2dd5c4e7a261ebea941973ad3dDavid Chisnall
112045d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
1121af2f62ce32e462f256855cd24b06dec4755d2827Daniel Dunbar                                           const ObjCProtocolDecl *PD);
11226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
112374391b48b4791cded373683a3baf67314f358d50Chris Lattner  virtual llvm::Constant *GetPropertyGetFunction();
112474391b48b4791cded373683a3baf67314f358d50Chris Lattner  virtual llvm::Constant *GetPropertySetFunction();
1125ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1126ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek                                                          bool copy);
11278fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  virtual llvm::Constant *GetGetStructFunction();
11288fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  virtual llvm::Constant *GetSetStructFunction();
1129e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  virtual llvm::Constant *GetCppAtomicObjectFunction();
113074391b48b4791cded373683a3baf67314f358d50Chris Lattner  virtual llvm::Constant *EnumerationMutationFunction();
11316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1132f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1133f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           const ObjCAtTryStmt &S);
1134f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1135f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                    const ObjCAtSynchronizedStmt &S);
1136f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
113764d5d6c5903157c521af496479d06dc26032d718Anders Carlsson  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
113864d5d6c5903157c521af496479d06dc26032d718Anders Carlsson                             const ObjCAtThrowStmt &S);
11393e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
11406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                         llvm::Value *AddrWeakObj);
11413e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
11426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                  llvm::Value *src, llvm::Value *dst);
114358626500527695865683d1d65053743de8770b60Fariborz Jahanian  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1144021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                    llvm::Value *src, llvm::Value *dest,
1145021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                    bool threadlocal = false);
11467eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
11476c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                  llvm::Value *src, llvm::Value *dest,
11486c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                  llvm::Value *ivarOffset);
114958626500527695865683d1d65053743de8770b60Fariborz Jahanian  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
115058626500527695865683d1d65053743de8770b60Fariborz Jahanian                                        llvm::Value *src, llvm::Value *dest);
1151082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1152082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian                                        llvm::Value *dest, llvm::Value *src,
115355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                        llvm::Value *size);
11546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1155598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1156598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      QualType ObjectTy,
1157598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      llvm::Value *BaseValue,
1158598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      const ObjCIvarDecl *Ivar,
1159598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      unsigned CVRQualifiers);
1160f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
11612a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar                                      const ObjCInterfaceDecl *Interface,
1162f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian                                      const ObjCIvarDecl *Ivar);
11636f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian
11646f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian  /// GetClassGlobal - Return the global variable for the Objective-C
11656f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian  /// class of the given name.
11666f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian  virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
1167b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("CGObjCMac::GetClassGlobal");
11686f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian  }
1169c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar};
11706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
117130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanianclass CGObjCNonFragileABIMac : public CGObjCCommonMac {
1172ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianprivate:
117330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  ObjCNonFragileABITypesHelper ObjCTypes;
1174aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  llvm::GlobalVariable* ObjCEmptyCacheVar;
1175aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  llvm::GlobalVariable* ObjCEmptyVtableVar;
11766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
11771139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  /// SuperClassReferences - uniqued super class references.
11781139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
11796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
11807a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  /// MetaClassReferences - uniqued meta class references.
11817a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1182e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
1183e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  /// EHTypeReferences - uniqued class ehtype references.
1184e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
11856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1186944c84313da15477eb18d90babb0890d10d98082John McCall  /// VTableDispatchMethods - List of methods for which we generate
1187944c84313da15477eb18d90babb0890d10d98082John McCall  /// vtable-based message dispatch.
1188944c84313da15477eb18d90babb0890d10d98082John McCall  llvm::DenseSet<Selector> VTableDispatchMethods;
11896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1190a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  /// DefinedMetaClasses - List of defined meta-classes.
1191a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1192a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian
1193944c84313da15477eb18d90babb0890d10d98082John McCall  /// isVTableDispatchedSelector - Returns true if SEL is a
1194944c84313da15477eb18d90babb0890d10d98082John McCall  /// vtable-based selector.
1195944c84313da15477eb18d90babb0890d10d98082John McCall  bool isVTableDispatchedSelector(Selector Sel);
11966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1197aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  /// FinishNonFragileABIModule - Write out global data structures at the end of
1198aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  /// processing a translation unit.
1199aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  void FinishNonFragileABIModule();
12008158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
1201463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  /// AddModuleClassList - Add the given list of class pointers to the
1202463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  /// module with the provided symbol and section names.
1203bb02855f46423d2034918b75b157f886bb04bcccBill Wendling  void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
1204463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                          const char *SymbolName,
1205463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                          const char *SectionName);
1206463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar
12076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
12086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                              unsigned InstanceStart,
12096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                              unsigned InstanceSize,
12106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                              const ObjCImplementationDecl *ID);
121184394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
12126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                            llvm::Constant *IsAGV,
121384394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian                                            llvm::Constant *SuperClassGV,
1214cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian                                            llvm::Constant *ClassRoGV,
1215cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian                                            bool HiddenVisibility);
12166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1217493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
12186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
12193819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
12206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1221493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  /// EmitMethodList - Emit the method list for the given
1222493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  /// implementation. The return value has type MethodListnfABITy.
12235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitMethodList(Twine Name,
1224493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian                                 const char *Section,
1225bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                 ArrayRef<llvm::Constant*> Methods);
122698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// EmitIvarList - Emit the ivar list for the given
122798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// implementation. If ForClass is true the list of class ivars
122898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// (i.e. metaclass ivars) is emitted, otherwise the list of
122998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// interface ivars will be emitted. The return value has type
123098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  /// IvarListnfABIPtrTy.
123198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
12326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1233ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
12342fa5a27f38b2c4abc26e86895fdcef3ec84af39dFariborz Jahanian                                    const ObjCIvarDecl *Ivar,
12351bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian                                    unsigned long int offset);
12366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1237da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetOrEmitProtocol - Get the protocol object for the given
1238da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// declaration, emitting it if necessary. The return value has type
1239da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// ProtocolPtrTy.
1240da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
12416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1242da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1243da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// object for the given declaration, emitting it if needed. These
1244da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// forward references will be filled in with empty bodies if no
1245da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// definition is seen. The return value has type ProtocolPtrTy.
1246da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
12476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1248da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// EmitProtocolList - Generate the list of referenced
1249da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  /// protocols. The return value has type ProtocolListPtrTy.
12505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  llvm::Constant *EmitProtocolList(Twine Name,
1251da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                                   ObjCProtocolDecl::protocol_iterator begin,
12524655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian                                   ObjCProtocolDecl::protocol_iterator end);
12536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1254944c84313da15477eb18d90babb0890d10d98082John McCall  CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1255944c84313da15477eb18d90babb0890d10d98082John McCall                                        ReturnValueSlot Return,
1256944c84313da15477eb18d90babb0890d10d98082John McCall                                        QualType ResultType,
1257944c84313da15477eb18d90babb0890d10d98082John McCall                                        Selector Sel,
1258944c84313da15477eb18d90babb0890d10d98082John McCall                                        llvm::Value *Receiver,
1259944c84313da15477eb18d90babb0890d10d98082John McCall                                        QualType Arg0Ty,
1260944c84313da15477eb18d90babb0890d10d98082John McCall                                        bool IsSuper,
1261944c84313da15477eb18d90babb0890d10d98082John McCall                                        const CallArgList &CallArgs,
1262944c84313da15477eb18d90babb0890d10d98082John McCall                                        const ObjCMethodDecl *Method);
12636f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian
12645a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  /// GetClassGlobal - Return the global variable for the Objective-C
12655a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  /// class of the given name.
12660f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian  llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
12676f40e2244b0590f144c5ceee07981a962fbbc72eFariborz Jahanian
12680e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
12691139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  /// for the given class reference.
12706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *EmitClassRef(CGBuilderTy &Builder,
12711139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar                            const ObjCInterfaceDecl *ID);
1272f85e193739c953358c865005855253af4f68a497John McCall
1273f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
1274f85e193739c953358c865005855253af4f68a497John McCall                                  IdentifierInfo *II);
1275f85e193739c953358c865005855253af4f68a497John McCall
1276f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
12776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
12781139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
12791139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  /// for the given super class reference.
12806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
12816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                 const ObjCInterfaceDecl *ID);
12826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
12837a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  /// EmitMetaClassRef - Return a Value * of the address of _class_t
12847a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  /// meta-data
12856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
12867a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian                                const ObjCInterfaceDecl *ID);
12877a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian
1288ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1289ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  /// the given ivar.
1290ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  ///
12915e88beaa0a86b162dfb9f53891adfdfbe925cc64Daniel Dunbar  llvm::GlobalVariable * ObjCIvarOffsetVariable(
12926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    const ObjCInterfaceDecl *ID,
12936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    const ObjCIvarDecl *Ivar);
12946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
129526cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
129626cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  /// for the given selector.
129703b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
129803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                            bool lval=false);
1299e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
13008158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1301e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  /// interface. The return value has type EHTypePtrTy.
13025a180397870944548aaadeaebf58e415885b9489John McCall  llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
13038158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar                                  bool ForDefinition);
13046ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar
13056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *getMetaclassSymbolPrefix() const {
13066ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar    return "OBJC_METACLASS_$_";
13076ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  }
13086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
13096ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  const char *getClassSymbolPrefix() const {
13106ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar    return "OBJC_CLASS_$_";
13116ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  }
13126ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar
13139f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar  void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1314b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar                        uint32_t &InstanceStart,
1315b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar                        uint32_t &InstanceSize);
13166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
13174523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian  // Shamelessly stolen from Analysis/CFRefCount.cpp
131874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  Selector GetNullarySelector(const char* name) const {
13194523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
13204523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian    return CGM.getContext().Selectors.getSelector(0, &II);
13214523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian  }
13226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
132374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  Selector GetUnarySelector(const char* name) const {
13244523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
13254523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian    return CGM.getContext().Selectors.getSelector(1, &II);
13264523eb0fdfb1e003c3810951d9eb3dddcf08cc24Fariborz Jahanian  }
1327b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar
132874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  /// ImplementationIsNonLazy - Check whether the given category or
132974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  /// class implementation is "non-lazy".
1330ecfbdcbaf71609ab99cdebbf2d704173070dbaf3Fariborz Jahanian  bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
133174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
1332ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanianpublic:
133330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1334aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  // FIXME. All stubs for now!
1335aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Function *ModuleInitFunction();
13366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1337aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1338ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                              ReturnValueSlot Return,
1339aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                                              QualType ResultType,
1340aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                                              Selector Sel,
1341aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                                              llvm::Value *Receiver,
1342df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                              const CallArgList &CallArgs,
1343c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                              const ObjCInterfaceDecl *Class,
1344df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                              const ObjCMethodDecl *Method);
13456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
13466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  virtual CodeGen::RValue
1347aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1348ef072fd2f3347cfd857d6eb787b245b950771430John McCall                           ReturnValueSlot Return,
1349aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           QualType ResultType,
1350aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           Selector Sel,
1351aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           const ObjCInterfaceDecl *Class,
13527ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian                           bool isCategoryImpl,
1353aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           llvm::Value *Receiver,
1354aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian                           bool IsClassMessage,
1355d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                           const CallArgList &CallArgs,
1356d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                           const ObjCMethodDecl *Method);
13576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1358aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
13590e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian                                const ObjCInterfaceDecl *ID);
13606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
136103b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
136203b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                   bool lvalue = false)
136303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian    { return EmitSelector(Builder, Sel, lvalue); }
1364df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian
1365df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1366df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  /// untyped one.
1367df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
1368df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                   const ObjCMethodDecl *Method)
1369df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian    { return EmitSelector(Builder, Method->getSelector()); }
13706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1371eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
13726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1373aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
137429254f4dd114fe2dd5c4e7a261ebea941973ad3dDavid Chisnall
137585fdea03687e45dfde025867fe98ea24ac74c501Daniel Dunbar  virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
137629254f4dd114fe2dd5c4e7a261ebea941973ad3dDavid Chisnall
1377aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
13788cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian                                           const ObjCProtocolDecl *PD);
13796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1380cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  virtual llvm::Constant *GetEHType(QualType T);
13815a180397870944548aaadeaebf58e415885b9489John McCall
13826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  virtual llvm::Constant *GetPropertyGetFunction() {
138372db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return ObjCTypes.getGetPropertyFn();
1384f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian  }
13856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  virtual llvm::Constant *GetPropertySetFunction() {
13866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    return ObjCTypes.getSetPropertyFn();
1387f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian  }
13886cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
1389ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1390ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek                                                          bool copy) {
1391ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1392ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  }
1393ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
13948fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  virtual llvm::Constant *GetSetStructFunction() {
13958fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall    return ObjCTypes.getCopyStructFn();
13968fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  }
13978fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  virtual llvm::Constant *GetGetStructFunction() {
13986cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian    return ObjCTypes.getCopyStructFn();
13996cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian  }
1400e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  virtual llvm::Constant *GetCppAtomicObjectFunction() {
1401e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian    return ObjCTypes.getCppAtomicObjectFunction();
1402e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  }
14036cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
140474391b48b4791cded373683a3baf67314f358d50Chris Lattner  virtual llvm::Constant *EnumerationMutationFunction() {
140572db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner    return ObjCTypes.getEnumerationMutationFn();
140628ed0847480b76ce76a7e605156608b1cea80e53Daniel Dunbar  }
14076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1408f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1409f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           const ObjCAtTryStmt &S);
1410f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1411f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                    const ObjCAtSynchronizedStmt &S);
1412aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1413f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson                             const ObjCAtThrowStmt &S);
1414aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
14156948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                                         llvm::Value *AddrWeakObj);
1416aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
14176948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                                  llvm::Value *src, llvm::Value *dst);
1418aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1419021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                    llvm::Value *src, llvm::Value *dest,
1420021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                    bool threadlocal = false);
1421aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
14226c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                  llvm::Value *src, llvm::Value *dest,
14236c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                  llvm::Value *ivarOffset);
1424aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
14256948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                                        llvm::Value *src, llvm::Value *dest);
1426082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1427082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian                                        llvm::Value *dest, llvm::Value *src,
142855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                        llvm::Value *size);
1429598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1430598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      QualType ObjectTy,
1431598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      llvm::Value *BaseValue,
1432598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      const ObjCIvarDecl *Ivar,
1433598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                      unsigned CVRQualifiers);
1434f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
14352a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar                                      const ObjCInterfaceDecl *Interface,
1436f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian                                      const ObjCIvarDecl *Ivar);
1437ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian};
14384e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
14394e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian/// A helper class for performing the null-initialization of a return
14404e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian/// value.
14414e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanianstruct NullReturnState {
14424e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian  llvm::BasicBlock *NullBB;
14434e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian  llvm::BasicBlock *callBB;
14444e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian  NullReturnState() : NullBB(0), callBB(0) {}
14454e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
14464e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian  void init(CodeGenFunction &CGF, llvm::Value *receiver) {
14474e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // Make blocks for the null-init and call edges.
14484e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    NullBB = CGF.createBasicBlock("msgSend.nullinit");
14494e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    callBB = CGF.createBasicBlock("msgSend.call");
14504e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
14514e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // Check for a null receiver and, if there is one, jump to the
14524e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // null-init test.
14534e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
14544e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
14554e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
14564e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // Otherwise, start performing the call.
14574e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    CGF.EmitBlock(callBB);
14584e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian  }
14594e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
14603c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian  RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
14613c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian                  const CallArgList &CallArgs,
14623c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian                  const ObjCMethodDecl *Method) {
14634e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    if (!NullBB) return result;
14643c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian
14653c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    llvm::Value *NullInitPtr = 0;
14663c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    if (result.isScalar() && !resultType->isVoidType()) {
14673c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      NullInitPtr = CGF.CreateTempAlloca(result.getScalarVal()->getType());
14683c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      CGF.Builder.CreateStore(result.getScalarVal(), NullInitPtr);
14693c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    }
14704e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
14714e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // Finish the call path.
14724e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    llvm::BasicBlock *contBB = CGF.createBasicBlock("msgSend.cont");
14734e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    if (CGF.HaveInsertPoint()) CGF.Builder.CreateBr(contBB);
14744e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
14754e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // Emit the null-init block and perform the null-initialization there.
14764e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    CGF.EmitBlock(NullBB);
14773c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian
14783c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    // Release consumed arguments along the null-receiver path.
14793c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    if (Method) {
14803c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      CallArgList::const_iterator I = CallArgs.begin();
14813c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
14823c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian           e = Method->param_end(); i != e; ++i, ++I) {
14833c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian        const ParmVarDecl *ParamDecl = (*i);
14843c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian        if (ParamDecl->hasAttr<NSConsumedAttr>()) {
14853c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian          RValue RV = I->RV;
14863c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian          assert(RV.isScalar() &&
14873c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian                 "NullReturnState::complete - arg not on object");
14883c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian          CGF.EmitARCRelease(RV.getScalarVal(), true);
14893c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian        }
14903c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      }
14913c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    }
14923c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian
14933c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    if (result.isScalar()) {
14943c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      if (NullInitPtr)
14953c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian        CGF.EmitNullInitialization(NullInitPtr, resultType);
14963c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      // Jump to the continuation block.
14973c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      CGF.EmitBlock(contBB);
14983c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      return NullInitPtr ? RValue::get(CGF.Builder.CreateLoad(NullInitPtr))
14993c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      : result;
15003c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    }
15013c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian
15024e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    if (!resultType->isAnyComplexType()) {
15034e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian      assert(result.isAggregate() && "null init of non-aggregate result?");
15044e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian      CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
15054e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian      // Jump to the continuation block.
15064e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian      CGF.EmitBlock(contBB);
15074e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian      return result;
15084e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    }
15094e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
15104e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // _Complex type
15114e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // FIXME. Now easy to handle any other scalar type whose result is returned
15124e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // in memory due to ABI limitations.
15134e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    CGF.EmitBlock(contBB);
15144e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    CodeGenFunction::ComplexPairTy CallCV = result.getComplexVal();
15154e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    llvm::Type *MemberType = CallCV.first->getType();
15164e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    llvm::Constant *ZeroCV = llvm::Constant::getNullValue(MemberType);
15174e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    // Create phi instruction for scalar complex value.
15184e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    llvm::PHINode *PHIReal = CGF.Builder.CreatePHI(MemberType, 2);
15194e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    PHIReal->addIncoming(ZeroCV, NullBB);
15204e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    PHIReal->addIncoming(CallCV.first, callBB);
15214e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    llvm::PHINode *PHIImag = CGF.Builder.CreatePHI(MemberType, 2);
15224e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    PHIImag->addIncoming(ZeroCV, NullBB);
15234e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    PHIImag->addIncoming(CallCV.second, callBB);
15244e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    return RValue::getComplex(PHIReal, PHIImag);
15254e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian  }
15264e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian};
15274e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian
1528c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar} // end anonymous namespace
1529bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
1530bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** Helper Functions *** */
1531bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
1532bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/// getConstantGEP() - Help routine to construct simple GEPs.
1533a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Andersonstatic llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
15346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                      llvm::Constant *C,
1535bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar                                      unsigned idx0,
1536bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar                                      unsigned idx1) {
1537bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  llvm::Value *Idxs[] = {
15380032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
15390032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1540bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  };
1541a5c04344fa70d6eec34344760c1fe511e16f2d76Jay Foad  return llvm::ConstantExpr::getGetElementPtr(C, Idxs);
1542bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar}
1543bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
15448158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar/// hasObjCExceptionAttribute - Return true if this class or any super
15458158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar/// class has the __objc_exception__ attribute.
15466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstatic bool hasObjCExceptionAttribute(ASTContext &Context,
154768584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor                                      const ObjCInterfaceDecl *OID) {
154840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  if (OID->hasAttr<ObjCExceptionAttr>())
15498158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    return true;
15508158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
155168584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor    return hasObjCExceptionAttribute(Context, Super);
15528158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  return false;
15538158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar}
15548158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
1555bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** CGObjCMac Public Interface *** */
15566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1557ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz JahanianCGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
15581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                    ObjCTypes(cgm) {
1559ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  ObjCABI = 1;
15606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  EmitImageInfo();
1561c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1562c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1563ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar/// GetClass - Return a reference to the class for the given interface
1564ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar/// decl.
156545d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbarllvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
156627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                 const ObjCInterfaceDecl *ID) {
156727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  return EmitClassRef(Builder, ID);
1568c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1569c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1570c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// GetSelector - Return the pointer to the unique'd string for this selector.
157103b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanianllvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel,
157203b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                    bool lval) {
157303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  return EmitSelector(Builder, Sel, lval);
1574c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1575df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanianllvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
15766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                    *Method) {
1577df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian  return EmitSelector(Builder, Method->getSelector());
1578df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian}
1579c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1580cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanianllvm::Constant *CGObjCMac::GetEHType(QualType T) {
15819d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian  if (T->isObjCIdType() ||
15829d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian      T->isObjCQualifiedIdType()) {
15839d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian    return CGM.GetAddrOfRTTIDescriptor(
158401a4cf11777bb34c35f5d251a9e95eb736d0842bDouglas Gregor              CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
15859d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian  }
1586cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  if (T->isObjCClassType() ||
1587cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian      T->isObjCQualifiedClassType()) {
1588cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian    return CGM.GetAddrOfRTTIDescriptor(
158901a4cf11777bb34c35f5d251a9e95eb736d0842bDouglas Gregor             CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1590cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  }
1591cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian  if (T->isObjCObjectPointerType())
1592cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian    return CGM.GetAddrOfRTTIDescriptor(T,  /*ForEH=*/true);
1593cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian
15945a180397870944548aaadeaebf58e415885b9489John McCall  llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
15955a180397870944548aaadeaebf58e415885b9489John McCall}
15965a180397870944548aaadeaebf58e415885b9489John McCall
1597bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/// Generate a constant CFString object.
15986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/*
15996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct __builtin_CFString {
16006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const int *isa; // point to __CFConstantStringClassReference
16016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  int flags;
16026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *str;
16036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long length;
16046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  };
1605bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar*/
1606bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
160733e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian/// or Generate a constant NSString object.
160833e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian/*
160933e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian   struct __builtin_NSString {
161033e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian     const int *isa; // point to __NSConstantStringClassReference
161133e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian     const char *str;
161233e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian     unsigned int length;
161333e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian   };
161433e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian*/
161533e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian
1616aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GenerateConstantString(
16170d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall  const StringLiteral *SL) {
16184e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
161933e982bf782d851bfe5767acb1336fcf3419ac6bFariborz Jahanian          CGM.GetAddrOfConstantCFString(SL) :
16204c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian          CGM.GetAddrOfConstantString(SL));
1621c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1622c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
1623ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenekenum {
1624ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  kCFTaggedObjectID_Integer = (1 << 1) + 1
1625ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek};
1626ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
1627c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// Generates a message send where the super is the receiver.  This is
1628c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// a message send to self with special delivery semantics indicating
1629c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar/// which class's method should be called.
16308f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCodeGen::RValue
16318f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1632ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                    ReturnValueSlot Return,
16337f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                    QualType ResultType,
16347f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                    Selector Sel,
1635f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                    const ObjCInterfaceDecl *Class,
16367ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian                                    bool isCategoryImpl,
1637f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                    llvm::Value *Receiver,
163819cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar                                    bool IsClassMessage,
1639d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                    const CodeGen::CallArgList &CallArgs,
1640d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                    const ObjCMethodDecl *Method) {
1641e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar  // Create and init a super structure; this is a (receiver, class)
1642e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar  // pair we will pass to objc_msgSendSuper.
16436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *ObjCSuper =
1644604da292483bc94a6a3e4700cd426d4fa7f1a4a8John McCall    CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
16456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *ReceiverAsObject =
1646e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
16476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CGF.Builder.CreateStore(ReceiverAsObject,
1648e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
1649e8b470d40c4d44b77c2efab3cb977beb23344ff6Daniel Dunbar
1650f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  // If this is a class message the metaclass is passed as the target.
1651f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  llvm::Value *Target;
1652f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  if (IsClassMessage) {
16537ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian    if (isCategoryImpl) {
16547ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // Message sent to 'super' in a class method defined in a category
16557ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // implementation requires an odd treatment.
16567ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // If we are in a class method, we must retrieve the
16577ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // _metaclass_ for the current class, pointed at by
16587ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // the class's "isa" pointer.  The following assumes that
16597ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // isa" is the first ivar in a class (which it must be).
16607ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
16617ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = CGF.Builder.CreateStructGEP(Target, 0);
16627ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = CGF.Builder.CreateLoad(Target);
1663b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
16647ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
16657ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
16667ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
16677ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = Super;
16686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
1669182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian  }
1670182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian  else if (isCategoryImpl)
1671182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian    Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
1672182f2681e75565c9ec3099c90bbc4fcc7782140cFariborz Jahanian  else {
1673b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1674b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1675b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    Target = CGF.Builder.CreateLoad(ClassPtr);
1676f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  }
1677f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1678f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ObjCTypes types.
16792acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *ClassTy =
168019cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
16810c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
16826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CGF.Builder.CreateStore(Target,
1683f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                          CGF.Builder.CreateStructGEP(ObjCSuper, 1));
1684944c84313da15477eb18d90babb0890d10d98082John McCall  return EmitMessageSend(CGF, Return, ResultType,
1685944c84313da15477eb18d90babb0890d10d98082John McCall                         EmitSelector(CGF.Builder, Sel),
1686944c84313da15477eb18d90babb0890d10d98082John McCall                         ObjCSuper, ObjCTypes.SuperPtrCTy,
1687944c84313da15477eb18d90babb0890d10d98082John McCall                         true, CallArgs, Method, ObjCTypes);
1688c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
16896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
16906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// Generate code for a message send expression.
16918f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarCodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1692ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                               ReturnValueSlot Return,
16937f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                               QualType ResultType,
16947f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                               Selector Sel,
1695f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                               llvm::Value *Receiver,
1696df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                               const CallArgList &CallArgs,
1697c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                               const ObjCInterfaceDecl *Class,
1698df9ccc6381314ccca6407abb209155e9273a631dFariborz Jahanian                                               const ObjCMethodDecl *Method) {
1699944c84313da15477eb18d90babb0890d10d98082John McCall  return EmitMessageSend(CGF, Return, ResultType,
1700944c84313da15477eb18d90babb0890d10d98082John McCall                         EmitSelector(CGF.Builder, Sel),
1701944c84313da15477eb18d90babb0890d10d98082John McCall                         Receiver, CGF.getContext().getObjCIdType(),
1702944c84313da15477eb18d90babb0890d10d98082John McCall                         false, CallArgs, Method, ObjCTypes);
170314c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar}
170414c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar
1705d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCodeGen::RValue
1706944c84313da15477eb18d90babb0890d10d98082John McCallCGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1707944c84313da15477eb18d90babb0890d10d98082John McCall                                 ReturnValueSlot Return,
1708944c84313da15477eb18d90babb0890d10d98082John McCall                                 QualType ResultType,
1709944c84313da15477eb18d90babb0890d10d98082John McCall                                 llvm::Value *Sel,
1710944c84313da15477eb18d90babb0890d10d98082John McCall                                 llvm::Value *Arg0,
1711944c84313da15477eb18d90babb0890d10d98082John McCall                                 QualType Arg0Ty,
1712944c84313da15477eb18d90babb0890d10d98082John McCall                                 bool IsSuper,
1713944c84313da15477eb18d90babb0890d10d98082John McCall                                 const CallArgList &CallArgs,
1714944c84313da15477eb18d90babb0890d10d98082John McCall                                 const ObjCMethodDecl *Method,
1715944c84313da15477eb18d90babb0890d10d98082John McCall                                 const ObjCCommonTypesHelper &ObjCTypes) {
171619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  CallArgList ActualArgs;
1717d019d96e1ea39cec32f1320b1f9f772aae28247eFariborz Jahanian  if (!IsSuper)
1718578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer    Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
171904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  ActualArgs.add(RValue::get(Arg0), Arg0Ty);
172004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1721f85e193739c953358c865005855253af4f68a497John McCall  ActualArgs.addFrom(CallArgs);
17226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
1723de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // If we're calling a method, use the formal signature.
1724de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
17256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
17267e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson  if (Method)
17277e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson    assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
17287e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson           CGM.getContext().getCanonicalType(ResultType) &&
17297e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson           "Result type mismatch!");
17307e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson
1731cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  NullReturnState nullReturn;
1732cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
1733d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  llvm::Constant *Fn = NULL;
1734de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
17354e1524babb095e70de1da882573eb6fbee98a857Fariborz Jahanian    if (!IsSuper) nullReturn.init(CGF, Arg0);
1736d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
17376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : ObjCTypes.getSendStretFn(IsSuper);
1738dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar  } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1739dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1740dacf9dda17346c628fdd8c5df53c681738db0dc5Daniel Dunbar      : ObjCTypes.getSendFpretFn(IsSuper);
1741eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson  } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1742eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1743eea64802558cc398571938b1f28cda1d4fa79ec3Anders Carlsson      : ObjCTypes.getSendFp2retFn(IsSuper);
17445669e57b4a74d26e9e2fb70d778141d0d849388bDaniel Dunbar  } else {
1745d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
17466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : ObjCTypes.getSendFn(IsSuper);
17475669e57b4a74d26e9e2fb70d778141d0d849388bDaniel Dunbar  }
17483c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian
17493c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian  bool requiresnullCheck = false;
17504e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().ObjCAutoRefCount && Method)
17513c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
17523c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian         e = Method->param_end(); i != e; ++i) {
17533c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      const ParmVarDecl *ParamDecl = (*i);
17543c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      if (ParamDecl->hasAttr<NSConsumedAttr>()) {
17553c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian        if (!nullReturn.NullBB)
17563c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian          nullReturn.init(CGF, Arg0);
17573c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian        requiresnullCheck = true;
17583c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian        break;
17593c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian      }
17603c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian    }
17613c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian
1762de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1763de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
17643c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian  return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
17653c267e6262bb319c8e56c9ea1283c7087f9ac107Fariborz Jahanian                             requiresnullCheck ? Method : 0);
1766c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
1767c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
176893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanianstatic Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
176993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (FQT.isObjCGCStrong())
177093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return Qualifiers::Strong;
177193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
1772f85e193739c953358c865005855253af4f68a497John McCall  if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
177393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return Qualifiers::Weak;
177493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
1775ba83c95b9f8e6bd65405ebff815416fd06b3d4f8Fariborz Jahanian  // check for __unsafe_unretained
1776ba83c95b9f8e6bd65405ebff815416fd06b3d4f8Fariborz Jahanian  if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone)
1777ba83c95b9f8e6bd65405ebff815416fd06b3d4f8Fariborz Jahanian    return Qualifiers::GCNone;
1778ba83c95b9f8e6bd65405ebff815416fd06b3d4f8Fariborz Jahanian
177993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
178093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return Qualifiers::Strong;
178193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
178293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (const PointerType *PT = FQT->getAs<PointerType>())
178393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
178493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
178593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  return Qualifiers::GCNone;
178693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian}
178793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
17886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
17896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall                                                const CGBlockInfo &blockInfo) {
17908b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
17916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
17924e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
17934e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      !CGM.getLangOpts().ObjCAutoRefCount)
17946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    return nullPtr;
17956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
1796a1f024c1a5c49f87ee1d0767afc0437c4e4dbecfFariborz Jahanian  bool hasUnion = false;
179793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  SkipIvars.clear();
179893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  IvarsInfo.clear();
1799bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
1800bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
180193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
180281979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian  // __isa is the first field in block descriptor and must assume by runtime's
180381979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian  // convention that it is GC'able.
180481979822cbf6347116d06dac0e5b06c451bcff05Fariborz Jahanian  IvarsInfo.push_back(GC_IVAR(0, 1));
18056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  const BlockDecl *blockDecl = blockInfo.getBlockDecl();
18076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // Calculate the basic layout of the block structure.
18096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  const llvm::StructLayout *layout =
18106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    CGM.getTargetData().getStructLayout(blockInfo.StructureType);
18116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // Ignore the optional 'this' capture: C++ objects are not assumed
18136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // to be GC'ed.
18146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // Walk the captured variables.
18166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
18176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall         ce = blockDecl->capture_end(); ci != ce; ++ci) {
18186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    const VarDecl *variable = ci->getVariable();
18196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    QualType type = variable->getType();
18206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
18226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    // Ignore constant captures.
18246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (capture.isConstant()) continue;
18256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
18276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    // __block variables are passed by their descriptor address.
18296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (ci->isByRef()) {
18306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall      IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
1831c5904b40c3d76b612fb09c6d2717f646a0af6670Fariborz Jahanian      continue;
18326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    }
18336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    assert(!type->isArrayType() && "array variable should not be caught");
18356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (const RecordType *record = type->getAs<RecordType>()) {
18366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall      BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
1837e1a48984f91cd8a65932f69be25f8330737e9842Fariborz Jahanian      continue;
1838e1a48984f91cd8a65932f69be25f8330737e9842Fariborz Jahanian    }
1839a1f024c1a5c49f87ee1d0767afc0437c4e4dbecfFariborz Jahanian
18406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
18416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    unsigned fieldSize = CGM.getContext().getTypeSize(type);
18426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (GCAttr == Qualifiers::Strong)
18446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall      IvarsInfo.push_back(GC_IVAR(fieldOffset,
18456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall                                  fieldSize / WordSizeInBits));
184693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
18476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall      SkipIvars.push_back(GC_IVAR(fieldOffset,
18486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall                                  fieldSize / ByteSizeInBits));
184993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  }
185093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
185193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (IvarsInfo.empty())
18526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    return nullPtr;
18536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
18546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // Sort on byte position; captures might not be allocated in order,
18556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  // and unions can do funny things.
18566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
18576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
185893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
185993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  std::string BitMap;
1860b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
18614e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().ObjCGCBitmapPrint) {
186293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    printf("\n block variable layout for block: ");
186331ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky    const unsigned char *s = (const unsigned char*)BitMap.c_str();
186413562a1f30df391607604fb6bf345af42b0d831dBill Wendling    for (unsigned i = 0, e = BitMap.size(); i < e; i++)
186593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian      if (!(s[i] & 0xf0))
186693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
186793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian      else
186893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
186993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    printf("\n");
187093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  }
187193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
187293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  return C;
187389ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian}
187489ecd41e0a6bfb3b0913dbe41c3c666340b308c7Fariborz Jahanian
18756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
1876af2f62ce32e462f256855cd24b06dec4755d2827Daniel Dunbar                                            const ObjCProtocolDecl *PD) {
1877c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar  // FIXME: I don't understand why gcc generates this, or where it is
1878f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // resolved. Investigate. Its also wasteful to look this up over and over.
1879c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1880c67876d6886219983881e1304a761b113ae1aec0Daniel Dunbar
18813c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
18824c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor                                        ObjCTypes.getExternalProtocolPtrTy());
18836efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
18846efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
1885da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianvoid CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
1886f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need this, the protocol decl should contain enough
1887f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // information to tell us whether this was a declaration or a definition.
18880c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  DefinedProtocols.insert(PD->getIdentifier());
18890c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
18900c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // If we have generated a forward reference to this protocol, emit
18910c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // it now. Otherwise do nothing, the protocol objects are lazily
18920c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // emitted.
18936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (Protocols.count(PD->getIdentifier()))
18940c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    GetOrEmitProtocol(PD);
18950c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar}
18960c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
1897da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
18980c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  if (DefinedProtocols.count(PD->getIdentifier()))
18990c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    return GetOrEmitProtocol(PD);
1900f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
19010c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  return GetOrEmitProtocolRef(PD);
19020c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar}
19030c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
19046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/*
19056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
19066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol {
19076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol_extension *isa;
19086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarchar *protocol_name;
19096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc_protocol_list *protocol_list;
19106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc__method_prototype_list *instance_methods;
19116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarstruct _objc__method_prototype_list *class_methods
19126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar};
19136efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
19146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarSee EmitProtocolExtension().
19156efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/
19160c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbarllvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
191750651b951c216573175e2145f32df2c4658ba3f9John McCall  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
19180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
19190c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // Early exit if a defining object has already been generated.
19200c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  if (Entry && Entry->hasInitializer())
19210c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    return Entry;
19220c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
19231d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor  // Use the protocol definition, if there is one.
19241d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor  if (const ObjCProtocolDecl *Def = PD->getDefinition())
19251d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor    PD = Def;
19261d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor
1927242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // FIXME: I don't understand why gcc generates this, or where it is
1928f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // resolved. Investigate. Its also wasteful to look this up over and over.
1929242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
1930242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar
1931ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  // Construct method lists.
1932ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1933ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
1934dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
19356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCProtocolDecl::instmeth_iterator
193617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
1937ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    ObjCMethodDecl *MD = *i;
1938ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    llvm::Constant *C = GetMethodDescriptionConstant(MD);
1939f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    if (!C)
1940f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor      return GetOrEmitProtocolRef(PD);
1941f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
1942ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1943ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar      OptInstanceMethods.push_back(C);
1944dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
1945ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    } else {
1946ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar      InstanceMethods.push_back(C);
1947dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      MethodTypesExt.push_back(GetMethodVarType(MD, true));
19486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
1949ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  }
1950ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar
19516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCProtocolDecl::classmeth_iterator
195217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
1953ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    ObjCMethodDecl *MD = *i;
1954ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    llvm::Constant *C = GetMethodDescriptionConstant(MD);
1955f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    if (!C)
1956f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor      return GetOrEmitProtocolRef(PD);
1957f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
1958ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
1959ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar      OptClassMethods.push_back(C);
1960dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
1961ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar    } else {
1962ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar      ClassMethods.push_back(C);
1963dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      MethodTypesExt.push_back(GetMethodVarType(MD, true));
19646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
1965ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  }
1966ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar
1967dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  MethodTypesExt.insert(MethodTypesExt.end(),
1968dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                        OptMethodTypesExt.begin(), OptMethodTypesExt.end());
1969dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson
19701d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
1971dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson    EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
1972dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                          MethodTypesExt),
19731d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetClassName(PD->getIdentifier()),
19749c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
1975dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                     PD->protocol_begin(),
19761d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                     PD->protocol_end()),
19779c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
1978ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       "__OBJC,__cat_inst_meth,regular,no_dead_strip",
19791d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                       InstanceMethods),
19809c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
1981ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       "__OBJC,__cat_cls_meth,regular,no_dead_strip",
19821d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                       ClassMethods)
19831d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
198408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
19856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                                                   Values);
19866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
19876efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  if (Entry) {
19880c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    // Already created, fix the linkage and update the initializer.
19890c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
19906efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setInitializer(Init);
19916efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  } else {
19926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
19931c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
19946efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                               llvm::GlobalValue::InternalLinkage,
19956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               Init,
19969c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               "\01L_OBJC_PROTOCOL_" + PD->getName());
19976efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
19986efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    // FIXME: Is this necessary? Why only for protocol?
19996efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setAlignment(4);
200050651b951c216573175e2145f32df2c4658ba3f9John McCall
200150651b951c216573175e2145f32df2c4658ba3f9John McCall    Protocols[PD->getIdentifier()] = Entry;
20026efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  }
2003ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(Entry);
20040c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
20050c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  return Entry;
20066efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
20076efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
20080c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbarllvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
20096efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
20106efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
20116efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  if (!Entry) {
20120c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    // We use the initializer as a marker of whether this is a forward
20130c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    // reference or not. At module finalization we add the empty
20140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    // contents for protocols which were referenced but never defined.
20156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
20161c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
20170c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar                               llvm::GlobalValue::ExternalLinkage,
20180c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar                               0,
20199c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               "\01L_OBJC_PROTOCOL_" + PD->getName());
20206efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
20216efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    // FIXME: Is this necessary? Why only for protocol?
20226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar    Entry->setAlignment(4);
20236efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  }
20246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
20256efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  return Entry;
20266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
20276efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
20286efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/*
20296efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  struct _objc_protocol_extension {
20306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t size;
20316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method_description_list *optional_instance_methods;
20326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method_description_list *optional_class_methods;
20336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_property_list *instance_properties;
2034dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  const char ** extendedMethodTypes;
20356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  };
20366efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/
2037ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant *
2038ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel DunbarCGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
2039bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                 ArrayRef<llvm::Constant*> OptInstanceMethods,
2040bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                 ArrayRef<llvm::Constant*> OptClassMethods,
2041bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                 ArrayRef<llvm::Constant*> MethodTypesExt) {
20426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint64_t Size =
20439408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
20441d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
20451d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
20466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
20479c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                       + PD->getName(),
2048ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       "__OBJC,__cat_inst_meth,regular,no_dead_strip",
20491d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                       OptInstanceMethods),
20509c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
2051ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       "__OBJC,__cat_cls_meth,regular,no_dead_strip",
20521d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                       OptClassMethods),
20531d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD,
2054dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                     ObjCTypes),
2055dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson    EmitProtocolMethodTypes("\01L_OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
2056dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                            MethodTypesExt, ObjCTypes)
20571d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
20586efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
205927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Return null if no extension bits are used.
20606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2061dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      Values[3]->isNullValue() && Values[4]->isNullValue())
2062c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
20636efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
20646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init =
206508e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
20666efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
206763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  // No special section, but goes in llvm.used
20689c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
20696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           Init,
207063c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                           0, 0, true);
20716efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
20726efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
20736efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/*
20746efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  struct objc_protocol_list {
20753964e62786b0912fecc82d776daac236e05fc792Bill Wendling    struct objc_protocol_list *next;
20763964e62786b0912fecc82d776daac236e05fc792Bill Wendling    long count;
20773964e62786b0912fecc82d776daac236e05fc792Bill Wendling    Protocol *list[];
20786efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  };
20796efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/
2080dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbarllvm::Constant *
20815f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCMac::EmitProtocolList(Twine Name,
2082dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                            ObjCProtocolDecl::protocol_iterator begin,
2083dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar                            ObjCProtocolDecl::protocol_iterator end) {
20843964e62786b0912fecc82d776daac236e05fc792Bill Wendling  llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs;
20856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
2086dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar  for (; begin != end; ++begin)
2087dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar    ProtocolRefs.push_back(GetProtocolRef(*begin));
20886efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
20896efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  // Just return null for empty protocol lists
20906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (ProtocolRefs.empty())
2091c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
20926efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
209327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // This list is null terminated.
2094c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
20956efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
2096c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
209727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // This field is only used by the runtime.
2098c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
20994a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
21006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                     ProtocolRefs.size() - 1);
21016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[2] =
21026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
21036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                  ProtocolRefs.size()),
21046efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                             ProtocolRefs);
21056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2106c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
21076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
210863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
210958a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar                      4, false);
21103c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2111c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2112c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
2113bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingvoid CGObjCCommonMac::
2114bb02855f46423d2034918b75b157f886bb04bcccBill WendlingPushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
21153964e62786b0912fecc82d776daac236e05fc792Bill Wendling                       llvm::SmallVectorImpl<llvm::Constant*> &Properties,
2116bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                       const Decl *Container,
2117bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                       const ObjCProtocolDecl *PROTO,
2118bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                       const ObjCCommonTypesHelper &ObjCTypes) {
2119191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
2120191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian         E = PROTO->protocol_end(); P != E; ++P)
2121191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
2122191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
2123191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian       E = PROTO->prop_end(); I != E; ++I) {
2124581deb3da481053c4993c7600f97acf7768caac5David Blaikie    const ObjCPropertyDecl *PD = *I;
2125191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    if (!PropertySet.insert(PD->getIdentifier()))
2126191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian      continue;
21271d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Prop[] = {
21281d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetPropertyName(PD->getIdentifier()),
21291d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetPropertyTypeString(PD, Container)
21301d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    };
2131191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2132191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  }
2133191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian}
2134191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian
21356efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar/*
2136c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  struct _objc_property {
21373964e62786b0912fecc82d776daac236e05fc792Bill Wendling    const char * const name;
21383964e62786b0912fecc82d776daac236e05fc792Bill Wendling    const char * const attributes;
2139c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  };
2140c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
2141c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  struct _objc_property_list {
21423964e62786b0912fecc82d776daac236e05fc792Bill Wendling    uint32_t entsize; // sizeof (struct _objc_property)
21433964e62786b0912fecc82d776daac236e05fc792Bill Wendling    uint32_t prop_count;
21443964e62786b0912fecc82d776daac236e05fc792Bill Wendling    struct _objc_property[prop_count];
2145c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  };
2146c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar*/
21475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
21486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const Decl *Container,
21496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const ObjCContainerDecl *OCD,
21506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const ObjCCommonTypesHelper &ObjCTypes) {
21513964e62786b0912fecc82d776daac236e05fc792Bill Wendling  llvm::SmallVector<llvm::Constant*, 16> Properties;
2152191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian  llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
21536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
21546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar         E = OCD->prop_end(); I != E; ++I) {
2155581deb3da481053c4993c7600f97acf7768caac5David Blaikie    const ObjCPropertyDecl *PD = *I;
2156191dcd76046ea751f21aae008df21bb3468a2188Fariborz Jahanian    PropertySet.insert(PD->getIdentifier());
21571d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Prop[] = {
21581d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetPropertyName(PD->getIdentifier()),
21591d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetPropertyTypeString(PD, Container)
21601d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    };
216108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
2162c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar                                                   Prop));
2163c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  }
21646afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
216553b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek    for (ObjCInterfaceDecl::all_protocol_iterator
216653b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek         P = OID->all_referenced_protocol_begin(),
216753b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek         E = OID->all_referenced_protocol_end(); P != E; ++P)
21686afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian      PushProtocolProperties(PropertySet, Properties, Container, (*P),
21696afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian                             ObjCTypes);
21706afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian  }
21716afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian  else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
21726afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian    for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
21736afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian         E = CD->protocol_end(); P != E; ++P)
21746afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian      PushProtocolProperties(PropertySet, Properties, Container, (*P),
21756afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian                             ObjCTypes);
21766afbdf52563942cbf3d68c1cc0fcf590c94a47d3Fariborz Jahanian  }
2177c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
2178c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  // Return null for empty list.
2179c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  if (Properties.empty())
2180c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2181c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
21826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned PropertySize =
21839408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy);
2184c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
21854a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
21864a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
21876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
2188c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar                                             Properties.size());
21897db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[2] = llvm::ConstantArray::get(AT, Properties);
2190c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2191c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
21926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
21936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    CreateMetadataVar(Name, Init,
21946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                      (ObjCABI == 2) ? "__DATA, __objc_const" :
21950bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                      "__OBJC,__property,regular,no_dead_strip",
21966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                      (ObjCABI == 2) ? 8 : 4,
21970bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                      true);
21983c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
2199c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar}
2200c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
2201bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingllvm::Constant *
2202bb02855f46423d2034918b75b157f886bb04bcccBill WendlingCGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
2203bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                         ArrayRef<llvm::Constant*> MethodTypes,
2204bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                         const ObjCCommonTypesHelper &ObjCTypes) {
2205dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  // Return null for empty list.
2206dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  if (MethodTypes.empty())
2207dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson    return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
2208dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson
2209dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2210dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                                             MethodTypes.size());
2211dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
2212dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson
2213dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  llvm::GlobalVariable *GV =
2214dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson    CreateMetadataVar(Name, Init,
2215dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                      (ObjCABI == 2) ? "__DATA, __objc_const" : 0,
2216dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                      (ObjCABI == 2) ? 8 : 4,
2217dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                      true);
2218dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
2219dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson}
2220dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson
2221c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar/*
22226efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  struct objc_method_description_list {
22236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  int count;
22246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method_description list[];
22256efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  };
22266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar*/
2227ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant *
2228ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel DunbarCGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
22291d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Desc[] = {
22306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
22311d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                                   ObjCTypes.SelectorPtrTy),
22321d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetMethodVarType(MD)
22331d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
2234f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor  if (!Desc[1])
2235f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    return 0;
2236f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
223708e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
2238ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                                   Desc);
2239ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar}
22406efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
2241bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingllvm::Constant *
2242bb02855f46423d2034918b75b157f886bb04bcccBill WendlingCGObjCMac::EmitMethodDescList(Twine Name, const char *Section,
2243bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                              ArrayRef<llvm::Constant*> Methods) {
22446efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  // Return null for empty list.
22456efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  if (Methods.empty())
2246c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
22476efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
2248c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[2];
22494a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
22506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
22516efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                                             Methods.size());
22527db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[1] = llvm::ConstantArray::get(AT, Methods);
2253c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
22546efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
22550bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
22566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  return llvm::ConstantExpr::getBitCast(GV,
22576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar                                        ObjCTypes.MethodDescriptionListPtrTy);
2258c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2259c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
226086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar/*
226186e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  struct _objc_category {
22626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  char *category_name;
22636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  char *class_name;
22646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_method_list *instance_methods;
22656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_method_list *class_methods;
22666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_protocol_list *protocols;
22676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t size; // <rdar://4585769>
22686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_property_list *instance_properties;
226986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  };
22706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/
22717ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbarvoid CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
22729408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy);
227386e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
2274f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: This is poor design, the OCD should have a pointer to the category
2275f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // decl. Additionally, note that Category can be null for the @implementation
2276f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // w/o an @interface case. Sema should just create one for us as it does for
2277f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // @implementation so everyone else can live life under a clear blue sky.
227886e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
22796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCCategoryDecl *Category =
228086e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar    Interface->FindCategoryDeclaration(OCD->getIdentifier());
22819c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar
2282f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<256> ExtName;
22839c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
22849c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                     << OCD->getName();
228586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
22863964e62786b0912fecc82d776daac236e05fc792Bill Wendling  llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods;
22876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCCategoryImplDecl::instmeth_iterator
228817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
2289c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    // Instance methods should always be defined.
2290c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    InstanceMethods.push_back(GetMethodConstant(*i));
2291c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
22926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCCategoryImplDecl::classmeth_iterator
229317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
2294c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    // Class methods should always be defined.
2295c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    ClassMethods.push_back(GetMethodConstant(*i));
2296c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
2297c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
2298c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[7];
229986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  Values[0] = GetClassName(OCD->getIdentifier());
230086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  Values[1] = GetClassName(Interface->getIdentifier());
2301679cd7fcbd341fa3747e598f537601db421b1002Fariborz Jahanian  LazySymbols.insert(Interface->getIdentifier());
23026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[2] =
23039c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2304c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar                   "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2305c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                   InstanceMethods);
23066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[3] =
23079c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
23080bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                   "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2309c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                   ClassMethods);
2310ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  if (Category) {
23116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Values[4] =
23129c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar      EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2313ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       Category->protocol_begin(),
2314ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar                       Category->protocol_end());
2315ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  } else {
2316c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2317ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbar  }
23184a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
231986e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar
232086e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar  // If there is no category @interface then there can be no properties.
232186e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar  if (Category) {
23229c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
23235de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian                                 OCD, Category, ObjCTypes);
232486e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar  } else {
2325c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
232686e2f40071ca8c29284a3294fe2f20a01ec88971Daniel Dunbar  }
23276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
232808e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
232986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar                                                   Values);
233086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
23316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
23329c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
233363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                      "__OBJC,__category,regular,no_dead_strip",
233458a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar                      4, true);
233586e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  DefinedCategories.push_back(GV);
2336b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian  DefinedCategoryNames.insert(ExtName.str());
233764089cece350472c04b420c497ae391443353325Fariborz Jahanian  // method definition entries must be clear for next implementation.
233864089cece350472c04b420c497ae391443353325Fariborz Jahanian  MethodDefinitions.clear();
2339c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2340c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
234127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar// FIXME: Get from somewhere?
234227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarenum ClassFlags {
234327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_Factory              = 0x00001,
234427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_Meta                 = 0x00002,
234527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // <rdr://5142207>
234627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_HasCXXStructors      = 0x02000,
234727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_Hidden               = 0x20000,
234827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_ABI2_Hidden          = 0x00010,
234927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  eClassFlags_ABI2_HasCXXStructors = 0x00004   // <rdr://4923634>
235027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar};
235127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
235227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/*
235327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct _objc_class {
23546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Class isa;
23556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Class super_class;
23566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *name;
23576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long version;
23586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long info;
23596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  long instance_size;
23606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_ivar_list *ivars;
23616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_method_list *methods;
23626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_cache *cache;
23636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_protocol_list *protocols;
23646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // Objective-C 1.0 extensions (<rdr://4585769>)
23656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *ivar_layout;
23666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_class_ext *ext;
236727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
236827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
236927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  See EmitClassExtension();
23706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/
237127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarvoid CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
2372242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  DefinedSymbols.insert(ID->getIdentifier());
2373242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar
23748ec03f58c33c33a917f54bb7f2cd61b6d7ffe0caChris Lattner  std::string ClassName = ID->getNameAsString();
237527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // FIXME: Gross
23766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ObjCInterfaceDecl *Interface =
237727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar    const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
23786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Protocols =
23799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
238053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                     Interface->all_referenced_protocol_begin(),
238153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                     Interface->all_referenced_protocol_end());
238227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  unsigned Flags = eClassFlags_Factory;
2383f85e193739c953358c865005855253af4f68a497John McCall  if (ID->hasCXXStructors())
2384109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    Flags |= eClassFlags_HasCXXStructors;
23856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned Size =
23865f022d82696c84e4d127c558871d68ac6273274eKen Dyck    CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
238727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
238827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // FIXME: Set CXX-structors flag.
23891fb0caaa7bef765b85972274e3b434af2572c141John McCall  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
239027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar    Flags |= eClassFlags_Hidden;
239127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
23923964e62786b0912fecc82d776daac236e05fc792Bill Wendling  llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods;
23936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCImplementationDecl::instmeth_iterator
239417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
2395c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    // Instance methods should always be defined.
2396c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    InstanceMethods.push_back(GetMethodConstant(*i));
2397c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
23986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCImplementationDecl::classmeth_iterator
239917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
2400c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    // Class methods should always be defined.
2401c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    ClassMethods.push_back(GetMethodConstant(*i));
2402c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
2403c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
24046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCImplementationDecl::propimpl_iterator
240517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
2406581deb3da481053c4993c7600f97acf7768caac5David Blaikie    ObjCPropertyImplDecl *PID = *i;
2407c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
2408c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
2409c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar      ObjCPropertyDecl *PD = PID->getPropertyDecl();
2410c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
2411c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar      if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
2412c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar        if (llvm::Constant *C = GetMethodConstant(MD))
2413c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar          InstanceMethods.push_back(C);
2414c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar      if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
2415c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar        if (llvm::Constant *C = GetMethodConstant(MD))
2416c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar          InstanceMethods.push_back(C);
2417c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    }
2418c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  }
2419c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar
2420c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[12];
24215384b0990ea6995121fd4bad0855e96d41dcad18Daniel Dunbar  Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
242227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
2423242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar    // Record a reference to the super class.
2424242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar    LazySymbols.insert(Super->getIdentifier());
2425242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar
24266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Values[ 1] =
24273c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
242827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                     ObjCTypes.ClassPtrTy);
242927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  } else {
2430c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
243127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  }
243227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[ 2] = GetClassName(ID->getIdentifier());
243327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Version is always 0.
24344a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
24354a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
24364a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
243746b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian  Values[ 6] = EmitIvarList(ID, false);
24386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 7] =
24399c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
2440c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar                   "__OBJC,__inst_meth,regular,no_dead_strip",
2441c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                   InstanceMethods);
244227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // cache is always NULL.
2443c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
244427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[ 9] = Protocols;
24456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[10] = BuildIvarLayout(ID, true);
244627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[11] = EmitClassExtension(ID);
244708e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
244827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                                   Values);
2449b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  std::string Name("\01L_OBJC_CLASS_");
2450b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  Name += ClassName;
2451b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  const char *Section = "__OBJC,__class,regular,no_dead_strip";
2452b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  // Check for a forward reference.
2453b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2454b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  if (GV) {
2455b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2456b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian           "Forward metaclass reference has incorrect type.");
2457b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2458b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV->setInitializer(Init);
2459b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV->setSection(Section);
2460b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV->setAlignment(4);
2461b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    CGM.AddUsedGlobal(GV);
2462b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  }
2463b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  else
2464b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    GV = CreateMetadataVar(Name, Init, Section, 4, true);
246527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  DefinedClasses.push_back(GV);
246664089cece350472c04b420c497ae391443353325Fariborz Jahanian  // method definition entries must be clear for next implementation.
246764089cece350472c04b420c497ae391443353325Fariborz Jahanian  MethodDefinitions.clear();
246827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
246927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
247027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
247127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                         llvm::Constant *Protocols,
2472bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                         ArrayRef<llvm::Constant*> Methods) {
247327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  unsigned Flags = eClassFlags_Meta;
24749408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
247527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
24761fb0caaa7bef765b85972274e3b434af2572c141John McCall  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
247727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar    Flags |= eClassFlags_Hidden;
24786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2479c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[12];
248027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // The isa for the metaclass is the root of the hierarchy.
248127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  const ObjCInterfaceDecl *Root = ID->getClassInterface();
248227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
248327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar    Root = Super;
24846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 0] =
24853c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
248627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                   ObjCTypes.ClassPtrTy);
248786e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // The super class for the metaclass is emitted as the name of the
248886e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // super class. The runtime fixes this up to point to the
248986e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // *metaclass* for the super class.
249027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
24916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Values[ 1] =
24923c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
249327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                     ObjCTypes.ClassPtrTy);
249427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  } else {
2495c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
249627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  }
249727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[ 2] = GetClassName(ID->getIdentifier());
249827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Version is always 0.
24994a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
25004a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
25014a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
250246b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian  Values[ 6] = EmitIvarList(ID, true);
25036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 7] =
2504d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner    EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
25050bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                   "__OBJC,__cls_meth,regular,no_dead_strip",
2506c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                   Methods);
250727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // cache is always NULL.
2508c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
250927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  Values[ 9] = Protocols;
251027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // ivar_layout for metaclass is always NULL.
2511c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
251227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // The class extension is always unused for metaclasses.
2513c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
251408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
251527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                                   Values);
251627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2517f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  std::string Name("\01L_OBJC_METACLASS_");
251894be8ea90795d00fe2a97fea9a9a727911a70997Benjamin Kramer  Name += ID->getName();
2519f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
2520f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  // Check for a forward reference.
2521f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
2522f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  if (GV) {
2523f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2524f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar           "Forward metaclass reference has incorrect type.");
2525f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
2526f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    GV->setInitializer(Init);
2527f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  } else {
25281c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2529f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                  llvm::GlobalValue::InternalLinkage,
25301c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                  Init, Name);
2531f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  }
253227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
253358a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar  GV->setAlignment(4);
2534ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
253527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
253627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  return GV;
253727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
253827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
25396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
2540d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner  std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
2541f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
2542f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: Should we look these up somewhere other than the module. Its a bit
2543f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // silly since we only generate these while processing an implementation, so
2544f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // exactly one pointer would work if know when we entered/exitted an
2545f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // implementation block.
2546f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
2547f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  // Check for an existing forward reference.
2548b0d27943e133f099a39abc26a49d1130b5a8f5afFariborz Jahanian  // Previously, metaclass with internal linkage may have been defined.
2549b0d27943e133f099a39abc26a49d1130b5a8f5afFariborz Jahanian  // pass 'true' as 2nd argument so it is returned.
25506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
25516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                                   true)) {
2552f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2553f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar           "Forward metaclass reference has incorrect type.");
2554f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    return GV;
2555f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  } else {
2556f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    // Generate as an external reference to keep a consistent
2557f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    // module. This will be patched up when we emit the metaclass.
25581c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2559f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                    llvm::GlobalValue::ExternalLinkage,
2560b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian                                    0,
2561b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian                                    Name);
2562b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  }
2563b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian}
2564b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian
2565b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanianllvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
2566b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
2567b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian
2568b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
2569b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian                                                                   true)) {
2570b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
2571b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian           "Forward class metadata reference has incorrect type.");
2572b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    return GV;
2573b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian  } else {
2574b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
2575b0069eebb604114d5c9d37d0856fc39d1dfffd6dFariborz Jahanian                                    llvm::GlobalValue::ExternalLinkage,
2576f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                    0,
25771c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                    Name);
2578f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  }
2579f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar}
2580f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
258127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/*
258227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_class_ext {
25836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t size;
25846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const char *weak_ivar_layout;
25856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct _objc_property_list *properties;
258627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
258727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar*/
258827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *
258927f9d77b61b377b21ccda536122f2be6fa715751Daniel DunbarCGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
25906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint64_t Size =
25919408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
259227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2593c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
25944a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2595c71303de3e295d19c3617b6738da009f6e679337Fariborz Jahanian  Values[1] = BuildIvarLayout(ID, false);
25969c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
25975de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian                               ID, ID->getClassInterface(), ObjCTypes);
259827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
259927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Return null if no extension bits are used.
260027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (Values[1]->isNullValue() && Values[2]->isNullValue())
2601c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
260227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
26036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init =
260408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
26059c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
26066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           Init, "__OBJC,__class_ext,regular,no_dead_strip",
26070bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                           4, true);
260827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
260927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
261027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/*
261127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_ivar {
2612795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling    char *ivar_name;
2613795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling    char *ivar_type;
2614795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling    int ivar_offset;
261527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
261627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
261727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_ivar_list {
2618795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling    int ivar_count;
2619795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling    struct objc_ivar list[count];
262027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
26216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar*/
262227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbarllvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
262346b86c610ede6d9abdec254f39663db86c9c88e0Fariborz Jahanian                                        bool ForClass) {
26241d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  std::vector<llvm::Constant*> Ivars;
262527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
262627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // When emitting the root class GCC emits ivar entries for the
262727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // actual class structure. It is not clear if we need to follow this
262827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // behavior; for now lets try and get away with not doing it. If so,
262927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // the cleanest solution would be to make up an ObjCInterfaceDecl
263027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // for the class.
263127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (ForClass)
2632c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
26336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2634db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *OID = ID->getClassInterface();
26356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
2636db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
2637bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian       IVD; IVD = IVD->getNextIvar()) {
26388e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian    // Ignore unnamed bit-fields.
26398e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian    if (!IVD->getDeclName())
26406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      continue;
26411d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Ivar[] = {
26421d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetMethodVarName(IVD->getIdentifier()),
26431d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      GetMethodVarType(IVD),
26441d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer      llvm::ConstantInt::get(ObjCTypes.IntTy,
26451d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                             ComputeIvarBaseOffset(CGM, OID, IVD))
26461d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    };
264708e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
264827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  }
264927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
265027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Return null for empty list.
265127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (Ivars.empty())
2652c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
265327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2654c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[2];
26554a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
265696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
265727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                             Ivars.size());
26587db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[1] = llvm::ConstantArray::get(AT, Ivars);
2659c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
266027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
266163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  llvm::GlobalVariable *GV;
266263c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (ForClass)
26639c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
26646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           Init, "__OBJC,__class_vars,regular,no_dead_strip",
266558a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar                           4, true);
266663c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  else
26679c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
266863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                           Init, "__OBJC,__instance_vars,regular,no_dead_strip",
26690bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                           4, true);
26703c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
267127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
267227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
267327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar/*
267427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_method {
26756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  SEL method_name;
26766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  char *method_types;
26776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  void *method;
267827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
26796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
268027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  struct objc_method_list {
26816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method_list *obsolete;
26826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  int count;
26836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  struct objc_method methods_list[count];
268427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  };
268527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar*/
268627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2687c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// GetMethodConstant - Return a struct objc_method constant for the
2688c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// given method if it has been defined. The result is null if the
2689c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar/// method has not been defined. The return value has type MethodPtrTy.
2690ae226fa1141e22d1b997f19bd92c7223079d03f4Daniel Dunbarllvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
26919d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  llvm::Function *Fn = GetMethodDefinition(MD);
2692c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  if (!Fn)
2693c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar    return 0;
26946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
26951d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Method[] = {
26963c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
26971d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                                   ObjCTypes.SelectorPtrTy),
26981d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetMethodVarType(MD),
26991d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
27001d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
270108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
2702c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar}
270327f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
27045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerllvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
2705c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar                                          const char *Section,
2706bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                          ArrayRef<llvm::Constant*> Methods) {
270727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Return null for empty list.
270827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (Methods.empty())
2709c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
271027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
2711c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
2712c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
27134a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
271496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
271527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                                             Methods.size());
27167db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[2] = llvm::ConstantArray::get(AT, Methods);
2717c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
271827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
27190bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2720c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
2721b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar}
2722b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
2723493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanianllvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
27246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                const ObjCContainerDecl *CD) {
2725f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<256> Name;
2726679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian  GetNameForMethod(OMD, CD, Name);
2727b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
2728541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar  CodeGenTypes &Types = CGM.getTypes();
27292acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *MethodTy =
2730de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
27316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Function *Method =
273245c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar    llvm::Function::Create(MethodTy,
2733b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar                           llvm::GlobalValue::InternalLinkage,
2734c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar                           Name.str(),
2735b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar                           &CGM.getModule());
2736c45ef600ed6f1544e8dfca2a3fa554eb7d6a9908Daniel Dunbar  MethodDefinitions.insert(std::make_pair(OMD, Method));
2737b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
2738b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Method;
2739c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2740c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
2741fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbarllvm::GlobalVariable *
27425f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCCommonMac::CreateMetadataVar(Twine Name,
2743fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar                                   llvm::Constant *Init,
2744fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar                                   const char *Section,
274535bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar                                   unsigned Align,
274635bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar                                   bool AddToUsed) {
27472acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *Ty = Init->getType();
27486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *GV =
27491c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), Ty, false,
2750ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner                             llvm::GlobalValue::InternalLinkage, Init, Name);
2751fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  if (Section)
2752fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar    GV->setSection(Section);
275335bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  if (Align)
275435bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar    GV->setAlignment(Align);
275535bd763b9438b53f7920521ed19c1ef74c7a6795Daniel Dunbar  if (AddToUsed)
2756ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(GV);
2757fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar  return GV;
2758fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar}
2759fd65d370b14209e35cdbf7bb3b899b60ef207eabDaniel Dunbar
27606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Function *CGObjCMac::ModuleInitFunction() {
2761f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  // Abuse this interface function as a place to finalize.
2762f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  FinishModule();
2763c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar  return NULL;
2764c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
2765c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar
276674391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::GetPropertyGetFunction() {
276772db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  return ObjCTypes.getGetPropertyFn();
276849f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar}
276949f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar
277074391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::GetPropertySetFunction() {
277172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  return ObjCTypes.getSetPropertyFn();
277249f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar}
277349f6602707887eea1a558a1dffe0213102f887f2Daniel Dunbar
2774ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenekllvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
2775ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek                                                           bool copy) {
2776ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
2777ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek}
2778ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
27798fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnallllvm::Constant *CGObjCMac::GetGetStructFunction() {
27808fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall  return ObjCTypes.getCopyStructFn();
27818fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall}
27828fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnallllvm::Constant *CGObjCMac::GetSetStructFunction() {
27836cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian  return ObjCTypes.getCopyStructFn();
27846cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian}
27856cc590602f41c3e98e8af0023d54296c8eca7910Fariborz Jahanian
2786e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanianllvm::Constant *CGObjCMac::GetCppAtomicObjectFunction() {
2787e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian  return ObjCTypes.getCppAtomicObjectFunction();
2788e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian}
2789e3173021fa3bfdf7e6759d67838e385a83b2d57eFariborz Jahanian
279074391b48b4791cded373683a3baf67314f358d50Chris Lattnerllvm::Constant *CGObjCMac::EnumerationMutationFunction() {
279172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  return ObjCTypes.getEnumerationMutationFn();
27922abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson}
27932abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
2794f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
2795f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return EmitTryOrSynchronizedStmt(CGF, S);
2796f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
2797f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2798f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
2799f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                     const ObjCAtSynchronizedStmt &S) {
2800f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return EmitTryOrSynchronizedStmt(CGF, S);
2801f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
2802f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2803cc5052999cd064584492ba15a808b6e1cee6d931John McCallnamespace {
28041f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  struct PerformFragileFinally : EHScopeStack::Cleanup {
2805cc5052999cd064584492ba15a808b6e1cee6d931John McCall    const Stmt &S;
28060b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::Value *SyncArgSlot;
2807cc5052999cd064584492ba15a808b6e1cee6d931John McCall    llvm::Value *CallTryExitVar;
2808cc5052999cd064584492ba15a808b6e1cee6d931John McCall    llvm::Value *ExceptionData;
2809cc5052999cd064584492ba15a808b6e1cee6d931John McCall    ObjCTypesHelper &ObjCTypes;
2810cc5052999cd064584492ba15a808b6e1cee6d931John McCall    PerformFragileFinally(const Stmt *S,
28110b2517299415ab1c28b9cb87d536ccea84317a10John McCall                          llvm::Value *SyncArgSlot,
2812cc5052999cd064584492ba15a808b6e1cee6d931John McCall                          llvm::Value *CallTryExitVar,
2813cc5052999cd064584492ba15a808b6e1cee6d931John McCall                          llvm::Value *ExceptionData,
2814cc5052999cd064584492ba15a808b6e1cee6d931John McCall                          ObjCTypesHelper *ObjCTypes)
28150b2517299415ab1c28b9cb87d536ccea84317a10John McCall      : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
2816cc5052999cd064584492ba15a808b6e1cee6d931John McCall        ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
2817cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2818ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
2819cc5052999cd064584492ba15a808b6e1cee6d931John McCall      // Check whether we need to call objc_exception_try_exit.
2820cc5052999cd064584492ba15a808b6e1cee6d931John McCall      // In optimized code, this branch will always be folded.
2821cc5052999cd064584492ba15a808b6e1cee6d931John McCall      llvm::BasicBlock *FinallyCallExit =
2822cc5052999cd064584492ba15a808b6e1cee6d931John McCall        CGF.createBasicBlock("finally.call_exit");
2823cc5052999cd064584492ba15a808b6e1cee6d931John McCall      llvm::BasicBlock *FinallyNoCallExit =
2824cc5052999cd064584492ba15a808b6e1cee6d931John McCall        CGF.createBasicBlock("finally.no_call_exit");
2825cc5052999cd064584492ba15a808b6e1cee6d931John McCall      CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
2826cc5052999cd064584492ba15a808b6e1cee6d931John McCall                               FinallyCallExit, FinallyNoCallExit);
2827cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2828cc5052999cd064584492ba15a808b6e1cee6d931John McCall      CGF.EmitBlock(FinallyCallExit);
2829cc5052999cd064584492ba15a808b6e1cee6d931John McCall      CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
2830cc5052999cd064584492ba15a808b6e1cee6d931John McCall        ->setDoesNotThrow();
2831cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2832cc5052999cd064584492ba15a808b6e1cee6d931John McCall      CGF.EmitBlock(FinallyNoCallExit);
2833cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2834cc5052999cd064584492ba15a808b6e1cee6d931John McCall      if (isa<ObjCAtTryStmt>(S)) {
2835cc5052999cd064584492ba15a808b6e1cee6d931John McCall        if (const ObjCAtFinallyStmt* FinallyStmt =
2836d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall              cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
2837d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          // Save the current cleanup destination in case there's
2838d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          // control flow inside the finally statement.
2839d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          llvm::Value *CurCleanupDest =
2840d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall            CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
2841d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall
2842cc5052999cd064584492ba15a808b6e1cee6d931John McCall          CGF.EmitStmt(FinallyStmt->getFinallyBody());
2843cc5052999cd064584492ba15a808b6e1cee6d931John McCall
2844d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          if (CGF.HaveInsertPoint()) {
2845d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall            CGF.Builder.CreateStore(CurCleanupDest,
2846d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall                                    CGF.getNormalCleanupDestSlot());
2847d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          } else {
2848d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall            // Currently, the end of the cleanup must always exist.
2849d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall            CGF.EnsureInsertPoint();
2850d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall          }
2851d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall        }
2852cc5052999cd064584492ba15a808b6e1cee6d931John McCall      } else {
2853cc5052999cd064584492ba15a808b6e1cee6d931John McCall        // Emit objc_sync_exit(expr); as finally's sole statement for
2854cc5052999cd064584492ba15a808b6e1cee6d931John McCall        // @synchronized.
28550b2517299415ab1c28b9cb87d536ccea84317a10John McCall        llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
2856cc5052999cd064584492ba15a808b6e1cee6d931John McCall        CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
2857cc5052999cd064584492ba15a808b6e1cee6d931John McCall          ->setDoesNotThrow();
2858cc5052999cd064584492ba15a808b6e1cee6d931John McCall      }
2859cc5052999cd064584492ba15a808b6e1cee6d931John McCall    }
2860cc5052999cd064584492ba15a808b6e1cee6d931John McCall  };
286187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
286287bb5822bfa4baea23a3d9273df266777f3ab796John McCall  class FragileHazards {
286387bb5822bfa4baea23a3d9273df266777f3ab796John McCall    CodeGenFunction &CGF;
28645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<llvm::Value*, 20> Locals;
286587bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
286687bb5822bfa4baea23a3d9273df266777f3ab796John McCall
286787bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::InlineAsm *ReadHazard;
286887bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::InlineAsm *WriteHazard;
286987bb5822bfa4baea23a3d9273df266777f3ab796John McCall
287087bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::FunctionType *GetAsmFnType();
287187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
287287bb5822bfa4baea23a3d9273df266777f3ab796John McCall    void collectLocals();
287387bb5822bfa4baea23a3d9273df266777f3ab796John McCall    void emitReadHazard(CGBuilderTy &Builder);
287487bb5822bfa4baea23a3d9273df266777f3ab796John McCall
287587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  public:
287687bb5822bfa4baea23a3d9273df266777f3ab796John McCall    FragileHazards(CodeGenFunction &CGF);
28770b2517299415ab1c28b9cb87d536ccea84317a10John McCall
287887bb5822bfa4baea23a3d9273df266777f3ab796John McCall    void emitWriteHazard();
28790b2517299415ab1c28b9cb87d536ccea84317a10John McCall    void emitHazardsInNewBlocks();
288087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  };
288187bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
288287bb5822bfa4baea23a3d9273df266777f3ab796John McCall
288387bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Create the fragile-ABI read and write hazards based on the current
288487bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// state of the function, which is presumed to be immediately prior
288587bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// to a @try block.  These hazards are used to maintain correct
288687bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// semantics in the face of optimization and the fragile ABI's
288787bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// cavalier use of setjmp/longjmp.
288887bb5822bfa4baea23a3d9273df266777f3ab796John McCallFragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
288987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  collectLocals();
289087bb5822bfa4baea23a3d9273df266777f3ab796John McCall
289187bb5822bfa4baea23a3d9273df266777f3ab796John McCall  if (Locals.empty()) return;
289287bb5822bfa4baea23a3d9273df266777f3ab796John McCall
289387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Collect all the blocks in the function.
289487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  for (llvm::Function::iterator
289587bb5822bfa4baea23a3d9273df266777f3ab796John McCall         I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
289687bb5822bfa4baea23a3d9273df266777f3ab796John McCall    BlocksBeforeTry.insert(&*I);
289787bb5822bfa4baea23a3d9273df266777f3ab796John McCall
289887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  llvm::FunctionType *AsmFnTy = GetAsmFnType();
289987bb5822bfa4baea23a3d9273df266777f3ab796John McCall
290087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Create a read hazard for the allocas.  This inhibits dead-store
290187bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // optimizations and forces the values to memory.  This hazard is
290287bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // inserted before any 'throwing' calls in the protected scope to
290387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // reflect the possibility that the variables might be read from the
290487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // catch block if the call throws.
290587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  {
290687bb5822bfa4baea23a3d9273df266777f3ab796John McCall    std::string Constraint;
290787bb5822bfa4baea23a3d9273df266777f3ab796John McCall    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
290887bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (I) Constraint += ',';
290987bb5822bfa4baea23a3d9273df266777f3ab796John McCall      Constraint += "*m";
291087bb5822bfa4baea23a3d9273df266777f3ab796John McCall    }
291187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
291287bb5822bfa4baea23a3d9273df266777f3ab796John McCall    ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
291387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  }
291487bb5822bfa4baea23a3d9273df266777f3ab796John McCall
291587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Create a write hazard for the allocas.  This inhibits folding
291687bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // loads across the hazard.  This hazard is inserted at the
291787bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // beginning of the catch path to reflect the possibility that the
291887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // variables might have been written within the protected scope.
291987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  {
292087bb5822bfa4baea23a3d9273df266777f3ab796John McCall    std::string Constraint;
292187bb5822bfa4baea23a3d9273df266777f3ab796John McCall    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
292287bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (I) Constraint += ',';
292387bb5822bfa4baea23a3d9273df266777f3ab796John McCall      Constraint += "=*m";
292487bb5822bfa4baea23a3d9273df266777f3ab796John McCall    }
292587bb5822bfa4baea23a3d9273df266777f3ab796John McCall
292687bb5822bfa4baea23a3d9273df266777f3ab796John McCall    WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
292787bb5822bfa4baea23a3d9273df266777f3ab796John McCall  }
292887bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
292987bb5822bfa4baea23a3d9273df266777f3ab796John McCall
293087bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Emit a write hazard at the current location.
293187bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::emitWriteHazard() {
293287bb5822bfa4baea23a3d9273df266777f3ab796John McCall  if (Locals.empty()) return;
293387bb5822bfa4baea23a3d9273df266777f3ab796John McCall
29344c7d9f1507d0f102bd4133bba63348636facd469Jay Foad  CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow();
293587bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
293687bb5822bfa4baea23a3d9273df266777f3ab796John McCall
293787bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
293887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  assert(!Locals.empty());
29394c7d9f1507d0f102bd4133bba63348636facd469Jay Foad  Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow();
294087bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
294187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
294287bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// Emit read hazards in all the protected blocks, i.e. all the blocks
294387bb5822bfa4baea23a3d9273df266777f3ab796John McCall/// which have been inserted since the beginning of the try.
29440b2517299415ab1c28b9cb87d536ccea84317a10John McCallvoid FragileHazards::emitHazardsInNewBlocks() {
294587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  if (Locals.empty()) return;
294687bb5822bfa4baea23a3d9273df266777f3ab796John McCall
294787bb5822bfa4baea23a3d9273df266777f3ab796John McCall  CGBuilderTy Builder(CGF.getLLVMContext());
294887bb5822bfa4baea23a3d9273df266777f3ab796John McCall
294987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Iterate through all blocks, skipping those prior to the try.
295087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  for (llvm::Function::iterator
295187bb5822bfa4baea23a3d9273df266777f3ab796John McCall         FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
295287bb5822bfa4baea23a3d9273df266777f3ab796John McCall    llvm::BasicBlock &BB = *FI;
295387bb5822bfa4baea23a3d9273df266777f3ab796John McCall    if (BlocksBeforeTry.count(&BB)) continue;
295487bb5822bfa4baea23a3d9273df266777f3ab796John McCall
295587bb5822bfa4baea23a3d9273df266777f3ab796John McCall    // Walk through all the calls in the block.
295687bb5822bfa4baea23a3d9273df266777f3ab796John McCall    for (llvm::BasicBlock::iterator
295787bb5822bfa4baea23a3d9273df266777f3ab796John McCall           BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
295887bb5822bfa4baea23a3d9273df266777f3ab796John McCall      llvm::Instruction &I = *BI;
295987bb5822bfa4baea23a3d9273df266777f3ab796John McCall
296087bb5822bfa4baea23a3d9273df266777f3ab796John McCall      // Ignore instructions that aren't non-intrinsic calls.
296187bb5822bfa4baea23a3d9273df266777f3ab796John McCall      // These are the only calls that can possibly call longjmp.
296287bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
296387bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (isa<llvm::IntrinsicInst>(I))
296487bb5822bfa4baea23a3d9273df266777f3ab796John McCall        continue;
296587bb5822bfa4baea23a3d9273df266777f3ab796John McCall
296687bb5822bfa4baea23a3d9273df266777f3ab796John McCall      // Ignore call sites marked nounwind.  This may be questionable,
296787bb5822bfa4baea23a3d9273df266777f3ab796John McCall      // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
296887bb5822bfa4baea23a3d9273df266777f3ab796John McCall      llvm::CallSite CS(&I);
296987bb5822bfa4baea23a3d9273df266777f3ab796John McCall      if (CS.doesNotThrow()) continue;
297087bb5822bfa4baea23a3d9273df266777f3ab796John McCall
29710b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // Insert a read hazard before the call.  This will ensure that
29720b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // any writes to the locals are performed before making the
29730b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // call.  If the call throws, then this is sufficient to
29740b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // guarantee correctness as long as it doesn't also write to any
29750b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // locals.
297687bb5822bfa4baea23a3d9273df266777f3ab796John McCall      Builder.SetInsertPoint(&BB, BI);
297787bb5822bfa4baea23a3d9273df266777f3ab796John McCall      emitReadHazard(Builder);
297887bb5822bfa4baea23a3d9273df266777f3ab796John McCall    }
297987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  }
298087bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
298187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
298287bb5822bfa4baea23a3d9273df266777f3ab796John McCallstatic void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
298387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  if (V) S.insert(V);
298487bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
298587bb5822bfa4baea23a3d9273df266777f3ab796John McCall
298687bb5822bfa4baea23a3d9273df266777f3ab796John McCallvoid FragileHazards::collectLocals() {
298787bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Compute a set of allocas to ignore.
298887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  llvm::DenseSet<llvm::Value*> AllocasToIgnore;
298987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  addIfPresent(AllocasToIgnore, CGF.ReturnValue);
299087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
299187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
299287bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Collect all the allocas currently in the function.  This is
299387bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // probably way too aggressive.
299487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
299587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  for (llvm::BasicBlock::iterator
299687bb5822bfa4baea23a3d9273df266777f3ab796John McCall         I = Entry.begin(), E = Entry.end(); I != E; ++I)
299787bb5822bfa4baea23a3d9273df266777f3ab796John McCall    if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
299887bb5822bfa4baea23a3d9273df266777f3ab796John McCall      Locals.push_back(&*I);
299987bb5822bfa4baea23a3d9273df266777f3ab796John McCall}
300087bb5822bfa4baea23a3d9273df266777f3ab796John McCall
300187bb5822bfa4baea23a3d9273df266777f3ab796John McCallllvm::FunctionType *FragileHazards::GetAsmFnType() {
30025f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<llvm::Type *, 16> tys(Locals.size());
30030774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  for (unsigned i = 0, e = Locals.size(); i != e; ++i)
30040774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall    tys[i] = Locals[i]->getType();
30050774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  return llvm::FunctionType::get(CGF.VoidTy, tys, false);
3006cc5052999cd064584492ba15a808b6e1cee6d931John McCall}
3007cc5052999cd064584492ba15a808b6e1cee6d931John McCall
30086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/*
300918ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
30106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Objective-C setjmp-longjmp (sjlj) Exception Handling
30116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  --
301218ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
3013f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  A catch buffer is a setjmp buffer plus:
3014f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    - a pointer to the exception that was caught
3015f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    - a pointer to the previous exception data buffer
3016f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    - two pointers of reserved storage
3017f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Therefore catch buffers form a stack, with a pointer to the top
3018f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  of the stack kept in thread-local storage.
3019f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3020f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  objc_exception_try_enter pushes a catch buffer onto the EH stack.
3021f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  objc_exception_try_exit pops the given catch buffer, which is
3022f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    required to be the top of the EH stack.
3023f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  objc_exception_throw pops the top of the EH stack, writes the
3024f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    thrown exception into the appropriate field, and longjmps
3025f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    to the setjmp buffer.  It crashes the process (with a printf
3026f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    and an abort()) if there are no catch buffers on the stack.
3027f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  objc_exception_extract just reads the exception pointer out of the
3028f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    catch buffer.
3029f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3030f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  There's no reason an implementation couldn't use a light-weight
3031f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  setjmp here --- something like __builtin_setjmp, but API-compatible
3032f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  with the heavyweight setjmp.  This will be more important if we ever
3033f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  want to implement correct ObjC/C++ exception interactions for the
3034f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  fragile ABI.
3035f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3036f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Note that for this use of setjmp/longjmp to be correct, we may need
3037f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  to mark some local variables volatile: if a non-volatile local
3038f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  variable is modified between the setjmp and the longjmp, it has
3039f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  indeterminate value.  For the purposes of LLVM IR, it may be
3040f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  sufficient to make loads and stores within the @try (to variables
3041f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  declared outside the @try) volatile.  This is necessary for
3042f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  optimized correctness, but is not currently being done; this is
3043f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  being tracked as rdar://problem/8160285
3044f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
30456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  The basic framework for a @try-catch-finally is as follows:
30466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  {
304718ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  objc_exception_data d;
304818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  id _rethrow = null;
3049190d00e1396214c77539c7095756b9ea38160463Anders Carlsson  bool _call_try_exit = true;
30506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
305118ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  objc_exception_try_enter(&d);
305218ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  if (!setjmp(d.jmp_buf)) {
30536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ... try body ...
305418ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  } else {
30556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // exception path
30566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  id _caught = objc_exception_extract(&d);
30576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
30586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // enter new try scope for handlers
30596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (!setjmp(d.jmp_buf)) {
30606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ... match exception and execute catch blocks ...
30616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
30626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // fell off end, rethrow.
30636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  _rethrow = _caught;
30646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ... jump-through-finally to finally_rethrow ...
30656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  } else {
30666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  // exception in catch block
30676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  _rethrow = objc_exception_extract(&d);
30686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  _call_try_exit = false;
30696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ... jump-through-finally to finally_rethrow ...
30706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  }
307118ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  }
3072898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar  ... jump-through-finally to finally_end ...
307318ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
30746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  finally:
3075190d00e1396214c77539c7095756b9ea38160463Anders Carlsson  if (_call_try_exit)
30766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  objc_exception_try_exit(&d);
3077190d00e1396214c77539c7095756b9ea38160463Anders Carlsson
307818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar  ... finally block ....
3079898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar  ... dispatch to finally destination ...
3080898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar
30816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  finally_rethrow:
3082898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar  objc_exception_throw(_rethrow);
3083898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar
30846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  finally_end:
30856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  }
30866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
30876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  This framework differs slightly from the one gcc uses, in that gcc
30886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uses _rethrow to determine if objc_exception_try_exit should be called
30896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  and if the object should be rethrown. This breaks in the face of
30906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  throwing nil and introduces unnecessary branches.
30916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
30926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  We specialize this framework for a few particular circumstances:
30936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
30946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  - If there are no catch blocks, then we avoid emitting the second
30956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  exception handling context.
30966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
30976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
30986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  e)) we avoid emitting the code to rethrow an uncaught exception.
309918ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
31006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  - FIXME: If there is no @finally block we can do a few more
31016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  simplifications.
31026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
31036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Rethrows and Jumps-Through-Finally
31046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  --
31056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3106f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  '@throw;' is supported by pushing the currently-caught exception
3107f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  onto ObjCEHStack while the @catch blocks are emitted.
3108f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3109f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Branches through the @finally block are handled with an ordinary
3110f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  normal cleanup.  We do not register an EH cleanup; fragile-ABI ObjC
3111f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  exceptions are not compatible with C++ exceptions, and this is
3112f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  hardly the only place where this will go wrong.
3113f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3114f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  @synchronized(expr) { stmt; } is emitted as if it were:
3115f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    id synch_value = expr;
3116f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    objc_sync_enter(synch_value);
3117f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    @try { stmt; } @finally { objc_sync_exit(synch_value); }
311818ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar*/
311918ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
3120bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanianvoid CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
3121bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanian                                          const Stmt &S) {
3122bd71be4683c195260d5245118b1e13e6b2e20504Fariborz Jahanian  bool isTry = isa<ObjCAtTryStmt>(S);
3123f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3124f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // A destination for the fall-through edges of the catch handlers to
3125f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // jump to.
3126f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CodeGenFunction::JumpDest FinallyEnd =
3127f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.getJumpDestInCurrentScope("finally.end");
3128f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3129f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // A destination for the rethrow edge of the catch handlers to jump
3130f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // to.
3131f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CodeGenFunction::JumpDest FinallyRethrow =
3132f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.getJumpDestInCurrentScope("finally.rethrow");
31336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
31341c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  // For @synchronized, call objc_sync_enter(sync.expr). The
31351c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  // evaluation of the expression must occur before we enter the
31360b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // @synchronized.  We can't avoid a temp here because we need the
31370b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // value to be preserved.  If the backend ever does liveness
31380b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // correctly after setjmp, this will be unnecessary.
31390b2517299415ab1c28b9cb87d536ccea84317a10John McCall  llvm::Value *SyncArgSlot = 0;
31401c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  if (!isTry) {
31410b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::Value *SyncArg =
31421c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
31431c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar    SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
3144f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
3145f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotThrow();
31460b2517299415ab1c28b9cb87d536ccea84317a10John McCall
31470b2517299415ab1c28b9cb87d536ccea84317a10John McCall    SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
31480b2517299415ab1c28b9cb87d536ccea84317a10John McCall    CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
31491c56667febcf8e2d78bd8c1c720eca1888ff1d60Daniel Dunbar  }
3150898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar
31510b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // Allocate memory for the setjmp buffer.  This needs to be kept
31520b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // live throughout the try and catch blocks.
31530b2517299415ab1c28b9cb87d536ccea84317a10John McCall  llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
31540b2517299415ab1c28b9cb87d536ccea84317a10John McCall                                                    "exceptiondata.ptr");
31550b2517299415ab1c28b9cb87d536ccea84317a10John McCall
315687bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Create the fragile hazards.  Note that this will not capture any
315787bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // of the allocas required for exception processing, but will
315887bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // capture the current basic block (which extends all the way to the
315987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // setjmp call) as "before the @try".
316087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  FragileHazards Hazards(CGF);
316187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
3162f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Create a flag indicating whether the cleanup needs to call
3163f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // objc_exception_try_exit.  This is true except when
3164f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - no catches match and we're branching through the cleanup
3165f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     just to rethrow the exception, or
3166f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - a catch matched and we're falling out of the catch handler.
31670b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // The setjmp-safety rule here is that we should always store to this
31680b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // variable in a place that dominates the branch through the cleanup
31690b2517299415ab1c28b9cb87d536ccea84317a10John McCall  // without passing through any setjmps.
3170f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
3171190d00e1396214c77539c7095756b9ea38160463Anders Carlsson                                                     "_call_try_exit");
3172f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
31739e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall  // A slot containing the exception to rethrow.  Only needed when we
31749e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall  // have both a @catch and a @finally.
31759e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall  llvm::Value *PropagatingExnVar = 0;
31769e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall
3177f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Push a normal cleanup to leave the try scope.
31781f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S,
31790b2517299415ab1c28b9cb87d536ccea84317a10John McCall                                                 SyncArgSlot,
31801f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall                                                 CallTryExitVar,
31811f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall                                                 ExceptionData,
31821f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall                                                 &ObjCTypes);
31836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3184f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Enter a try block:
3185f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //  - Call objc_exception_try_enter to push ExceptionData on top of
3186f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //    the EH stack.
3187f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
3188f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotThrow();
3189898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar
3190f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //  - Call setjmp on the exception data buffer.
3191f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
3192f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
3193f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *SetJmpBuffer =
31940f6ac7cf7bc6a02c1a5c19d2c90ec0d1dd7786e7Jay Foad    CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer");
3195f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *SetJmpResult =
3196f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
3197f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  SetJmpResult->setDoesNotThrow();
31986446c3e3600032c5f17ca2324a4581b9301afa59Bill Wendling  SetJmpResult->setCanReturnTwice();
3199f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3200f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If setjmp returned 0, enter the protected block; otherwise,
3201f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // branch to the handler.
320255e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
320355e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
3204f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *DidCatch =
3205d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall    CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3206d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall  CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
320780f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
3208f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the protected block.
320980f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson  CGF.EmitBlock(TryBlock);
32100b2517299415ab1c28b9cb87d536ccea84317a10John McCall  CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
32116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
3212f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
32130b2517299415ab1c28b9cb87d536ccea84317a10John McCall
32140b2517299415ab1c28b9cb87d536ccea84317a10John McCall  CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
32156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3216f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the exception handler block.
3217e4b5ee06153777c6899d20797dce1d4d236eb4bcDaniel Dunbar  CGF.EmitBlock(TryHandler);
321855e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar
321987bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Don't optimize loads of the in-scope locals across this point.
322087bb5822bfa4baea23a3d9273df266777f3ab796John McCall  Hazards.emitWriteHazard();
322187bb5822bfa4baea23a3d9273df266777f3ab796John McCall
3222f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // For a @synchronized (or a @try with no catches), just branch
3223f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // through the cleanup to the rethrow block.
3224f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
3225f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Tell the cleanup not to re-pop the exit.
32260b2517299415ab1c28b9cb87d536ccea84317a10John McCall    CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3227f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson    CGF.EmitBranchThroughCleanup(FinallyRethrow);
3228f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3229f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Otherwise, we have to match against the caught exceptions.
3230f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else {
32310b2517299415ab1c28b9cb87d536ccea84317a10John McCall    // Retrieve the exception object.  We may emit multiple blocks but
32320b2517299415ab1c28b9cb87d536ccea84317a10John McCall    // nothing can cross this so the value is already in SSA form.
32330b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::CallInst *Caught =
32340b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
32350b2517299415ab1c28b9cb87d536ccea84317a10John McCall                             ExceptionData, "caught");
32360b2517299415ab1c28b9cb87d536ccea84317a10John McCall    Caught->setDoesNotThrow();
32370b2517299415ab1c28b9cb87d536ccea84317a10John McCall
3238f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Push the exception to rethrow onto the EH value stack for the
3239f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // benefit of any @throws in the handlers.
3240f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.ObjCEHValueStack.push_back(Caught);
3241f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
32428f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor    const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
3243f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
32440b2517299415ab1c28b9cb87d536ccea84317a10John McCall    bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
32450b2517299415ab1c28b9cb87d536ccea84317a10John McCall
32460b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::BasicBlock *CatchBlock = 0;
32470b2517299415ab1c28b9cb87d536ccea84317a10John McCall    llvm::BasicBlock *CatchHandler = 0;
32480b2517299415ab1c28b9cb87d536ccea84317a10John McCall    if (HasFinally) {
32499e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      // Save the currently-propagating exception before
32509e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      // objc_exception_try_enter clears the exception slot.
32519e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
32529e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall                                               "propagating_exception");
32539e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      CGF.Builder.CreateStore(Caught, PropagatingExnVar);
32549e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall
32550b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // Enter a new exception try block (in case a @catch block
32560b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // throws an exception).
32570b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
32580b2517299415ab1c28b9cb87d536ccea84317a10John McCall        ->setDoesNotThrow();
32590b2517299415ab1c28b9cb87d536ccea84317a10John McCall
32600b2517299415ab1c28b9cb87d536ccea84317a10John McCall      llvm::CallInst *SetJmpResult =
32610b2517299415ab1c28b9cb87d536ccea84317a10John McCall        CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer,
32620b2517299415ab1c28b9cb87d536ccea84317a10John McCall                               "setjmp.result");
32630b2517299415ab1c28b9cb87d536ccea84317a10John McCall      SetJmpResult->setDoesNotThrow();
32646446c3e3600032c5f17ca2324a4581b9301afa59Bill Wendling      SetJmpResult->setCanReturnTwice();
32650b2517299415ab1c28b9cb87d536ccea84317a10John McCall
32660b2517299415ab1c28b9cb87d536ccea84317a10John McCall      llvm::Value *Threw =
32670b2517299415ab1c28b9cb87d536ccea84317a10John McCall        CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
32686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
32690b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CatchBlock = CGF.createBasicBlock("catch");
32700b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CatchHandler = CGF.createBasicBlock("catch_for_catch");
32710b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
327280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
32730b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.EmitBlock(CatchBlock);
32740b2517299415ab1c28b9cb87d536ccea84317a10John McCall    }
32756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
32760b2517299415ab1c28b9cb87d536ccea84317a10John McCall    CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
32776bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
327855e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar    // Handle catch list. As a special case we check if everything is
327955e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar    // matched and avoid generating code for falling off the end if
328055e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar    // so.
328155e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar    bool AllMatched = false;
32828f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor    for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
32838f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor      const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
328480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
3285c00d8e18ad3d903acfeb5d05163ce90713066a3fDouglas Gregor      const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
328614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      const ObjCObjectPointerType *OPT = 0;
3287129271a42975f8b9d42adc707be9883db91c8a5dDaniel Dunbar
328880f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      // catch(...) always matches.
328955e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar      if (!CatchParam) {
329055e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar        AllMatched = true;
329155e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar      } else {
3292183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
32936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3294f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        // catch(id e) always matches under this ABI, since only
3295f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        // ObjC exceptions end up here in the first place.
329697f61d14c89c26b9ae8e8f1faa8e8fcc6ec00b77Daniel Dunbar        // FIXME: For the time being we also match id<X>; this should
329797f61d14c89c26b9ae8e8f1faa8e8fcc6ec00b77Daniel Dunbar        // be rejected by Sema instead.
3298818e96f5a42b2a9adea4ac0050340469b49d70efEli Friedman        if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
329955e40721e7c27611174e52378f50435c9ded27dbDaniel Dunbar          AllMatched = true;
330080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      }
33016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3302f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // If this is a catch-all, we don't need to test anything.
33036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      if (AllMatched) {
3304f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3305f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3306dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson        if (CatchParam) {
3307b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall          CGF.EmitAutoVarDecl(*CatchParam);
3308a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar          assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3309f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3310f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall          // These types work out because ConvertType(id) == i8*.
33117ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff          CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
3312dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson        }
33136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3314dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson        CGF.EmitStmt(CatchStmt->getCatchBody());
3315f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3316f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        // The scope of the catch variable ends right here.
3317f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        CatchVarCleanups.ForceCleanup();
3318f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3319f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson        CGF.EmitBranchThroughCleanup(FinallyEnd);
332080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson        break;
332180f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      }
33226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
332314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      assert(OPT && "Unexpected non-object pointer type in @catch");
3324506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall      const ObjCObjectType *ObjTy = OPT->getObjectType();
3325f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3326f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // FIXME: @catch (Class c) ?
3327506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall      ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
3328506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall      assert(IDecl && "Catch parameter must have Objective-C type!");
332980f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
333080f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      // Check if the @catch block matches the exception object.
3331506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall      llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl);
33326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3333f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::CallInst *Match =
333434b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner        CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
333534b02a11576fd6123a703102fc0405a5bb29f6a9Chris Lattner                                Class, Caught, "match");
3336f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Match->setDoesNotThrow();
33376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3338f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
3339f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
33406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
33416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
3342e4b5ee06153777c6899d20797dce1d4d236eb4bcDaniel Dunbar                               MatchedBlock, NextCatchBlock);
33436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
334480f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      // Emit the @catch block.
334580f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      CGF.EmitBlock(MatchedBlock);
3346f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3347f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Collect any cleanups for the catch variable.  The scope lasts until
3348f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // the end of the catch body.
33490b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3350f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3351b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall      CGF.EmitAutoVarDecl(*CatchParam);
3352a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar      assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
335318ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar
3354f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Initialize the catch variable.
33556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      llvm::Value *Tmp =
33566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar        CGF.Builder.CreateBitCast(Caught,
3357578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer                                  CGF.ConvertType(CatchParam->getType()));
33587ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff      CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
33596bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3360dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson      CGF.EmitStmt(CatchStmt->getCatchBody());
3361f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3362f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // We're done with the catch variable.
3363f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchVarCleanups.ForceCleanup();
3364f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
3365f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson      CGF.EmitBranchThroughCleanup(FinallyEnd);
33666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
336780f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson      CGF.EmitBlock(NextCatchBlock);
336880f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson    }
336980f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
3370f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.ObjCEHValueStack.pop_back();
3371f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
33720b2517299415ab1c28b9cb87d536ccea84317a10John McCall    // If nothing wanted anything to do with the caught exception,
33730b2517299415ab1c28b9cb87d536ccea84317a10John McCall    // kill the extract call.
33740b2517299415ab1c28b9cb87d536ccea84317a10John McCall    if (Caught->use_empty())
33750b2517299415ab1c28b9cb87d536ccea84317a10John McCall      Caught->eraseFromParent();
33760b2517299415ab1c28b9cb87d536ccea84317a10John McCall
33770b2517299415ab1c28b9cb87d536ccea84317a10John McCall    if (!AllMatched)
3378f3a79a96eecff0fba4de8e29831a5ec0eaf90385Anders Carlsson      CGF.EmitBranchThroughCleanup(FinallyRethrow);
33796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
33800b2517299415ab1c28b9cb87d536ccea84317a10John McCall    if (HasFinally) {
33810b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // Emit the exception handler for the @catch blocks.
33820b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.EmitBlock(CatchHandler);
3383f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
33840b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // In theory we might now need a write hazard, but actually it's
33850b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // unnecessary because there's no local-accessing code between
33860b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // the try's write hazard and here.
33870b2517299415ab1c28b9cb87d536ccea84317a10John McCall      //Hazards.emitWriteHazard();
3388f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
33899e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      // Extract the new exception and save it to the
33909e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      // propagating-exception slot.
33919e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      assert(PropagatingExnVar);
33929e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      llvm::CallInst *NewCaught =
33939e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall        CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
33949e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall                               ExceptionData, "caught");
33959e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      NewCaught->setDoesNotThrow();
33969e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
33979e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall
33980b2517299415ab1c28b9cb87d536ccea84317a10John McCall      // Don't pop the catch handler; the throw already did.
33990b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
34000b2517299415ab1c28b9cb87d536ccea84317a10John McCall      CGF.EmitBranchThroughCleanup(FinallyRethrow);
34010b2517299415ab1c28b9cb87d536ccea84317a10John McCall    }
340280f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson  }
34036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
340487bb5822bfa4baea23a3d9273df266777f3ab796John McCall  // Insert read hazards as required in the new blocks.
34050b2517299415ab1c28b9cb87d536ccea84317a10John McCall  Hazards.emitHazardsInNewBlocks();
340687bb5822bfa4baea23a3d9273df266777f3ab796John McCall
3407f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Pop the cleanup.
34080b2517299415ab1c28b9cb87d536ccea84317a10John McCall  CGF.Builder.restoreIP(TryFallthroughIP);
34090b2517299415ab1c28b9cb87d536ccea84317a10John McCall  if (CGF.HaveInsertPoint())
34100b2517299415ab1c28b9cb87d536ccea84317a10John McCall    CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3411f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.PopCleanupBlock();
34120b2517299415ab1c28b9cb87d536ccea84317a10John McCall  CGF.EmitBlock(FinallyEnd.getBlock(), true);
34136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3414f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the rethrow block.
341587bb5822bfa4baea23a3d9273df266777f3ab796John McCall  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
3416ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  CGF.EmitBlock(FinallyRethrow.getBlock(), true);
3417f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (CGF.HaveInsertPoint()) {
34189e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    // If we have a propagating-exception variable, check it.
34199e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    llvm::Value *PropagatingExn;
34209e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    if (PropagatingExnVar) {
34219e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
34229e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall
34239e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    // Otherwise, just look in the buffer for the exception to throw.
34249e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    } else {
34259e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      llvm::CallInst *Caught =
34269e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall        CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
34279e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall                               ExceptionData);
34289e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      Caught->setDoesNotThrow();
34299e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall      PropagatingExn = Caught;
34309e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    }
34310b2517299415ab1c28b9cb87d536ccea84317a10John McCall
34329e2213ddd5b3510fa48e3175e9d098db4224cc30John McCall    CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn)
3433f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotThrow();
3434f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateUnreachable();
3435f2878e5dffd20bf0a97fb0b30a376f2d60963593Fariborz Jahanian  }
343680f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson
343787bb5822bfa4baea23a3d9273df266777f3ab796John McCall  CGF.Builder.restoreIP(SavedIP);
343864d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
343964d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
344064d5d6c5903157c521af496479d06dc26032d718Anders Carlssonvoid CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
3441898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar                              const ObjCAtThrowStmt &S) {
34422b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson  llvm::Value *ExceptionAsObject;
34436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
34442b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson  if (const Expr *ThrowExpr = S.getThrowExpr()) {
34452b014d6c0c6b8ac94b416ac37dfc7931f20777a7John McCall    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
34466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    ExceptionAsObject =
3447578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer      CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
34482b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson  } else {
34496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
345018ccc7776ad6288c5f630dc7967fb99d099c9cd9Daniel Dunbar           "Unexpected rethrow outside @catch block.");
3451273558fbd891a0872e620e0d3d109b92c1160d72Anders Carlsson    ExceptionAsObject = CGF.ObjCEHValueStack.back();
34522b1e311009cf682b7b5adb8ba97a0816f727bfb7Anders Carlsson  }
34536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3454f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
3455f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ->setDoesNotReturn();
345680f2567e30959b4428c14b3cb872a91be10b69f9Anders Carlsson  CGF.Builder.CreateUnreachable();
3457a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar
3458a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar  // Clear the insertion point to indicate we are in unreachable code.
3459a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar  CGF.Builder.ClearInsertionPoint();
346064d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
346164d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
34623e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// EmitObjCWeakRead - Code gen for loading value of a __weak
34636dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian/// object: objc_read_weak (id *src)
34646dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian///
34653e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanianllvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
34661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                          llvm::Value *AddrWeakObj) {
34672acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type* DestTy =
34686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
34696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
34706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                          ObjCTypes.PtrObjectPtrTy);
347172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
34723e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian                                                  AddrWeakObj, "weakread");
34738339b35ca05dd040a9a0ecfc92e7b49d80c5a96bEli Friedman  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
34746dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian  return read_weak;
34756dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian}
34766dc2317b59cb1180a59f6c283d96b7a5dfeb5307Fariborz Jahanian
34773e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
34783e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian/// objc_assign_weak (id src, id *dst)
34793e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian///
34803e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanianvoid CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
34811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                   llvm::Value *src, llvm::Value *dst) {
34822acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
34830a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
34849408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
34850a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
34860a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
34876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
34883b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
34893b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
3490dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3491dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
349296508e1fea58347b6401ca9a4728c0b268174603Chris Lattner  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
34933e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian                          src, dst, "weakassign");
34943e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian  return;
34953e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian}
34963e283e344595e0bd499b13b30a92b7d9c10a2140Fariborz Jahanian
349758626500527695865683d1d65053743de8770b60Fariborz Jahanian/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
349858626500527695865683d1d65053743de8770b60Fariborz Jahanian/// objc_assign_global (id src, id *dst)
349958626500527695865683d1d65053743de8770b60Fariborz Jahanian///
350058626500527695865683d1d65053743de8770b60Fariborz Jahanianvoid CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
3501021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                     llvm::Value *src, llvm::Value *dst,
3502021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                     bool threadlocal) {
35032acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
35040a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
35059408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
35060a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
35070a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
35086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
35093b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
35103b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
3511dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3512dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3513021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  if (!threadlocal)
3514021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
3515021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                            src, dst, "globalassign");
3516021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  else
3517021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
3518021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                            src, dst, "threadlocalassign");
351958626500527695865683d1d65053743de8770b60Fariborz Jahanian  return;
352058626500527695865683d1d65053743de8770b60Fariborz Jahanian}
352158626500527695865683d1d65053743de8770b60Fariborz Jahanian
35227eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
35236c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
35247eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian///
35257eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanianvoid CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
35266c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                   llvm::Value *src, llvm::Value *dst,
35276c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                   llvm::Value *ivarOffset) {
35286c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian  assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
35292acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
35300a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
35319408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
35320a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
35330a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
35346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
35353b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
35363b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
35377eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
35387eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
35396c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian  CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
35406c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                          src, dst, ivarOffset);
35417eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian  return;
35427eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian}
35437eda8367cf63caee8acf907356b1d199ccaa6e89Fariborz Jahanian
354458626500527695865683d1d65053743de8770b60Fariborz Jahanian/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
354558626500527695865683d1d65053743de8770b60Fariborz Jahanian/// objc_assign_strongCast (id src, id *dst)
354658626500527695865683d1d65053743de8770b60Fariborz Jahanian///
354758626500527695865683d1d65053743de8770b60Fariborz Jahanianvoid CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
35481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                         llvm::Value *src, llvm::Value *dst) {
35492acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
35500a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
35519408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
35520a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
35530a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
35546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
35553b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
35563b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
3557dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
3558dbd32c20c529430fe1d22d87317f039849b8b0bbFariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
3559bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
356058626500527695865683d1d65053743de8770b60Fariborz Jahanian                          src, dst, "weakassign");
356158626500527695865683d1d65053743de8770b60Fariborz Jahanian  return;
356258626500527695865683d1d65053743de8770b60Fariborz Jahanian}
356358626500527695865683d1d65053743de8770b60Fariborz Jahanian
3564082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanianvoid CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
35656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                         llvm::Value *DestPtr,
35666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                         llvm::Value *SrcPtr,
356755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                         llvm::Value *size) {
3568082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
3569082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
3570082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
357155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                          DestPtr, SrcPtr, size);
3572082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  return;
3573082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian}
3574082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian
35750bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian/// EmitObjCValueForIvar - Code Gen for ivar reference.
35760bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian///
3577598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz JahanianLValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
3578598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                       QualType ObjectTy,
3579598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                       llvm::Value *BaseValue,
3580598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                       const ObjCIvarDecl *Ivar,
3581598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz Jahanian                                       unsigned CVRQualifiers) {
3582c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  const ObjCInterfaceDecl *ID =
3583c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall    ObjectTy->getAs<ObjCObjectType>()->getInterface();
35849777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
35859777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar                                  EmitIvarOffset(CGF, ID, Ivar));
35860bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian}
35870bb20361a321593887f067515dd04cf109f4c74aFariborz Jahanian
3588f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanianllvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
35892a03192a02dbf4fdff438d1e658356bde871aba4Daniel Dunbar                                       const ObjCInterfaceDecl *Interface,
3590f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian                                       const ObjCIvarDecl *Ivar) {
35919777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar  uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
35924a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  return llvm::ConstantInt::get(
35936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    CGM.getTypes().ConvertType(CGM.getContext().LongTy),
35946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Offset);
3595f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian}
3596f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian
3597f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/* *** Private Interface *** */
3598f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
3599f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// EmitImageInfo - Emit the image info marker used to encode some module
3600f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// level information.
3601f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar///
3602f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// See: <rdr://4810609&4810587&4810587>
3603f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// struct IMAGE_INFO {
3604f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar///   unsigned version;
3605f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar///   unsigned flags;
3606f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/// };
3607f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbarenum ImageInfoFlags {
3608fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  eImageInfo_FixAndContinue      = (1 << 0),
36096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  eImageInfo_GarbageCollected    = (1 << 1),
36106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  eImageInfo_GCOnly              = (1 << 2),
3611c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar  eImageInfo_OptimizedByDyld     = (1 << 3), // FIXME: When is this set.
3612c7c6dc0c7ad547f03778502a63a18c3277dd93b5Daniel Dunbar
3613fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  // A flag indicating that the module has no instances of a @synthesize of a
3614fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  // superclass variable. <rdar://problem/6803242>
36150982251be96409814c69d03193b558c7a927e1e8Bill Wendling  eImageInfo_CorrectedSynthesize = (1 << 4),
36160982251be96409814c69d03193b558c7a927e1e8Bill Wendling  eImageInfo_ImageIsSimulated    = (1 << 5)
3617f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar};
3618f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
3619fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbarvoid CGObjCCommonMac::EmitImageInfo() {
3620f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar  unsigned version = 0; // Version is unused?
36213973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  const char *Section = (ObjCABI == 1) ?
36223973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling    "__OBJC, __image_info,regular" :
36233973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling    "__DATA, __objc_imageinfo, regular, no_dead_strip";
36243973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling
36253973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  // Generate module-level named metadata to convey this information to the
36263973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  // linker and code-gen.
36273973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  llvm::Module &Mod = CGM.getModule();
36283973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling
36293973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  // Add the ObjC ABI version to the module flags.
36303973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
36313973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
36323973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling                    version);
36333973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
36343973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling                    llvm::MDString::get(VMContext,Section));
36353973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling
36364e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
36373973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling    // Non-GC overrides those files which specify GC.
36383973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling    Mod.addModuleFlag(llvm::Module::Override,
36393973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling                      "Objective-C Garbage Collection", (uint32_t)0);
36403973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  } else {
36413973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling    // Add the ObjC garbage collection value.
36423973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling    Mod.addModuleFlag(llvm::Module::Error,
36433973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling                      "Objective-C Garbage Collection",
36443973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling                      eImageInfo_GarbageCollected);
36453973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling
36464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
36473973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling      // Add the ObjC GC Only value.
36483973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling      Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
36493973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling                        eImageInfo_GCOnly);
36503973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling
36513973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling      // Require that GC be specified and set to eImageInfo_GarbageCollected.
36523973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling      llvm::Value *Ops[2] = {
36533973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling        llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
36543973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
36553973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling                               eImageInfo_GarbageCollected)
36563973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling      };
36573973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling      Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
36583973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling                        llvm::MDNode::get(VMContext, Ops));
36593973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling    }
36603973accabc855b81b55bcc1945a98b2adb2ce72aBill Wendling  }
36610982251be96409814c69d03193b558c7a927e1e8Bill Wendling
36620982251be96409814c69d03193b558c7a927e1e8Bill Wendling  // Indicate whether we're compiling this to run on a simulator.
36630982251be96409814c69d03193b558c7a927e1e8Bill Wendling  const llvm::Triple &Triple = CGM.getTarget().getTriple();
36640982251be96409814c69d03193b558c7a927e1e8Bill Wendling  if (Triple.getOS() == llvm::Triple::IOS &&
36650982251be96409814c69d03193b558c7a927e1e8Bill Wendling      (Triple.getArch() == llvm::Triple::x86 ||
36660982251be96409814c69d03193b558c7a927e1e8Bill Wendling       Triple.getArch() == llvm::Triple::x86_64))
36670982251be96409814c69d03193b558c7a927e1e8Bill Wendling    Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
36680982251be96409814c69d03193b558c7a927e1e8Bill Wendling                      eImageInfo_ImageIsSimulated);
3669f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar}
3670f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
36714e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// struct objc_module {
36724e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar//   unsigned long version;
36734e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar//   unsigned long size;
36744e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar//   const char *name;
36754e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar//   Symtab symtab;
36764e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// };
36774e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
36784e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar// FIXME: Get from somewhere
36794e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarstatic const int ModuleVersion = 7;
36804e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
36814e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarvoid CGObjCMac::EmitModuleInfo() {
36829408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy);
36836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
36841d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
36851d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
36861d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
36871d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    // This used to be the filename, now it is unused. <rdr://4327263>
36881d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetClassName(&CGM.getContext().Idents.get("")),
36891d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    EmitModuleSymbols()
36901d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
36916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CreateMetadataVar("\01L_OBJC_MODULES",
369208e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson                    llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
369363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                    "__OBJC,__module_info,regular,no_dead_strip",
369458a29128005f6e54c7d3aa39797d86ada8d40006Daniel Dunbar                    4, true);
36954e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar}
36964e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
36974e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbarllvm::Constant *CGObjCMac::EmitModuleSymbols() {
369827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  unsigned NumClasses = DefinedClasses.size();
369927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  unsigned NumCategories = DefinedCategories.size();
370027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
3701242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // Return null if no symbols were defined.
3702242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  if (!NumClasses && !NumCategories)
3703c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
3704242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar
3705c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[5];
37064a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3707c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
37084a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
37094a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
371027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
371186e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // The runtime expects exactly the list of defined classes followed
371286e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  // by the list of defined categories, in a single array.
37130b2397132efe74ee11c1b371dd9033820c54240fChris Lattner  SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
371486e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  for (unsigned i=0; i<NumClasses; i++)
37153c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
371686e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar                                                ObjCTypes.Int8PtrTy);
371786e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar  for (unsigned i=0; i<NumCategories; i++)
37186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Symbols[NumClasses + i] =
37193c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson      llvm::ConstantExpr::getBitCast(DefinedCategories[i],
372086e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar                                     ObjCTypes.Int8PtrTy);
372186e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
37226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[4] =
372396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
37240b2397132efe74ee11c1b371dd9033820c54240fChris Lattner                                                  Symbols.size()),
372527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar                             Symbols);
372627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
3727c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
372827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
37294e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  llvm::GlobalVariable *GV =
373063c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
373163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                      "__OBJC,__symbols,regular,no_dead_strip",
37320bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                      4, true);
37333c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
373427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
373527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
3736f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder,
3737f85e193739c953358c865005855253af4f68a497John McCall                                     IdentifierInfo *II) {
3738f85e193739c953358c865005855253af4f68a497John McCall  LazySymbols.insert(II);
3739f85e193739c953358c865005855253af4f68a497John McCall
3740f85e193739c953358c865005855253af4f68a497John McCall  llvm::GlobalVariable *&Entry = ClassReferences[II];
3741f85e193739c953358c865005855253af4f68a497John McCall
374227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  if (!Entry) {
37436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::Constant *Casted =
3744f85e193739c953358c865005855253af4f68a497John McCall    llvm::ConstantExpr::getBitCast(GetClassName(II),
3745f85e193739c953358c865005855253af4f68a497John McCall                                   ObjCTypes.ClassPtrTy);
37466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
3747f85e193739c953358c865005855253af4f68a497John McCall    CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
3748f85e193739c953358c865005855253af4f68a497John McCall                      "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
3749f85e193739c953358c865005855253af4f68a497John McCall                      4, true);
375027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  }
3751f85e193739c953358c865005855253af4f68a497John McCall
3752578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
37534e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar}
37544e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
3755f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
3756f85e193739c953358c865005855253af4f68a497John McCall                                     const ObjCInterfaceDecl *ID) {
3757f85e193739c953358c865005855253af4f68a497John McCall  return EmitClassRefFromId(Builder, ID->getIdentifier());
3758f85e193739c953358c865005855253af4f68a497John McCall}
3759f85e193739c953358c865005855253af4f68a497John McCall
3760f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
3761f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
3762f85e193739c953358c865005855253af4f68a497John McCall  return EmitClassRefFromId(Builder, II);
3763f85e193739c953358c865005855253af4f68a497John McCall}
3764f85e193739c953358c865005855253af4f68a497John McCall
376503b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanianllvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
376603b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                     bool lvalue) {
3767259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
37686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3769259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  if (!Entry) {
37706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::Constant *Casted =
37713c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
3772259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar                                     ObjCTypes.SelectorPtrTy);
37736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
377463c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar      CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
377563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                        "__OBJC,__message_refs,literal_pointers,no_dead_strip",
37760bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar                        4, true);
3777259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  }
3778259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
377903b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  if (lvalue)
378003b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian    return Entry;
3781578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
3782259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar}
3783259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
3784058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
37856efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  llvm::GlobalVariable *&Entry = ClassNames[Ident];
37864e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
378763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (!Entry)
37886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
378994010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner                              llvm::ConstantDataArray::getString(VMContext,
379094010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner                                                         Ident->getNameStart()),
3791af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                              ((ObjCABI == 2) ?
3792af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__objc_classname,cstring_literals" :
3793af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__cstring,cstring_literals"),
3794b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
37954e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
3796a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
37974e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar}
37984e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
37999d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidisllvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
38009d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
38019d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis      I = MethodDefinitions.find(MD);
38029d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  if (I != MethodDefinitions.end())
38039d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis    return I->second;
38049d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis
38059d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  return NULL;
38069d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis}
38079d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis
3808d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian/// GetIvarLayoutName - Returns a unique constant for the given
3809d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian/// ivar layout bitmap.
3810d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
38116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const ObjCCommonTypesHelper &ObjCTypes) {
3812c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3813d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian}
3814d80d81b53c08db00078c14d30aba4fa259a20ae0Fariborz Jahanian
3815d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbarvoid CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
38166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                unsigned int BytePos,
3817d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                                                bool ForStrongLayout,
3818d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                                                bool &HasUnion) {
3819d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar  const RecordDecl *RD = RT->getDecl();
3820d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar  // FIXME - Use iterator.
3821262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie  SmallVector<const FieldDecl*, 16> Fields;
3822262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie  for (RecordDecl::field_iterator i = RD->field_begin(),
3823262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie                                  e = RD->field_end(); i != e; ++i)
3824581deb3da481053c4993c7600f97acf7768caac5David Blaikie    Fields.push_back(*i);
38252acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
38266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const llvm::StructLayout *RecLayout =
3827d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar    CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
38286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3829d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar  BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
3830d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                      ForStrongLayout, HasUnion);
3831d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar}
3832d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar
38335a5a803df8a8e3e567278fdfd8a6c1aff8dc6b82Daniel Dunbarvoid CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
38346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             const llvm::StructLayout *Layout,
38356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             const RecordDecl *RD,
3836795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill Wendling                             ArrayRef<const FieldDecl*> RecFields,
38376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             unsigned int BytePos, bool ForStrongLayout,
38386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             bool &HasUnion) {
3839820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  bool IsUnion = (RD && RD->isUnion());
3840820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  uint64_t MaxUnionIvarSize = 0;
3841820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  uint64_t MaxSkippedUnionIvarSize = 0;
3842db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const FieldDecl *MaxField = 0;
3843db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const FieldDecl *MaxSkippedField = 0;
3844db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
3845900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar  uint64_t MaxFieldOffset = 0;
3846900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar  uint64_t MaxSkippedFieldOffset = 0;
38470dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis  uint64_t LastBitfieldOrUnnamedOffset = 0;
3848f85e193739c953358c865005855253af4f68a497John McCall  uint64_t FirstFieldDelta = 0;
38496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3850a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian  if (RecFields.empty())
3851a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    return;
3852bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
3853bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
38544e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
3855db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    const FieldDecl *FirstField = RecFields[0];
3856f85e193739c953358c865005855253af4f68a497John McCall    FirstFieldDelta =
3857f85e193739c953358c865005855253af4f68a497John McCall      ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
3858f85e193739c953358c865005855253af4f68a497John McCall  }
3859f85e193739c953358c865005855253af4f68a497John McCall
3860f1690858344968358131f8d5690d9ee458883000Chris Lattner  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3861db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    const FieldDecl *Field = RecFields[i];
3862e05cc98e97ec910829beccd0d890a002ce5ab909Daniel Dunbar    uint64_t FieldOffset;
3863fc514abac21dbd801e2b665a1a24075c5ff62f44Anders Carlsson    if (RD) {
3864f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar      // Note that 'i' here is actually the field index inside RD of Field,
3865f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar      // although this dependency is hidden.
3866f8f8ebafafa6f4469a44de7a64194f52be1b8f53Daniel Dunbar      const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
3867f85e193739c953358c865005855253af4f68a497John McCall      FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
3868fc514abac21dbd801e2b665a1a24075c5ff62f44Anders Carlsson    } else
3869f85e193739c953358c865005855253af4f68a497John McCall      FieldOffset =
3870f85e193739c953358c865005855253af4f68a497John McCall        ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
387125d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar
3872a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    // Skip over unnamed or bitfields
38737fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian    if (!Field->getIdentifier() || Field->isBitField()) {
38740dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      LastFieldBitfieldOrUnnamed = Field;
38750dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      LastBitfieldOrUnnamedOffset = FieldOffset;
3876a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian      continue;
38777fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian    }
387825d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar
38790dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis    LastFieldBitfieldOrUnnamed = 0;
3880a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    QualType FQT = Field->getType();
3881667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian    if (FQT->isRecordType() || FQT->isUnionType()) {
3882a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian      if (FQT->isUnionType())
3883a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian        HasUnion = true;
3884820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian
38856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
388625d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar                                BytePos + FieldOffset,
3887d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                                ForStrongLayout, HasUnion);
3888a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian      continue;
3889a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    }
38906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3891f1690858344968358131f8d5690d9ee458883000Chris Lattner    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
38926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      const ConstantArrayType *CArray =
38935e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar        dyn_cast_or_null<ConstantArrayType>(Array);
38947fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian      uint64_t ElCount = CArray->getSize().getZExtValue();
38955e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar      assert(CArray && "only array with known element size is supported");
3896820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian      FQT = CArray->getElementType();
3897667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian      while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
3898667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian        const ConstantArrayType *CArray =
38995e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar          dyn_cast_or_null<ConstantArrayType>(Array);
39007fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian        ElCount *= CArray->getSize().getZExtValue();
3901667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian        FQT = CArray->getElementType();
3902667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian      }
39036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
39046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      assert(!FQT->isUnionType() &&
3905820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian             "layout for array of unions not supported");
3906f96bdf409fc9e5570e35aaf8a9167265e63d58d8Fariborz Jahanian      if (FQT->isRecordType() && ElCount) {
390781adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian        int OldIndex = IvarsInfo.size() - 1;
390881adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian        int OldSkIndex = SkipIvars.size() -1;
39096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
39106217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        const RecordType *RT = FQT->getAs<RecordType>();
391125d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar        BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
3912d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar                                  ForStrongLayout, HasUnion);
39136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
3914820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        // Replicate layout information for each array element. Note that
3915820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        // one element is already done.
3916820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        uint64_t ElIx = 1;
39176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar        for (int FirstIndex = IvarsInfo.size() - 1,
39186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar               FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
3919c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian          uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
39208b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar          for (int i = OldIndex+1; i <= FirstIndex; ++i)
39218b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar            IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
39228b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                        IvarsInfo[i].ivar_size));
39238b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar          for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
39248b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar            SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
39258b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                        SkipIvars[i].ivar_size));
3926820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        }
3927820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        continue;
3928820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian      }
3929a5a10c37a02ac65f88624a29d1f7ad1d196fc7eaFariborz Jahanian    }
3930820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian    // At this point, we are done with Record/Union and array there of.
3931820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian    // For other arrays we are down to its element type.
39320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
39335e563dd38d6ec9f367cfd4b55d3efaf88a97cc09Daniel Dunbar
39348b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar    unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
39350953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
39360953e767ff7817f97b3ab20896b229891eeff45bJohn McCall        || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
3937487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar      if (IsUnion) {
39388b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar        uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
3939487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar        if (UnionIvarSize > MaxUnionIvarSize) {
3940820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          MaxUnionIvarSize = UnionIvarSize;
3941820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          MaxField = Field;
3942900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar          MaxFieldOffset = FieldOffset;
3943820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        }
3944487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar      } else {
394525d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar        IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
39468b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                    FieldSize / WordSizeInBits));
3947820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian      }
39486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    } else if ((ForStrongLayout &&
39490953e767ff7817f97b3ab20896b229891eeff45bJohn McCall                (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
39500953e767ff7817f97b3ab20896b229891eeff45bJohn McCall               || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
3951487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar      if (IsUnion) {
3952f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump        // FIXME: Why the asymmetry? We divide by word size in bits on other
3953f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump        // side.
39548b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar        uint64_t UnionIvarSize = FieldSize;
3955487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar        if (UnionIvarSize > MaxSkippedUnionIvarSize) {
3956820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          MaxSkippedUnionIvarSize = UnionIvarSize;
3957820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          MaxSkippedField = Field;
3958900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar          MaxSkippedFieldOffset = FieldOffset;
3959820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian        }
3960487993b90d432e9c866475ff0ffb8915e21c3904Daniel Dunbar      } else {
39618b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar        // FIXME: Why the asymmetry, we divide by byte size in bits here?
396225d583ec27cc2fe4d0dccaa5d41b6c3b645beda0Daniel Dunbar        SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
39638b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                    FieldSize / ByteSizeInBits));
3964820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian      }
3965820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian    }
3966820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  }
3967d58edcb49140b4e82f8b1e2f2e6ab35b9d401c99Daniel Dunbar
39680dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis  if (LastFieldBitfieldOrUnnamed) {
39690dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis    if (LastFieldBitfieldOrUnnamed->isBitField()) {
39700dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      // Last field was a bitfield. Must update skip info.
3971a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith      uint64_t BitFieldSize
3972a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith          = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
39730dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      GC_IVAR skivar;
39740dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
39750dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
39760dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis        + ((BitFieldSize % ByteSizeInBits) != 0);
39770dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      SkipIvars.push_back(skivar);
39780dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis    } else {
39790dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
39800dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      // Last field was unnamed. Must update skip info.
39810dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      unsigned FieldSize
39820dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis          = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
39830dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis      SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
39840dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis                                  FieldSize / ByteSizeInBits));
39850dc7509ed7f775f74106fbac37473da39b6c8e3aArgyrios Kyrtzidis    }
39867fb162785f42d74d419db3d0d37ba698bca780a1Fariborz Jahanian  }
39876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
39888b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar  if (MaxField)
39896bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
39908b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                MaxUnionIvarSize));
39918b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar  if (MaxSkippedField)
3992900c1980de73d17cdc11b108cde7f9b68be1e5bdDaniel Dunbar    SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
39938b2926c23645627d60d62667fc0e7a310e40815eDaniel Dunbar                                MaxSkippedUnionIvarSize));
3994d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian}
3995d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian
3996b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// BuildIvarLayoutBitmap - This routine is the horsework for doing all
3997b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// the computations and returning the layout bitmap (for ivar or blocks) in
3998b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// the given argument BitMap string container. Routine reads
3999b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// two containers, IvarsInfo and SkipIvars which are assumed to be
4000b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian/// filled already by the caller.
400194010695f7fce626e41ef045b60def9c912e9ce8Chris Lattnerllvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
40029397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  unsigned int WordsToScan, WordsToSkip;
40038b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner  llvm::Type *PtrTy = CGM.Int8PtrTy;
400493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
40059397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // Build the string of skip/scan nibbles
40065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<SKIP_SCAN, 32> SkipScanIvars;
40076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned int WordSize =
400893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
40099397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  if (IvarsInfo[0].ivar_bytepos == 0) {
40109397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    WordsToSkip = 0;
40119397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    WordsToScan = IvarsInfo[0].ivar_size;
401231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  } else {
40139397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
40149397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    WordsToScan = IvarsInfo[0].ivar_size;
40159397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
401631682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
40176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    unsigned int TailPrevGCObjC =
401893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
401931682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar    if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
40209397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // consecutive 'scanned' object pointers.
40219397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      WordsToScan += IvarsInfo[i].ivar_size;
402231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar    } else {
40239397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // Skip over 'gc'able object pointer which lay over each other.
40249397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
40259397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        continue;
40269397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // Must skip over 1 or more words. We save current skip/scan values
40279397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      //  and start a new pair.
4028c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SKIP_SCAN SkScan;
4029c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.skip = WordsToSkip;
4030c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.scan = WordsToScan;
403181adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian      SkipScanIvars.push_back(SkScan);
403293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
40339397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // Skip the hole.
4034c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
4035c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.scan = 0;
403681adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian      SkipScanIvars.push_back(SkScan);
40379397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      WordsToSkip = 0;
40389397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      WordsToScan = IvarsInfo[i].ivar_size;
40399397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
40409397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
404131682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  if (WordsToScan > 0) {
4042c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian    SKIP_SCAN SkScan;
4043c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian    SkScan.skip = WordsToSkip;
4044c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian    SkScan.scan = WordsToScan;
404581adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian    SkipScanIvars.push_back(SkScan);
40469397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
404793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
404831682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  if (!SkipIvars.empty()) {
404981adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian    unsigned int LastIndex = SkipIvars.size()-1;
40506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    int LastByteSkipped =
405193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
405281adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian    LastIndex = IvarsInfo.size()-1;
40536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    int LastByteScanned =
405493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    IvarsInfo[LastIndex].ivar_bytepos +
405593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    IvarsInfo[LastIndex].ivar_size * WordSize;
40569397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // Compute number of bytes to skip at the tail end of the last ivar scanned.
405754d76db0aa7107597cac0b80d8e138a37e6d1de9Benjamin Kramer    if (LastByteSkipped > LastByteScanned) {
40589397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
4059c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SKIP_SCAN SkScan;
4060c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.skip = TotalWords - (LastByteScanned/WordSize);
4061c8ce9c8c0b24e45aac06795a0222d8d1dbdeafccFariborz Jahanian      SkScan.scan = 0;
406281adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian      SkipScanIvars.push_back(SkScan);
40639397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
40649397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
40659397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
40669397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // as 0xMN.
406781adc058eaf450b43671633b2ad92e8bfa08d9b3Fariborz Jahanian  int SkipScan = SkipScanIvars.size()-1;
406831682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  for (int i = 0; i <= SkipScan; i++) {
40699397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
40709397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
40719397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      // 0xM0 followed by 0x0N detected.
40729397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
40739397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      for (int j = i+1; j < SkipScan; j++)
40749397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        SkipScanIvars[j] = SkipScanIvars[j+1];
40759397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      --SkipScan;
40769397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
40779397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
407893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
40799397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // Generate the string.
408031682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar  for (int i = 0; i <= SkipScan; i++) {
40819397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned char byte;
40829397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
40839397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
40849397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned int skip_big  = SkipScanIvars[i].skip / 0xf;
40859397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    unsigned int scan_big  = SkipScanIvars[i].scan / 0xf;
408693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
40879397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // first skip big.
40889397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    for (unsigned int ix = 0; ix < skip_big; ix++)
40899397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      BitMap += (unsigned char)(0xf0);
409093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
40919397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // next (skip small, scan)
409231682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar    if (skip_small) {
40939397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      byte = skip_small << 4;
409431682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar      if (scan_big > 0) {
40959397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        byte |= 0xf;
40969397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        --scan_big;
409731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar      } else if (scan_small) {
40989397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        byte |= scan_small;
40999397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian        scan_small = 0;
41009397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      }
41019397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      BitMap += byte;
41029397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
41039397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // next scan big
41049397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    for (unsigned int ix = 0; ix < scan_big; ix++)
41059397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      BitMap += (unsigned char)(0x0f);
41069397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    // last scan small
410731682fd385042369d490b2f73ecff2871467ade9Daniel Dunbar    if (scan_small) {
41089397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      byte = scan_small;
41099397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian      BitMap += byte;
41109397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian    }
41119397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  }
41129397e1dd41cb52fb3f49e1872d48897dcfb14859Fariborz Jahanian  // null terminate string.
4113667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian  unsigned char zero = 0;
4114667423a545c1f62efc32b48e5ce19c1c90181d4aFariborz Jahanian  BitMap += zero;
411593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
411693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  llvm::GlobalVariable * Entry =
411793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
411894010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner                    llvm::ConstantDataArray::getString(VMContext, BitMap,false),
4119af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                    ((ObjCABI == 2) ?
4120af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                     "__TEXT,__objc_classname,cstring_literals" :
4121af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                     "__TEXT,__cstring,cstring_literals"),
412293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian                    1, true);
412393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  return getConstantGEP(VMContext, Entry, 0, 0);
412493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian}
41256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
412693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// BuildIvarLayout - Builds ivar layout bitmap for the class
412793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// implementation for the __strong or __weak case.
412893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// The layout map displays which words in ivar list must be skipped
412993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// and which must be scanned by GC (see below). String is built of bytes.
413093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
413193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// of words to skip and right nibble is count of words to scan. So, each
413293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
413393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// represented by a 0x00 byte which also ends the string.
413493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 1. when ForStrongLayout is true, following ivars are scanned:
413593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - id, Class
413693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - object *
413793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - __strong anything
413893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian///
413993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// 2. When ForStrongLayout is false, following ivars are scanned:
414093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian/// - __weak anything
414193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian///
414293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanianllvm::Constant *CGObjCCommonMac::BuildIvarLayout(
414393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  const ObjCImplementationDecl *OMD,
414493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  bool ForStrongLayout) {
414593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  bool hasUnion = false;
414693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
41478b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner  llvm::Type *PtrTy = CGM.Int8PtrTy;
41484e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
41494e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      !CGM.getLangOpts().ObjCAutoRefCount)
415093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return llvm::Constant::getNullValue(PtrTy);
415193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
4152db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *OI = OMD->getClassInterface();
4153db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  SmallVector<const FieldDecl*, 32> RecFields;
41544e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().ObjCAutoRefCount) {
4155db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
4156bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian         IVD; IVD = IVD->getNextIvar())
4157bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian      RecFields.push_back(cast<FieldDecl>(IVD));
4158bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian  }
4159bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian  else {
4160db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    SmallVector<const ObjCIvarDecl*, 32> Ivars;
4161f85e193739c953358c865005855253af4f68a497John McCall    CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
416293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
4163db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    // FIXME: This is not ideal; we shouldn't have to do this copy.
4164db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    RecFields.append(Ivars.begin(), Ivars.end());
4165bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian  }
416693ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
416793ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (RecFields.empty())
416893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return llvm::Constant::getNullValue(PtrTy);
416993ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
417093ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  SkipIvars.clear();
417193ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  IvarsInfo.clear();
417293ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
417393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
417493ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  if (IvarsInfo.empty())
417593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian    return llvm::Constant::getNullValue(PtrTy);
4176b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  // Sort on byte position in case we encounterred a union nested in
4177b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  // the ivar list.
4178b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  if (hasUnion && !IvarsInfo.empty())
4179b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian    std::sort(IvarsInfo.begin(), IvarsInfo.end());
4180b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  if (hasUnion && !SkipIvars.empty())
4181b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian    std::sort(SkipIvars.begin(), SkipIvars.end());
4182b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian
418393ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  std::string BitMap;
4184b8fd2eb42a9f21c1ea65a5be37f3ce814c5cf745Fariborz Jahanian  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
418593ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian
41864e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie   if (CGM.getLangOpts().ObjCGCBitmapPrint) {
41876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    printf("\n%s ivar layout for class '%s': ",
41883d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian           ForStrongLayout ? "strong" : "weak",
41894087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar           OMD->getClassInterface()->getName().data());
419031ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky    const unsigned char *s = (const unsigned char*)BitMap.c_str();
419113562a1f30df391607604fb6bf345af42b0d831dBill Wendling    for (unsigned i = 0, e = BitMap.size(); i < e; i++)
41923d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian      if (!(s[i] & 0xf0))
41933d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
41943d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian      else
41953d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
41963d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian    printf("\n");
41973d2ad66b47d19fb771276a66ab8ac7c9c38694b7Fariborz Jahanian  }
419893ce50d0e6fda37a74033596d8c1c08e6ec27ab1Fariborz Jahanian  return C;
4199d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian}
4200d61a50a84d87a317cf929c6c1babf27d404b1e29Fariborz Jahanian
420156210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
4202259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar  llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
4203259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
42040b2397132efe74ee11c1b371dd9033820c54240fChris Lattner  // FIXME: Avoid std::string in "Sel.getAsString()"
420563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (!Entry)
42066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
420794010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner               llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
4208af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                              ((ObjCABI == 2) ?
4209af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__objc_methname,cstring_literals" :
4210af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__cstring,cstring_literals"),
4211b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
4212259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
4213a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
42146efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar}
42156efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
421627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar// FIXME: Merge into a single cstring creation function.
421756210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
421827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
421927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
422027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
42213e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbarllvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
42227794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel  std::string TypeStr;
42237794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel  CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
42247794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel
42257794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
42266efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
422763c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (!Entry)
422863c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
422994010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner                         llvm::ConstantDataArray::getString(VMContext, TypeStr),
4230af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                              ((ObjCABI == 2) ?
4231af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__objc_methtype,cstring_literals" :
4232af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__cstring,cstring_literals"),
4233b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
42346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4235a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
4236259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar}
4237259d93d1e1f820d5ee7251e875fdb7c883102f16Daniel Dunbar
4238dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilsonllvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
4239dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                                                  bool Extended) {
424027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  std::string TypeStr;
4241a4dc693368e7af4001fe88076bdf4efd440022faBill Wendling  if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
4242f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    return 0;
42437794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel
42447794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
42457794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel
4246b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar  if (!Entry)
4247b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
424894010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner                         llvm::ConstantDataArray::getString(VMContext, TypeStr),
4249af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                              ((ObjCABI == 2) ?
4250af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__objc_methtype,cstring_literals" :
4251af19ac4b39ea1a545bd279df38ac65144f84e4b2Daniel Dunbar                               "__TEXT,__cstring,cstring_literals"),
4252b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
42537794bb8271d97bea5d0bf52f4f050fbfff1a7420Devang Patel
4254a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
425527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar}
425627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
4257c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar// FIXME: Merge into a single cstring creation function.
425856210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanianllvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
4259c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  llvm::GlobalVariable *&Entry = PropertyNames[Ident];
42606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
426163c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar  if (!Entry)
42626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
426394010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner                        llvm::ConstantDataArray::getString(VMContext,
426494010695f7fce626e41ef045b60def9c912e9ce8Chris Lattner                                                       Ident->getNameStart()),
426563c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbar                              "__TEXT,__cstring,cstring_literals",
4266b90bb0099e9c8914ba18ddb2d30f9369b6de74d5Daniel Dunbar                              1, true);
4267c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
4268a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return getConstantGEP(VMContext, Entry, 0, 0);
4269c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar}
4270c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
4271c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar// FIXME: Merge into a single cstring creation function.
4272c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar// FIXME: This Decl should be more precise.
427363c5b50d80b9843acaea0a89d425b77454ac88d9Daniel Dunbarllvm::Constant *
42746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
42756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                       const Decl *Container) {
4276c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  std::string TypeStr;
4277c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
4278c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar  return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4279c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar}
4280c8ef551615e7c7e4aae7c2e845f998be42daef4fDaniel Dunbar
42816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
428256210f780b3d7e6533b3dd968ad9ba007cdbe7b4Fariborz Jahanian                                       const ObjCContainerDecl *CD,
42835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                       SmallVectorImpl<char> &Name) {
4284c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar  llvm::raw_svector_ostream OS(Name);
4285679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian  assert (CD && "Missing container decl in GetNameForMethod");
4286c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar  OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4287c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar     << '[' << CD->getName();
42886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (const ObjCCategoryImplDecl *CID =
4289c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar      dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
4290f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer    OS << '(' << *CID << ')';
4291c575ce7287ed9b5a2657aa0079595ebb59490afbDaniel Dunbar  OS << ' ' << D->getSelector().getAsString() << ']';
4292b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar}
4293b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
4294f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbarvoid CGObjCMac::FinishModule() {
42954e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  EmitModuleInfo();
42964e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
42970c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // Emit the dummy bodies for any protocols which were referenced but
42980c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // never defined.
42996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4300ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner         I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4301ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    if (I->second->hasInitializer())
43020c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar      continue;
43034e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
43041d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Values[5];
4305c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4306ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    Values[1] = GetClassName(I->first);
4307c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
43080c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar    Values[3] = Values[4] =
4309c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson      llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4310ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
431108e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
43120c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar                                                        Values));
4313ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(I->second);
43140c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  }
43150c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar
4316242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // Add assembler directives to add lazy undefined symbol references
4317242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // for classes which are referenced but not defined. This is
4318242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  // important for correct linker interaction.
4319330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  //
4320330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  // FIXME: It would be nice if we had an LLVM construct for this.
4321330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar  if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
4322f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith    SmallString<256> Asm;
4323330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    Asm += CGM.getModule().getModuleInlineAsm();
4324330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    if (!Asm.empty() && Asm.back() != '\n')
4325330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar      Asm += '\n';
4326330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar
4327330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    llvm::raw_svector_ostream OS(Asm);
4328330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4329330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar           e = DefinedSymbols.end(); I != e; ++I)
433001eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
433101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar         << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
4332afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner    for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
4333b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian         e = LazySymbols.end(); I != e; ++I) {
4334afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner      OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
4335b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian    }
4336b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian
433713562a1f30df391607604fb6bf345af42b0d831dBill Wendling    for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
4338b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian      OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
4339b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian         << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
4340b9c5b3ddde5a327cd31f3aacbfc7d1e491f99fcbFariborz Jahanian    }
4341afd5eda46e8e98e13e6cb0c937e39835eef5a296Chris Lattner
4342330634933b67f917e993e7de020cf671ac614acbDaniel Dunbar    CGM.getModule().setModuleInlineAsm(OS.str());
4343242d4dce3ab9a649866066b44c5a32cd2c09b6b8Daniel Dunbar  }
4344f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar}
4345f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
43466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
4347ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  : CGObjCCommonMac(cgm),
43481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ObjCTypes(cgm) {
4349aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
4350ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  ObjCABI = 2;
4351ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}
4352ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian
4353f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar/* *** */
4354f77ac86f4eca528a04b817d7ad7f045a47d52712Daniel Dunbar
4355ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz JahanianObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
435665a1e6707de0d6641e70d0a6edd7593fae85df3cDouglas Gregor  : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(0)
435765a1e6707de0d6641e70d0a6edd7593fae85df3cDouglas Gregor{
43584e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  CodeGen::CodeGenTypes &Types = CGM.getTypes();
43594e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  ASTContext &Ctx = CGM.getContext();
43606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
436127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  ShortTy = Types.ConvertType(Ctx.ShortTy);
43626efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  IntTy = Types.ConvertType(Ctx.IntTy);
43634e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  LongTy = Types.ConvertType(Ctx.LongTy);
43640a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  LongLongTy = Types.ConvertType(Ctx.LongLongTy);
43658b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner  Int8PtrTy = CGM.Int8PtrTy;
43668b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner  Int8PtrPtrTy = CGM.Int8PtrPtrTy;
43676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
43684e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
436996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
43704e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar  SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
43716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4372ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // I'm not sure I like this. The implicit coordination is a bit
4373ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // gross. We should solve this in a reasonable fashion because this
4374ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // is a pretty common task (match some runtime data structure with
4375ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // an LLVM data structure).
43766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4377ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // FIXME: This is leaked.
4378ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // FIXME: Merge with rewriter code?
43796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4380ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // struct _objc_super {
4381ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  //   id self;
4382ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  //   Class cls;
4383ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  // }
4384465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4385daa3ac503e93315ed3546463c13de4856bb80ef7Daniel Dunbar                                      Ctx.getTranslationUnitDecl(),
4386ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                      SourceLocation(), SourceLocation(),
43876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                      &Ctx.Idents.get("_objc_super"));
4388ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4389ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                Ctx.getObjCIdType(), 0, 0, false, ICIS_NoInit));
4390ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4391ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                Ctx.getObjCClassType(), 0, 0, false,
4392ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                ICIS_NoInit));
4393838db383b69b9fb55f55c8e9546477df198a4faaDouglas Gregor  RD->completeDefinition();
43946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4395ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  SuperCTy = Ctx.getTagDeclType(RD);
4396ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  SuperPtrCTy = Ctx.getPointerType(SuperCTy);
43976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4398ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian  SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
43996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
44006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
440130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _prop_t {
440230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *name;
44036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  //   char *attributes;
440430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
4405c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  PropertyTy = llvm::StructType::create("struct._prop_t",
4406c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                        Int8PtrTy, Int8PtrTy, NULL);
44076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
440830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _prop_list_t {
4409d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   uint32_t entsize;      // sizeof(struct _prop_t)
441030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t count_of_properties;
4411d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct _prop_t prop_list[count_of_properties];
441230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
44139cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  PropertyListTy =
4414c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
4415c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(PropertyTy, 0), NULL);
441630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _prop_list_t *
441796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
44186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
441930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _objc_method {
442030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   SEL _cmd;
442130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *method_type;
442230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *_imp;
442330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
4424c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  MethodTy = llvm::StructType::create("struct._objc_method",
4425c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                      SelectorPtrTy, Int8PtrTy, Int8PtrTy,
4426c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                      NULL);
44276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4428d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _objc_cache *
4429c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
443096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
44319d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
4432ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian}
44334e2d7d03b2e07ad5f4eb56be67f066ed1427b3a5Daniel Dunbar
44346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
44351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : ObjCCommonTypesHelper(cgm) {
443610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_method_description {
443710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   SEL name;
443810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *types;
443910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
44406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  MethodDescriptionTy =
4441c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_method_description",
4442c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             SelectorPtrTy, Int8PtrTy, NULL);
44436efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
444410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_method_description_list {
444510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   int count;
444610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description[1];
444710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
44486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  MethodDescriptionListTy =
4449c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_method_description_list",
4450c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             IntTy,
4451c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(MethodDescriptionTy, 0),NULL);
44526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
445310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_method_description_list *
44546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  MethodDescriptionListPtrTy =
445596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    llvm::PointerType::getUnqual(MethodDescriptionListTy);
44566efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
44576efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar  // Protocol description structures
44586efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
445910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_protocol_extension {
446010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   uint32_t size;  // sizeof(struct _objc_protocol_extension)
446110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description_list *optional_instance_methods;
446210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description_list *optional_class_methods;
446310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_property_list *instance_properties;
4464dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  //   const char ** extendedMethodTypes;
446510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
44666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ProtocolExtensionTy =
4467c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_protocol_extension",
4468c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             IntTy, MethodDescriptionListPtrTy,
4469c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             MethodDescriptionListPtrTy, PropertyListPtrTy,
4470dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                             Int8PtrPtrTy, NULL);
44716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
447210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_protocol_extension *
447396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
44746efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
44750c0e7a65214d0b4af68336d6d2fdce525695146aDaniel Dunbar  // Handle recursive construction of Protocol and ProtocolList types
44766efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
44779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolTy =
4478c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_protocol");
44796efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
44809cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolListTy =
4481c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_protocol_list");
44829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
4483ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian                          LongTy,
44849cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                          llvm::ArrayType::get(ProtocolTy, 0),
4485ee0af74d1e0990c7b66d32657f3e4e54b8691552Fariborz Jahanian                          NULL);
44866efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
448710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_protocol {
448810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_protocol_extension *isa;
448910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *protocol_name;
449010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_protocol **_objc_protocol_list;
449110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description_list *instance_methods;
449210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_description_list *class_methods;
449310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
44949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
44959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                      llvm::PointerType::getUnqual(ProtocolListTy),
44969cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                      MethodDescriptionListPtrTy,
44979cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                      MethodDescriptionListPtrTy,
44989cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                      NULL);
44999cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner
450010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_protocol_list *
450196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
45026efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel Dunbar
450396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
450427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
450527f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Class description structures
450627f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
450710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_ivar {
450810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *ivar_name;
450910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *ivar_type;
451010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   int  ivar_offset;
451110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
4512c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  IvarTy = llvm::StructType::create("struct._objc_ivar",
4513c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                    Int8PtrTy, Int8PtrTy, IntTy, NULL);
451427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
451510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_ivar_list *
45169cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  IvarListTy =
4517c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_ivar_list");
451896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
451927f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
452010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_method_list *
45219cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  MethodListTy =
4522c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_method_list");
452396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
452427f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
452510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_class_extension *
45266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ClassExtensionTy =
4527c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_class_extension",
4528c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             IntTy, Int8PtrTy, PropertyListPtrTy, NULL);
452996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
453027f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
4531c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
453227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
453310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_class {
453410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   Class isa;
453510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   Class super_class;
453610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *name;
453710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   long version;
453810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   long info;
453910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   long instance_size;
454010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_ivar_list *ivars;
454110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_list *methods;
454210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_cache *cache;
454310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_protocol_list *protocols;
454410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *ivar_layout;
454510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_class_ext *ext;
454610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // };
45479cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
45489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   llvm::PointerType::getUnqual(ClassTy),
45499cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   Int8PtrTy,
45509cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   LongTy,
45519cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   LongTy,
45529cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   LongTy,
45539cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   IvarListPtrTy,
45549cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   MethodListPtrTy,
45559cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   CachePtrTy,
45569cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   ProtocolListPtrTy,
45579cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   Int8PtrTy,
45589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   ClassExtensionPtrTy,
45599cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                   NULL);
45609cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner
456196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
456227f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
456310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_category {
456410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *category_name;
456510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *class_name;
456610a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_list *instance_method;
456710a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_method_list *class_method;
456810a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   uint32_t size;  // sizeof(struct _objc_category)
456910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   struct _objc_property_list *instance_properties;// category's @property
457010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
45719cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  CategoryTy =
4572c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_category",
4573c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             Int8PtrTy, Int8PtrTy, MethodListPtrTy,
4574c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             MethodListPtrTy, ProtocolListPtrTy,
4575c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             IntTy, PropertyListPtrTy, NULL);
457686e253a0cb438b118eb598abb0225d431c8798d2Daniel Dunbar
457727f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar  // Global metadata structures
457827f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
457910a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // struct _objc_symtab {
458010a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   long sel_ref_cnt;
458110a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   SEL *refs;
458210a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   short cls_def_cnt;
458310a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   short cat_def_cnt;
458410a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  //   char *defs[cls_def_cnt + cat_def_cnt];
458510a4231e73017e70231acebd55de2d2e48930a91Fariborz Jahanian  // }
45869cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  SymtabTy =
4587c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_symtab",
4588c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             LongTy, SelectorPtrTy, ShortTy, ShortTy,
4589c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(Int8PtrTy, 0), NULL);
459096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
459127f9d77b61b377b21ccda536122f2be6fa715751Daniel Dunbar
4592db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  // struct _objc_module {
4593db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //   long version;
4594db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //   long size;   // sizeof(struct _objc_module)
4595db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //   char *name;
4596db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //   struct _objc_symtab* symtab;
4597db2868616b966c96a5014e58892c27cea377477cFariborz Jahanian  //  }
45986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ModuleTy =
4599c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_module",
4600c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL);
460114c80b7ed64e0eddfbe81adf5113d5be5f9964bfDaniel Dunbar
46026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4603f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: This is the size of the setjmp buffer and should be target
4604f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // specific. 18 is what's used on 32-bit X86.
4605124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  uint64_t SetJmpBufferSize = 18;
46066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4607124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson  // Exceptions
46088b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner  llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
46096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
46106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  ExceptionDataTy =
4611c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_exception_data",
46128b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner                             llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
46138b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner                             StackPtrTy, NULL);
4614124526b72f35978e4c9d5e1af8ee125a65c1b917Anders Carlsson
4615bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar}
4616bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
46176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
46181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : ObjCCommonTypesHelper(cgm) {
461930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _method_list_t {
462030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t entsize;  // sizeof(struct _objc_method)
462130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t method_count;
462230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   struct _objc_method method_list[method_count];
462330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
46249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  MethodListnfABITy =
4625c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
4626c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(MethodTy, 0), NULL);
4627d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct method_list_t *
462896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
46296bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
463030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _protocol_t {
463130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   id isa;  // NULL
463230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const char * const protocol_name;
4633d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _protocol_list_t * protocol_list; // super protocols
463430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct method_list_t * const instance_methods;
463530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct method_list_t * const class_methods;
463630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct method_list_t *optionalInstanceMethods;
463730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct method_list_t *optionalClassMethods;
4638d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _prop_list_t * properties;
463930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const uint32_t size;  // sizeof(struct _protocol_t)
464030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const uint32_t flags;  // = 0
4641dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  //   const char ** extendedMethodTypes;
464230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
46436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4644d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // Holder for struct _protocol_list_t *
46459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolListnfABITy =
4646c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create(VMContext, "struct._objc_protocol_list");
46479cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner
46489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolnfABITy =
4649c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
4650c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::PointerType::getUnqual(ProtocolListnfABITy),
4651c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             MethodListnfABIPtrTy, MethodListnfABIPtrTy,
4652c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             MethodListnfABIPtrTy, MethodListnfABIPtrTy,
4653dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                             PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
4654dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                             NULL);
4655948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar
4656948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  // struct _protocol_t*
465796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
46586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4659da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // struct _protocol_list_t {
4660d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   long protocol_count;   // Note, this is 32/64 bit
4661948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  //   struct _protocol_t *[protocol_count];
466230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
46639cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ProtocolListnfABITy->setBody(LongTy,
46649cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                               llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
46659cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                               NULL);
46666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4667d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _objc_protocol_list*
466896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
46696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
467030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _ivar_t {
467130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   unsigned long int *offset;  // pointer to ivar offset location
467230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *name;
467330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   char *type;
467430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t alignment;
467530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t size;
467630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
46779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  IvarnfABITy =
4678c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._ivar_t",
4679c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::PointerType::getUnqual(LongTy),
4680c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
46816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
468230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // struct _ivar_list_t {
468330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32 entsize;  // sizeof(struct _ivar_t)
468430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32 count;
468530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   struct _iver_t list[count];
468630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
46879cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  IvarListnfABITy =
4688c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
4689c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::ArrayType::get(IvarnfABITy, 0), NULL);
46906bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
469196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
46926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4693d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _class_ro_t {
469430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t const flags;
469530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t const instanceStart;
469630bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t const instanceSize;
469730bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   uint32_t const reserved;  // only when building for 64bit targets
469830bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const uint8_t * const ivarLayout;
469930bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const char *const name;
470030bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct _method_list_t * const baseMethods;
470130bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct _objc_protocol_list *const baseProtocols;
470230bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct _ivar_list_t *const ivars;
470330bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const uint8_t * const weakIvarLayout;
470430bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  //   const struct _prop_list_t * const properties;
470530bc57187be7535c57ef1ca8ff3e765653e94332Fariborz Jahanian  // }
47066bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4707d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // FIXME. Add 'reserved' field in 64bit abi mode!
4708c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
4709c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            IntTy, IntTy, IntTy, Int8PtrTy,
4710c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            Int8PtrTy, MethodListnfABIPtrTy,
4711c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            ProtocolListnfABIPtrTy,
4712c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            IvarListnfABIPtrTy,
4713c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                            Int8PtrTy, PropertyListPtrTy, NULL);
47146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4715d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
47169cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
47170774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
47180774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall                 ->getPointerTo();
47196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4720d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _class_t {
4721d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct _class_t *isa;
4722d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct _class_t * const superclass;
4723d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   void *cache;
4724d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   IMP *vtable;
4725d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct class_ro_t *ro;
4726d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // }
47276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4728c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
47299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
47309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        llvm::PointerType::getUnqual(ClassnfABITy),
47319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        CachePtrTy,
47329cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        llvm::PointerType::getUnqual(ImpnfABITy),
47339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        llvm::PointerType::getUnqual(ClassRonfABITy),
47349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                        NULL);
47356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4736aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  // LLVM for struct _class_t *
473796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
47386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4739d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  // struct _category_t {
4740d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const char * const name;
4741d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   struct _class_t *const cls;
4742d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _method_list_t * const instance_methods;
4743d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _method_list_t * const class_methods;
4744d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _protocol_list_t * const protocols;
4745d55b6fc5f3304e97621b4d5a2d9376ad63d74179Fariborz Jahanian  //   const struct _prop_list_t * const properties;
474645c2ba0c13f353a8bab6cc01b30b3a13f3404c1eFariborz Jahanian  // }
4747c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner  CategorynfABITy = llvm::StructType::create("struct._category_t",
4748c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             Int8PtrTy, ClassnfABIPtrTy,
4749c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             MethodListnfABIPtrTy,
4750c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             MethodListnfABIPtrTy,
4751c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             ProtocolListnfABIPtrTy,
4752c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             PropertyListPtrTy,
4753c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                                             NULL);
47546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
47552e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // New types for nonfragile abi messaging.
475683a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  CodeGen::CodeGenTypes &Types = CGM.getTypes();
475783a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  ASTContext &Ctx = CGM.getContext();
47586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
47592e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // MessageRefTy - LLVM for:
47602e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // struct _message_ref_t {
47612e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   IMP messenger;
47622e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SEL name;
47632e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // };
47646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
476583a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  // First the clang type for struct _message_ref_t
4766465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
4767daa3ac503e93315ed3546463c13de4856bb80ef7Daniel Dunbar                                      Ctx.getTranslationUnitDecl(),
4768ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                      SourceLocation(), SourceLocation(),
476983a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian                                      &Ctx.Idents.get("_message_ref_t"));
4770ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4771ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                Ctx.VoidPtrTy, 0, 0, false, ICIS_NoInit));
4772ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
4773ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                Ctx.getObjCSelType(), 0, 0, false,
4774ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                ICIS_NoInit));
4775838db383b69b9fb55f55c8e9546477df198a4faaDouglas Gregor  RD->completeDefinition();
47766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
477783a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  MessageRefCTy = Ctx.getTagDeclType(RD);
477883a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
477983a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
47806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
47812e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // MessageRefPtrTy - LLVM for struct _message_ref_t*
478296e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
47836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
47842e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // SuperMessageRefTy - LLVM for:
47852e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // struct _super_message_ref_t {
47862e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SUPER_IMP messenger;
47872e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  //   SEL name;
47882e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // };
47899cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  SuperMessageRefTy =
4790c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._super_message_ref_t",
4791c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             ImpnfABITy, SelectorPtrTy, NULL);
47926bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
47932e4672b53107245deb998f55fb9dd77650d610ddFariborz Jahanian  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
47946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
47959d96bce991048fd2337cf058ec6a6a722207cbf2Fariborz Jahanian
4796e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
4797e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  // struct objc_typeinfo {
4798e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  //   const void** vtable; // objc_ehtype_vtable + 2
4799e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  //   const char*  name;    // c++ typeinfo string
4800e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  //   Class        cls;
4801e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  // };
48029cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  EHTypeTy =
4803c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner    llvm::StructType::create("struct._objc_typeinfo",
4804c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             llvm::PointerType::getUnqual(Int8PtrTy),
4805c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner                             Int8PtrTy, ClassnfABIPtrTy, NULL);
480696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
4807bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar}
4808bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
48096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
4810aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  FinishNonFragileABIModule();
48116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4812aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  return NULL;
4813aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian}
4814aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian
4815bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingvoid CGObjCNonFragileABIMac::
4816bb02855f46423d2034918b75b157f886bb04bcccBill WendlingAddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
4817bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                   const char *SymbolName,
4818bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                   const char *SectionName) {
4819463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  unsigned NumClasses = Container.size();
48206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4821463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  if (!NumClasses)
4822463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar    return;
48236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
48240b2397132efe74ee11c1b371dd9033820c54240fChris Lattner  SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
4825463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  for (unsigned i=0; i<NumClasses; i++)
48263c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
4827463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                                                ObjCTypes.Int8PtrTy);
48280b2397132efe74ee11c1b371dd9033820c54240fChris Lattner  llvm::Constant *Init =
482996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
48300b2397132efe74ee11c1b371dd9033820c54240fChris Lattner                                                  Symbols.size()),
4831463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                             Symbols);
48326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4833463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  llvm::GlobalVariable *GV =
48341c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
4835463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                             llvm::GlobalValue::InternalLinkage,
4836463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                             Init,
48371c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                             SymbolName);
48384b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar  GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
4839463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  GV->setSection(SectionName);
4840ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
4841463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar}
48426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4843aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianvoid CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
4844aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  // nonfragile abi has no module definition.
48456bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4846463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar  // Build list of all implemented class addresses in array
4847f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian  // L_OBJC_LABEL_CLASS_$.
48486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddModuleClassList(DefinedClasses,
4849463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                     "\01L_OBJC_LABEL_CLASS_$",
4850463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                     "__DATA, __objc_classlist, regular, no_dead_strip");
4851a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian
485213562a1f30df391607604fb6bf345af42b0d831dBill Wendling  for (unsigned i = 0, e = DefinedClasses.size(); i < e; i++) {
4853a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian    llvm::GlobalValue *IMPLGV = DefinedClasses[i];
4854a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
4855a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian      continue;
4856a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
4857a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  }
4858a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian
485913562a1f30df391607604fb6bf345af42b0d831dBill Wendling  for (unsigned i = 0, e = DefinedMetaClasses.size(); i < e; i++) {
48600e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian    llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
48610e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
48620e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian      continue;
48630e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
48640e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian  }
4865a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian
48666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddModuleClassList(DefinedNonLazyClasses,
486774d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar                     "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
486874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar                     "__DATA, __objc_nlclslist, regular, no_dead_strip");
48696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4870f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian  // Build list of all implemented category addresses in array
4871f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian  // L_OBJC_LABEL_CATEGORY_$.
48726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddModuleClassList(DefinedCategories,
4873463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                     "\01L_OBJC_LABEL_CATEGORY_$",
4874463b87687346d3990a9854382abfb41810f0678aDaniel Dunbar                     "__DATA, __objc_catlist, regular, no_dead_strip");
48756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddModuleClassList(DefinedNonLazyCategories,
487674d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar                     "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
487774d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar                     "__DATA, __objc_nlcatlist, regular, no_dead_strip");
48786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
4879fce176b051a5f6abe7464b6c75161476eceda0c5Daniel Dunbar  EmitImageInfo();
4880aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian}
4881aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian
4882944c84313da15477eb18d90babb0890d10d98082John McCall/// isVTableDispatchedSelector - Returns true if SEL is not in the list of
4883944c84313da15477eb18d90babb0890d10d98082John McCall/// VTableDispatchMethods; false otherwise. What this means is that
48846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar/// except for the 19 selectors in the list, we generate 32bit-style
4885d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian/// message dispatch call for all the rest.
4886944c84313da15477eb18d90babb0890d10d98082John McCallbool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
4887944c84313da15477eb18d90babb0890d10d98082John McCall  // At various points we've experimented with using vtable-based
4888944c84313da15477eb18d90babb0890d10d98082John McCall  // dispatch for all methods.
4889f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
4890f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  case CodeGenOptions::Legacy:
4891776dbf9704353515b422ee13e481194c937ba01dFariborz Jahanian    return false;
4892944c84313da15477eb18d90babb0890d10d98082John McCall  case CodeGenOptions::NonLegacy:
4893944c84313da15477eb18d90babb0890d10d98082John McCall    return true;
4894f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  case CodeGenOptions::Mixed:
4895f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar    break;
4896f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  }
4897f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar
4898f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  // If so, see whether this selector is in the white-list of things which must
4899f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar  // use the new dispatch convention. We lazily build a dense set for this.
4900944c84313da15477eb18d90babb0890d10d98082John McCall  if (VTableDispatchMethods.empty()) {
4901944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("alloc"));
4902944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("class"));
4903944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("self"));
4904944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
4905944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("length"));
4906944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetNullarySelector("count"));
4907944c84313da15477eb18d90babb0890d10d98082John McCall
4908944c84313da15477eb18d90babb0890d10d98082John McCall    // These are vtable-based if GC is disabled.
4909944c84313da15477eb18d90babb0890d10d98082John McCall    // Optimistically use vtable dispatch for hybrid compiles.
49104e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
4911944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetNullarySelector("retain"));
4912944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetNullarySelector("release"));
4913944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
4914944c84313da15477eb18d90babb0890d10d98082John McCall    }
4915944c84313da15477eb18d90babb0890d10d98082John McCall
4916944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
4917944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
4918944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
4919944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
4920944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
4921944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
4922944c84313da15477eb18d90babb0890d10d98082John McCall    VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
4923944c84313da15477eb18d90babb0890d10d98082John McCall
4924944c84313da15477eb18d90babb0890d10d98082John McCall    // These are vtable-based if GC is enabled.
4925944c84313da15477eb18d90babb0890d10d98082John McCall    // Optimistically use vtable dispatch for hybrid compiles.
49264e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
4927944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetNullarySelector("hash"));
4928944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(GetUnarySelector("addObject"));
4929944c84313da15477eb18d90babb0890d10d98082John McCall
4930944c84313da15477eb18d90babb0890d10d98082John McCall      // "countByEnumeratingWithState:objects:count"
4931944c84313da15477eb18d90babb0890d10d98082John McCall      IdentifierInfo *KeyIdents[] = {
4932944c84313da15477eb18d90babb0890d10d98082John McCall        &CGM.getContext().Idents.get("countByEnumeratingWithState"),
4933944c84313da15477eb18d90babb0890d10d98082John McCall        &CGM.getContext().Idents.get("objects"),
4934944c84313da15477eb18d90babb0890d10d98082John McCall        &CGM.getContext().Idents.get("count")
4935944c84313da15477eb18d90babb0890d10d98082John McCall      };
4936944c84313da15477eb18d90babb0890d10d98082John McCall      VTableDispatchMethods.insert(
4937944c84313da15477eb18d90babb0890d10d98082John McCall        CGM.getContext().Selectors.getSelector(3, KeyIdents));
4938944c84313da15477eb18d90babb0890d10d98082John McCall    }
4939d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian  }
4940f643b9b338b797a824447207d7eab5f1187f4f34Daniel Dunbar
4941944c84313da15477eb18d90babb0890d10d98082John McCall  return VTableDispatchMethods.count(Sel);
4942d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian}
4943d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian
4944058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian// Metadata flags
4945058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianenum MetaDataDlags {
4946058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  CLS = 0x0,
4947058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  CLS_META = 0x1,
4948058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  CLS_ROOT = 0x2,
4949493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  OBJC2_CLS_HIDDEN = 0x10,
4950f85e193739c953358c865005855253af4f68a497John McCall  CLS_EXCEPTION = 0x20,
4951f85e193739c953358c865005855253af4f68a497John McCall
4952f85e193739c953358c865005855253af4f68a497John McCall  /// (Obsolete) ARC-specific: this class has a .release_ivars method
4953f85e193739c953358c865005855253af4f68a497John McCall  CLS_HAS_IVAR_RELEASER = 0x40,
4954f85e193739c953358c865005855253af4f68a497John McCall  /// class was compiled with -fobjc-arr
4955f85e193739c953358c865005855253af4f68a497John McCall  CLS_COMPILED_BY_ARC = 0x80  // (1<<7)
4956058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian};
4957058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// BuildClassRoTInitializer - generate meta-data for:
4958058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_ro_t {
4959058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   uint32_t const flags;
4960058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   uint32_t const instanceStart;
4961058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   uint32_t const instanceSize;
4962058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   uint32_t const reserved;  // only when building for 64bit targets
4963058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const uint8_t * const ivarLayout;
4964058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const char *const name;
4965058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const struct _method_list_t * const baseMethods;
4966da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct _protocol_list_t *const baseProtocols;
4967058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const struct _ivar_list_t *const ivars;
4968058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const uint8_t * const weakIvarLayout;
4969058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   const struct _prop_list_t * const properties;
4970058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// }
4971058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///
4972058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanianllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
49736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned flags,
49746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned InstanceStart,
49756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  unsigned InstanceSize,
49766bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCImplementationDecl *ID) {
4977058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  std::string ClassName = ID->getNameAsString();
49781d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[10]; // 11 for 64bit targets!
4979f85e193739c953358c865005855253af4f68a497John McCall
49804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().ObjCAutoRefCount)
4981f85e193739c953358c865005855253af4f68a497John McCall    flags |= CLS_COMPILED_BY_ARC;
4982f85e193739c953358c865005855253af4f68a497John McCall
49834a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
49844a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
49854a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
4986058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  // FIXME. For 64bit targets add 0 here.
49876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
49886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    : BuildIvarLayout(ID, true);
4989058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  Values[ 4] = GetClassName(ID->getIdentifier());
4990493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  // const struct _method_list_t * const baseMethods;
4991493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  std::vector<llvm::Constant*> Methods;
4992493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  std::string MethodListName("\01l_OBJC_$_");
4993493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (flags & CLS_META) {
4994493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
49956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    for (ObjCImplementationDecl::classmeth_iterator
499617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis           i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
4997493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian      // Class methods should always be defined.
4998493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian      Methods.push_back(GetMethodConstant(*i));
4999493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    }
5000493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  } else {
5001493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
50026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    for (ObjCImplementationDecl::instmeth_iterator
500317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis           i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
5004493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian      // Instance methods should always be defined.
5005493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian      Methods.push_back(GetMethodConstant(*i));
5006493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    }
50076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    for (ObjCImplementationDecl::propimpl_iterator
500817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis           i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
5009581deb3da481053c4993c7600f97acf7768caac5David Blaikie      ObjCPropertyImplDecl *PID = *i;
50106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5011939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian      if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5012939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian        ObjCPropertyDecl *PD = PID->getPropertyDecl();
50136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5014939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian        if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5015939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian          if (llvm::Constant *C = GetMethodConstant(MD))
5016939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian            Methods.push_back(C);
5017939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian        if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5018939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian          if (llvm::Constant *C = GetMethodConstant(MD))
5019939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian            Methods.push_back(C);
5020939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian      }
5021939abced90071beb750041ee9c2cf57f827e024aFariborz Jahanian    }
5022493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  }
50236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 5] = EmitMethodList(MethodListName,
50246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                              "__DATA, __objc_const", Methods);
50256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5026da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  const ObjCInterfaceDecl *OID = ID->getClassInterface();
5027da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
50286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
50299c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                + OID->getName(),
503053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                                OID->all_referenced_protocol_begin(),
503153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                                OID->all_referenced_protocol_end());
50326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
503398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  if (flags & CLS_META)
5034c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
503598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  else
503698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian    Values[ 7] = EmitIvarList(ID);
50376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes)
50386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    : BuildIvarLayout(ID, false);
50395de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian  if (flags & CLS_META)
5040c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
50415de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian  else
50429c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
50439c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                  ID, ID->getClassInterface(), ObjCTypes);
504408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5045058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian                                                   Values);
5046058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  llvm::GlobalVariable *CLASS_RO_GV =
50476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
50486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             llvm::GlobalValue::InternalLinkage,
50496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             Init,
50506bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             (flags & CLS_META) ?
50516bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
50526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
505309796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  CLASS_RO_GV->setAlignment(
50544b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
50551bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian  CLASS_RO_GV->setSection("__DATA, __objc_const");
5056058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  return CLASS_RO_GV;
5057f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian
5058058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian}
5059058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian
5060058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// BuildClassMetaData - This routine defines that to-level meta-data
5061058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// for the given ClassName for:
5062058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// struct _class_t {
5063058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   struct _class_t *isa;
5064058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   struct _class_t * const superclass;
5065058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   void *cache;
5066058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   IMP *vtable;
5067058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///   struct class_ro_t *ro;
5068058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian/// }
5069058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian///
507084394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanianllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
50716bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  std::string &ClassName,
50726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *IsAGV,
50736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *SuperClassGV,
50746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *ClassRoGV,
50756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  bool HiddenVisibility) {
50761d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
50771d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    IsAGV,
50781d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    SuperClassGV,
50791d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    ObjCEmptyCacheVar,  // &ObjCEmptyCacheVar
50801d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
50811d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    ClassRoGV           // &CLASS_RO_GV
50821d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
50836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (!Values[1])
50846bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
50856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5086058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian                                                   Values);
50875a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
50885a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  GV->setInitializer(Init);
5089dd0db2a60b65e7eaa852b77c8b9f607640eb50b9Fariborz Jahanian  GV->setSection("__DATA, __objc_data");
509009796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  GV->setAlignment(
50914b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5092cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian  if (HiddenVisibility)
5093cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
509484394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  return GV;
5095058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian}
5096058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian
50976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarbool
5098ecfbdcbaf71609ab99cdebbf2d704173070dbaf3Fariborz JahanianCGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
509917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  return OD->getClassMethod(GetNullarySelector("load")) != 0;
510074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar}
510174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
51029f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbarvoid CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5103b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar                                              uint32_t &InstanceStart,
5104b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar                                              uint32_t &InstanceSize) {
51056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ASTRecordLayout &RL =
5106b4c79e027fdcc752b5a377611fd4cfbb21611a05Daniel Dunbar    CGM.getContext().getASTObjCImplementationLayout(OID);
51076bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
51086e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar  // InstanceSize is really instance end.
5109ec2990351335f163601b98e39b52425e2e9f931eKen Dyck  InstanceSize = RL.getDataSize().getQuantity();
51106e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar
51116e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar  // If there are no fields, the start is the same as the end.
51126e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar  if (!RL.getFieldCount())
51136e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar    InstanceStart = InstanceSize;
51146e8575b88bfb2634d7b28c0c4d5ed2a6acc8418aDaniel Dunbar  else
5115fb67ccd9da412d652d62e2ac9675b0f1b14fdc73Ken Dyck    InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5116b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar}
5117b02532a9e34d23de996cbf1f46fc978ef556c0e5Daniel Dunbar
5118aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanianvoid CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
5119aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  std::string ClassName = ID->getNameAsString();
5120aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian  if (!ObjCEmptyCacheVar) {
5121aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian    ObjCEmptyCacheVar = new llvm::GlobalVariable(
51226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      CGM.getModule(),
51236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      ObjCTypes.CacheTy,
51246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      false,
51256bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      llvm::GlobalValue::ExternalLinkage,
51266bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      0,
51276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "_objc_empty_cache");
51286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5129aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian    ObjCEmptyVtableVar = new llvm::GlobalVariable(
51306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      CGM.getModule(),
51316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      ObjCTypes.ImpnfABITy,
51326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      false,
51336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      llvm::GlobalValue::ExternalLinkage,
51346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      0,
51356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      "_objc_empty_vtable");
51366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  }
51376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  assert(ID->getClassInterface() &&
5138493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian         "CGObjCNonFragileABIMac::GenerateClass - class is 0");
51396c1aac8883ef2732a2d8543d7ac2a5ca9a199f86Daniel Dunbar  // FIXME: Is this correct (that meta class size is never computed)?
51406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t InstanceStart =
51419408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy);
5142058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  uint32_t InstanceSize = InstanceStart;
5143058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  uint32_t flags = CLS_META;
51446ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
51456ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  std::string ObjCClassName(getClassSymbolPrefix());
51466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5147058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  llvm::GlobalVariable *SuperClassGV, *IsAGV;
51486bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
51496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  bool classIsHidden =
51501fb0caaa7bef765b85972274e3b434af2572c141John McCall    ID->getClassInterface()->getVisibility() == HiddenVisibility;
5151cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian  if (classIsHidden)
5152493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    flags |= OBJC2_CLS_HIDDEN;
5153f85e193739c953358c865005855253af4f68a497John McCall  if (ID->hasCXXStructors())
5154109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    flags |= eClassFlags_ABI2_HasCXXStructors;
5155493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (!ID->getClassInterface()->getSuperClass()) {
5156058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian    // class is root
5157058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian    flags |= CLS_ROOT;
51585a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar    SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
51590f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian    IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
5160058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  } else {
516184394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian    // Has a root. Current class is not a root.
5162fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian    const ObjCInterfaceDecl *Root = ID->getClassInterface();
5163fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian    while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
5164fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian      Root = Super;
51650f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian    IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
51660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (Root->isWeakImported())
51670e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian      IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5168fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian    // work on super class metadata symbol.
51696bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    std::string SuperClassName =
51700e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian      ObjCMetaClassName +
51710e93d259ad19a0f70d3536d4f0f49710af52a169Fariborz Jahanian        ID->getClassInterface()->getSuperClass()->getNameAsString();
51720f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian    SuperClassGV = GetClassGlobal(SuperClassName);
51730a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (ID->getClassInterface()->getSuperClass()->isWeakImported())
5174a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5175058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  }
5176058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian  llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
5177058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian                                                               InstanceStart,
5178058a1b7f9d7d3498783f7d24e73235c4ba7ee851Fariborz Jahanian                                                               InstanceSize,ID);
517984394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  std::string TClassName = ObjCMetaClassName + ClassName;
51806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *MetaTClass =
5181cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian    BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
5182cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian                       classIsHidden);
5183a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian  DefinedMetaClasses.push_back(MetaTClass);
51846ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar
518584394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  // Metadata for the class
518684394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  flags = CLS;
5187cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian  if (classIsHidden)
5188493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    flags |= OBJC2_CLS_HIDDEN;
5189f85e193739c953358c865005855253af4f68a497John McCall  if (ID->hasCXXStructors())
5190109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    flags |= eClassFlags_ABI2_HasCXXStructors;
51918158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
519268584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor  if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
51938158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    flags |= CLS_EXCEPTION;
51948158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
5195493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (!ID->getClassInterface()->getSuperClass()) {
519684394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian    flags |= CLS_ROOT;
519784394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian    SuperClassGV = 0;
5198b7b58b1fcd3007730fd46471583543c9b57c7693Chris Lattner  } else {
519984394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian    // Has a root. Current class is not a root.
5200fab98c4e24a55960322c0f5e349df22c48597a73Fariborz Jahanian    std::string RootClassName =
520184394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian      ID->getClassInterface()->getSuperClass()->getNameAsString();
52025a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar    SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
52030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (ID->getClassInterface()->getSuperClass()->isWeakImported())
5204a03d0dd528573d0fc340370dc30ee7767c9cae9cFariborz Jahanian      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
520584394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  }
52069f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar  GetClassSizeInfo(ID, InstanceStart, InstanceSize);
520784394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  CLASS_RO_GV = BuildClassRoTInitializer(flags,
5208f6a077edbbfc88d63b43d43f22db93017685c130Fariborz Jahanian                                         InstanceStart,
52096bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                         InstanceSize,
5210f6a077edbbfc88d63b43d43f22db93017685c130Fariborz Jahanian                                         ID);
52116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
521284394a50e307e2f056e270e1eeadd4f26913cd1eFariborz Jahanian  TClassName = ObjCClassName + ClassName;
52136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *ClassMD =
5214cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian    BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
5215cf55516a2f8db4790e4f291fd94fe9e887d2464aFariborz Jahanian                       classIsHidden);
5216f87a0ccb05eb2aa095ea835fdcdf4a0363637b28Fariborz Jahanian  DefinedClasses.push_back(ClassMD);
52178158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
521874d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  // Determine if this class is also "non-lazy".
521974d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  if (ImplementationIsNonLazy(ID))
522074d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar    DefinedNonLazyClasses.push_back(ClassMD);
522174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
52228158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // Force the definition of the EHType if necessary.
52238158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (flags & CLS_EXCEPTION)
52248158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    GetInterfaceEHType(ID->getClassInterface(), true);
522564089cece350472c04b420c497ae391443353325Fariborz Jahanian  // Make sure method definition entries are all clear for next implementation.
522664089cece350472c04b420c497ae391443353325Fariborz Jahanian  MethodDefinitions.clear();
5227aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian}
5228aa23b570b059e8d29c69a656bbdc42f652f7c308Fariborz Jahanian
52298cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// GenerateProtocolRef - This routine is called to generate code for
52308cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// a protocol reference expression; as in:
52318cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @code
52328cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian///   @protocol(Proto1);
52338cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// @endcode
52348cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
52358cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian/// which will hold address of the protocol meta-data.
52368cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian///
52378cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
52386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                         const ObjCProtocolDecl *PD) {
52396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5240960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian  // This routine is called for @protocol only. So, we must build definition
5241960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian  // of protocol's meta-data (not a reference to it!)
5242960cd06eab1325071d331b462553c9e4135c926eFariborz Jahanian  //
52436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init =
52446bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
52454c86fdb84ff016ee708e71f563ffe2a1c1b96b26Douglas Gregor                                   ObjCTypes.getExternalProtocolPtrTy());
52466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
52478cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
52484087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar  ProtocolName += PD->getName();
52496bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
52508cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
52518cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  if (PTGV)
5252578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer    return Builder.CreateLoad(PTGV);
52538cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  PTGV = new llvm::GlobalVariable(
52546bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    CGM.getModule(),
52556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Init->getType(), false,
52566bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::GlobalValue::WeakAnyLinkage,
52576bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Init,
52586bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    ProtocolName);
52598cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
52608cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5261ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(PTGV);
5262578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(PTGV);
52638cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian}
52648cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian
5265eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// GenerateCategory - Build metadata for a category implementation.
5266eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// struct _category_t {
5267eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const char * const name;
5268eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   struct _class_t *const cls;
5269eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const struct _method_list_t * const instance_methods;
5270eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const struct _method_list_t * const class_methods;
5271eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const struct _protocol_list_t * const protocols;
5272eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///   const struct _prop_list_t * const properties;
5273eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian/// }
5274eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian///
527574d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbarvoid CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
5276eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
5277f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  const char *Prefix = "\01l_OBJC_$_CATEGORY_";
52786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  std::string ExtCatName(Prefix + Interface->getNameAsString()+
52796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                         "_$_" + OCD->getNameAsString());
52806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  std::string ExtClassName(getClassSymbolPrefix() +
52816ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar                           Interface->getNameAsString());
52826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
52831d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[6];
5284eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  Values[0] = GetClassName(OCD->getIdentifier());
5285eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  // meta-class entry symbol
52865a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
52870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Interface->isWeakImported())
52882cdcc4c4314b9db36028b10da8805fe02b1c85ebFariborz Jahanian    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
52892cdcc4c4314b9db36028b10da8805fe02b1c85ebFariborz Jahanian
5290eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  Values[1] = ClassGV;
5291f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  std::vector<llvm::Constant*> Methods;
5292f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  std::string MethodListName(Prefix);
52936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
5294f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    "_$_" + OCD->getNameAsString();
52956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
52966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCCategoryImplDecl::instmeth_iterator
529717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
5298f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    // Instance methods should always be defined.
5299f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    Methods.push_back(GetMethodConstant(*i));
5300f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  }
53016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
53026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[2] = EmitMethodList(MethodListName,
53036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             "__DATA, __objc_const",
5304f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian                             Methods);
5305f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian
5306f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  MethodListName = Prefix;
5307f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
5308f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    OCD->getNameAsString();
5309f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  Methods.clear();
53106bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCCategoryImplDecl::classmeth_iterator
531117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
5312f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    // Class methods should always be defined.
5313f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian    Methods.push_back(GetMethodConstant(*i));
5314f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian  }
53156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
53166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[3] = EmitMethodList(MethodListName,
53176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             "__DATA, __objc_const",
5318f6317dd7da4a3de06a45cba3ed9d47e6877b4ccaFariborz Jahanian                             Methods);
53196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCCategoryDecl *Category =
53205de14dc87966ab98730cfacffe0b7d3198a91a62Fariborz Jahanian    Interface->FindCategoryDeclaration(OCD->getIdentifier());
5321943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian  if (Category) {
5322f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith    SmallString<256> ExtName;
53239c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
53249c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                       << OCD->getName();
5325943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian    Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
53269c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                 + Interface->getName() + "_$_"
53279c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                 + Category->getName(),
5328943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian                                 Category->protocol_begin(),
5329943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian                                 Category->protocol_end());
53309c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
53319c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                 OCD, Category, ObjCTypes);
5332b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
5333c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5334c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5335943ed6ff5fafabc5ee1ea6a015908562688fbd47Fariborz Jahanian  }
53366bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
53376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Constant *Init =
53386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
5339eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian                              Values);
5340eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  llvm::GlobalVariable *GCATV
53416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
5342eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian                               false,
5343eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian                               llvm::GlobalValue::InternalLinkage,
5344eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian                               Init,
53451c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                               ExtCatName);
534609796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  GCATV->setAlignment(
53474b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy));
53481bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian  GCATV->setSection("__DATA, __objc_const");
5349ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GCATV);
5350eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian  DefinedCategories.push_back(GCATV);
535174d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar
535274d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  // Determine if this category is also "non-lazy".
535374d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar  if (ImplementationIsNonLazy(OCD))
535474d4b127d9f924ad354f47012e0d0e42ab1ee32bDaniel Dunbar    DefinedNonLazyCategories.push_back(GCATV);
535564089cece350472c04b420c497ae391443353325Fariborz Jahanian  // method definition entries must be clear for next implementation.
535664089cece350472c04b420c497ae391443353325Fariborz Jahanian  MethodDefinitions.clear();
5357eb062d922f10f7e649c2a18fab6c65bc169c77d5Fariborz Jahanian}
5358493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian
5359493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// GetMethodConstant - Return a struct objc_method constant for the
5360493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// given method if it has been defined. The result is null if the
5361493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// method has not been defined. The return value has type MethodPtrTy.
5362493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
53636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCMethodDecl *MD) {
53649d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis  llvm::Function *Fn = GetMethodDefinition(MD);
5365493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (!Fn)
5366493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian    return 0;
53676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
53681d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Method[] = {
53693c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
53701d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer                                   ObjCTypes.SelectorPtrTy),
53711d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetMethodVarType(MD),
53721d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
53731d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
537408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
5375493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian}
5376493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian
5377493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// EmitMethodList - Build meta-data for method declarations
5378493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// struct _method_list_t {
5379493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian///   uint32_t entsize;  // sizeof(struct _objc_method)
5380493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian///   uint32_t method_count;
5381493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian///   struct _objc_method method_list[method_count];
5382493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian/// }
5383493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian///
5384bb02855f46423d2034918b75b157f886bb04bcccBill Wendlingllvm::Constant *
5385bb02855f46423d2034918b75b157f886bb04bcccBill WendlingCGObjCNonFragileABIMac::EmitMethodList(Twine Name,
5386bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                       const char *Section,
5387bb02855f46423d2034918b75b157f886bb04bcccBill Wendling                                       ArrayRef<llvm::Constant*> Methods) {
5388493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  // Return null for empty list.
5389493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  if (Methods.empty())
5390c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
53916bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5392c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
5393493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  // sizeof(struct _objc_method)
53949408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy);
53954a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5396493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  // method_count
53974a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
539896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
5399493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian                                             Methods.size());
54007db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[2] = llvm::ConstantArray::get(AT, Methods);
5401c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
54026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5403493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  llvm::GlobalVariable *GV =
54041c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5405c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner                             llvm::GlobalValue::InternalLinkage, Init, Name);
5406c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType()));
5407493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian  GV->setSection(Section);
5408ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
5409c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
5410493dab7fe59303d8bb2120bc2556f355344f65bdFariborz Jahanian}
541198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian
5412ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
5413ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian/// the given ivar.
5414e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbarllvm::GlobalVariable *
5415e83be1228028f44de76cbad9d908e2dc9e261171Daniel DunbarCGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
5416e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar                                               const ObjCIvarDecl *Ivar) {
5417e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
5418a81419d0b53a40399a589a2fcc13f1ed2ec28f75Daniel Dunbar  std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
54196ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor    '.' + Ivar->getNameAsString();
54206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *IvarOffsetGV =
5421ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian    CGM.getModule().getGlobalVariable(Name);
5422ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  if (!IvarOffsetGV)
54236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    IvarOffsetGV =
54241c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
5425ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian                               false,
5426ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian                               llvm::GlobalValue::ExternalLinkage,
5427ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian                               0,
54281c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                               Name);
5429ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian  return IvarOffsetGV;
5430ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian}
5431ed157d3952637afe0ec38bf850b4d025b9a701acFariborz Jahanian
5432e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbarllvm::Constant *
5433e83be1228028f44de76cbad9d908e2dc9e261171Daniel DunbarCGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
5434e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar                                          const ObjCIvarDecl *Ivar,
5435e83be1228028f44de76cbad9d908e2dc9e261171Daniel Dunbar                                          unsigned long int Offset) {
5436737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar  llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
54376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
5438737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar                                                      Offset));
543909796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  IvarOffsetGV->setAlignment(
54404b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy));
5441737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar
5442f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
5443f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // well (i.e., in ObjCIvarOffsetVariable).
5444737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar  if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
5445737c502a3f259fc3790542366597c7e3fccad6fdDaniel Dunbar      Ivar->getAccessControl() == ObjCIvarDecl::Package ||
54461fb0caaa7bef765b85972274e3b434af2572c141John McCall      ID->getVisibility() == HiddenVisibility)
54472fa5a27f38b2c4abc26e86895fdcef3ec84af39dFariborz Jahanian    IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
544804d4078425614bf9fd58d606335c1f5f74ee7fa4Daniel Dunbar  else
544977c9fd2eee4cdac3c5a38a353788f308990598afFariborz Jahanian    IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
54501f382510495b581e3028d670a23c7dcf5440be62Bill Wendling  IvarOffsetGV->setSection("__DATA, __objc_ivar");
545145012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  return IvarOffsetGV;
54521bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian}
54531bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian
545498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// EmitIvarList - Emit the ivar list for the given
54551139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar/// implementation. The return value has type
545698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// IvarListnfABIPtrTy.
545798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///  struct _ivar_t {
545898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   unsigned long int *offset;  // pointer to ivar offset location
545998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   char *name;
546098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   char *type;
546198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   uint32_t alignment;
546298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   uint32_t size;
546398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// }
546498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// struct _ivar_list_t {
546598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   uint32 entsize;  // sizeof(struct _ivar_t)
546698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   uint32 count;
546798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///   struct _iver_t list[count];
546898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// }
546998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian///
54703e5f0d88d7eda79b7a679188d1e6da54cec72f5dDaniel Dunbar
547198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
54726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCImplementationDecl *ID) {
54736bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
54741d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  std::vector<llvm::Constant*> Ivars;
54756bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5476db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *OID = ID->getClassInterface();
547798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
54786bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
54791bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian  // FIXME. Consolidate this with similar code in GenerateClass.
54806bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5481db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
5482bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian       IVD; IVD = IVD->getNextIvar()) {
54838e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian    // Ignore unnamed bit-fields.
54848e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian    if (!IVD->getDeclName())
54858e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian      continue;
54861d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::Constant *Ivar[5];
54876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
54889f89f2bc111339ee7fa0df3c2f18e39493b460c4Daniel Dunbar                                ComputeIvarBaseOffset(CGM, ID, IVD));
54893fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar    Ivar[1] = GetMethodVarName(IVD->getIdentifier());
54903fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar    Ivar[2] = GetMethodVarType(IVD);
54912acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *FieldTy =
54923fea0c01e178e46eb20e81de4907a3d144c21fd6Daniel Dunbar      CGM.getTypes().ConvertTypeForMem(IVD->getType());
54939408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy);
549498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian    unsigned Align = CGM.getContext().getPreferredTypeAlign(
54956bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      IVD->getType().getTypePtr()) >> 3;
549698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian    Align = llvm::Log2_32(Align);
54974a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
549891636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // NOTE. Size of a bitfield does not match gcc's, because of the
549991636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // way bitfields are treated special in each. But I am told that
550091636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // 'size' for bitfield ivars is ignored by the runtime so it does
550191636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // not matter.  If it matters, there is enough info to get the
550291636d6c4c07fd2edf19a510b02c6e793a28741fDaniel Dunbar    // bitfield right!
55034a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
550408e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
550598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  }
550698abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  // Return null for empty list.
550798abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  if (Ivars.empty())
5508c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5509c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner
5510c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[3];
55119408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands  unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy);
55124a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
55134a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
551496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
551598abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian                                             Ivars.size());
55167db6d838aad4083fe86d7bf703a75fe6e8a17856Owen Anderson  Values[2] = llvm::ConstantArray::get(AT, Ivars);
5517c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
551898abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
551998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian  llvm::GlobalVariable *GV =
55201c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
552198abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian                             llvm::GlobalValue::InternalLinkage,
552298abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian                             Init,
55239c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             Prefix + OID->getName());
552409796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  GV->setAlignment(
55254b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(Init->getType()));
55261bf0afbb08a23412d1607505c092a537f305d8c7Fariborz Jahanian  GV->setSection("__DATA, __objc_const");
55276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5528ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
55293c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
5530da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian}
5531da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5532da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
55336bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCProtocolDecl *PD) {
5534da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
55356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5536da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  if (!Entry) {
5537da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    // We use the initializer as a marker of whether this is a forward
5538da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    // reference or not. At module finalization we add the empty
5539da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    // contents for protocols which were referenced but never defined.
55406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
55416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
55426bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               llvm::GlobalValue::ExternalLinkage,
55436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               0,
55449c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
5545da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    Entry->setSection("__DATA,__datacoal_nt,coalesced");
5546da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  }
55476bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5548da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  return Entry;
5549da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian}
5550da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5551da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// GetOrEmitProtocol - Generate the protocol meta-data:
5552da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @code
5553da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_t {
5554da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   id isa;  // NULL
5555da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const char * const protocol_name;
5556da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct _protocol_list_t * protocol_list; // super protocols
5557da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct method_list_t * const instance_methods;
5558da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct method_list_t * const class_methods;
5559da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct method_list_t *optionalInstanceMethods;
5560da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct method_list_t *optionalClassMethods;
5561da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const struct _prop_list_t * properties;
5562da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const uint32_t size;  // sizeof(struct _protocol_t)
5563da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   const uint32_t flags;  // = 0
5564dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson///   const char ** extendedMethodTypes;
5565da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// }
5566da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @endcode
5567da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///
5568da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5569da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
55706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCProtocolDecl *PD) {
557150651b951c216573175e2145f32df2c4658ba3f9John McCall  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
55726bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5573da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // Early exit if a defining object has already been generated.
5574da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  if (Entry && Entry->hasInitializer())
5575da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    return Entry;
5576da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
55771d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor  // Use the protocol definition, if there is one.
55781d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor  if (const ObjCProtocolDecl *Def = PD->getDefinition())
55791d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor    PD = Def;
55801d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor
5581da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // Construct method lists.
5582da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
5583da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
5584dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
55856bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCProtocolDecl::instmeth_iterator
558617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
5587da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    ObjCMethodDecl *MD = *i;
55883819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian    llvm::Constant *C = GetMethodDescriptionConstant(MD);
5589f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    if (!C)
5590f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor      return GetOrEmitProtocolRef(PD);
5591f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
5592da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5593da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian      OptInstanceMethods.push_back(C);
5594dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
5595da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    } else {
5596da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian      InstanceMethods.push_back(C);
5597dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      MethodTypesExt.push_back(GetMethodVarType(MD, true));
55986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
5599da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  }
56006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
56016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  for (ObjCProtocolDecl::classmeth_iterator
560217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
5603da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    ObjCMethodDecl *MD = *i;
56043819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian    llvm::Constant *C = GetMethodDescriptionConstant(MD);
5605f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    if (!C)
5606f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor      return GetOrEmitProtocolRef(PD);
5607f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
5608da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
5609da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian      OptClassMethods.push_back(C);
5610dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
5611da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    } else {
5612da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian      ClassMethods.push_back(C);
5613dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson      MethodTypesExt.push_back(GetMethodVarType(MD, true));
56146bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    }
5615da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  }
56166bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5617dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  MethodTypesExt.insert(MethodTypesExt.end(),
5618dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                        OptMethodTypesExt.begin(), OptMethodTypesExt.end());
5619dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson
5620dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  llvm::Constant *Values[11];
5621da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // isa is NULL
5622c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
5623da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  Values[1] = GetClassName(PD->getIdentifier());
56249c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
56259c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               PD->protocol_begin(),
56269c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               PD->protocol_end());
56276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
56283819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian  Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
56299c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             + PD->getName(),
5630da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             "__DATA, __objc_const",
5631da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             InstanceMethods);
56326bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
56339c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             + PD->getName(),
5634da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             "__DATA, __objc_const",
5635da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             ClassMethods);
56363819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian  Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
56379c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             + PD->getName(),
5638da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             "__DATA, __objc_const",
5639da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             OptInstanceMethods);
56406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
56419c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             + PD->getName(),
5642da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             "__DATA, __objc_const",
5643da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                             OptClassMethods);
56449c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
5645da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                               0, PD, ObjCTypes);
56466bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  uint32_t Size =
56479408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
56484a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
5649c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
5650dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson  Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
5651dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                                       + PD->getName(),
5652dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7Bob Wilson                                       MethodTypesExt, ObjCTypes);
565308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
5654da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                                                   Values);
56556bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5656da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  if (Entry) {
5657da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    // Already created, fix the linkage and update the initializer.
5658286acbdbe0c82e9a6bcad5fca3c4fa582f3f1a2cMike Stump    Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
5659da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    Entry->setInitializer(Init);
5660da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  } else {
56616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
56629c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
56639c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               false, llvm::GlobalValue::WeakAnyLinkage, Init,
56649c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
566509796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian    Entry->setAlignment(
56664b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar      CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
5667da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian    Entry->setSection("__DATA,__datacoal_nt,coalesced");
566850651b951c216573175e2145f32df2c4658ba3f9John McCall
566950651b951c216573175e2145f32df2c4658ba3f9John McCall    Protocols[PD->getIdentifier()] = Entry;
5670da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  }
56718448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian  Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
5672ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(Entry);
5673ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner
56748448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian  // Use this protocol meta-data to build protocol list table in section
56758448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian  // __DATA, __objc_protolist
56769c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  llvm::GlobalVariable *PTGV =
56779c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
56789c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             false, llvm::GlobalValue::WeakAnyLinkage, Entry,
56799c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
568009796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  PTGV->setAlignment(
56814b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
56820bf2199b79b1ca2dcbb0d0406fd90335c8575752Daniel Dunbar  PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
56838448c2cdab6e3d4b15725921735243c77b06623dFariborz Jahanian  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5684ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(PTGV);
5685da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  return Entry;
5686da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian}
5687da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
5688da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// EmitProtocolList - Generate protocol list meta-data:
5689da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @code
5690da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// struct _protocol_list_t {
5691da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   long protocol_count;   // Note, this is 32/64 bit
5692da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///   struct _protocol_t[protocol_count];
5693da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// }
5694da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian/// @endcode
5695da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian///
5696da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanianllvm::Constant *
56975f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
56989c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                      ObjCProtocolDecl::protocol_iterator begin,
56999c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                      ObjCProtocolDecl::protocol_iterator end) {
57003964e62786b0912fecc82d776daac236e05fc792Bill Wendling  llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs;
57016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5702da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // Just return null for empty protocol lists
57036bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  if (begin == end)
5704c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
57056bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5706948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  // FIXME: We shouldn't need to do this lookup here, should we?
5707f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<256> TmpName;
57089c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  Name.toVector(TmpName);
57099c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar  llvm::GlobalVariable *GV =
57109c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    CGM.getModule().getGlobalVariable(TmpName.str(), true);
5711da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  if (GV)
57129c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
57136bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5714948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar  for (; begin != end; ++begin)
5715948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar    ProtocolRefs.push_back(GetProtocolRef(*begin));  // Implemented???
5716948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar
5717da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  // This list is null terminated.
5718c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  ProtocolRefs.push_back(llvm::Constant::getNullValue(
57196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                           ObjCTypes.ProtocolnfABIPtrTy));
57206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5721c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Values[2];
5722a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  Values[0] =
57234a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
57246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Values[1] =
57253964e62786b0912fecc82d776daac236e05fc792Bill Wendling    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
57263964e62786b0912fecc82d776daac236e05fc792Bill Wendling                                                  ProtocolRefs.size()),
57273964e62786b0912fecc82d776daac236e05fc792Bill Wendling                             ProtocolRefs);
57286bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5729c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
57301c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson  GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5731da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian                                llvm::GlobalValue::InternalLinkage,
5732c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner                                Init, Name);
5733da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian  GV->setSection("__DATA, __objc_const");
573409796d6a23c683413470efd19dd5ad331d91af7dFariborz Jahanian  GV->setAlignment(
57354b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(Init->getType()));
5736ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(GV);
57376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  return llvm::ConstantExpr::getBitCast(GV,
5738948e2589505aa1b334b2cff81b28a741db49f701Daniel Dunbar                                        ObjCTypes.ProtocolListnfABIPtrTy);
5739da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian}
5740da3200986d9ec2ed0920e4d84ac210c889136946Fariborz Jahanian
57413819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// GetMethodDescriptionConstant - This routine build following meta-data:
57423819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// struct _objc_method {
57433819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian///   SEL _cmd;
57443819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian///   char *method_type;
57453819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian///   char *_imp;
57463819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian/// }
57473819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian
57483819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanianllvm::Constant *
57493819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz JahanianCGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
57501d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Desc[3];
5751a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  Desc[0] =
57526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
57536bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                   ObjCTypes.SelectorPtrTy);
57543819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian  Desc[1] = GetMethodVarType(MD);
5755f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor  if (!Desc[1])
5756f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor    return 0;
5757f968d8374791c37bc464efd9168c2d33dd73605fDouglas Gregor
57588cfd397d5f1dfb0a0242c428f7d9cb24dceb5760Fariborz Jahanian  // Protocol methods have no implementation. So, this entry is always NULL.
5759c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
576008e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
57613819a0bf47f43fc6e496c1d0257a1658424ab6a5Fariborz Jahanian}
576245012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
576345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
576445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// This code gen. amounts to generating code for:
576545012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// @code
576645012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
576745012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian/// @encode
57686bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar///
5769598d3f61b6ca854e9d3c2f3359e24468502a61aaFariborz JahanianLValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
5770506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               CodeGen::CodeGenFunction &CGF,
5771506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               QualType ObjectTy,
5772506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               llvm::Value *BaseValue,
5773506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               const ObjCIvarDecl *Ivar,
5774506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall                                               unsigned CVRQualifiers) {
5775506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
5776cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian  llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
5777cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian  if (llvm::LoadInst *LI = dyn_cast<llvm::LoadInst>(Offset))
5778cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian    LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
5779cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian                   llvm::MDNode::get(VMContext,
5780cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian                   ArrayRef<llvm::Value*>()));
57819777687562c338601c2f17906e65e1c1a0aad96fDaniel Dunbar  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5782cd285d061546b701431b4214e068e024245a96f5Fariborz Jahanian                                  Offset);
578345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian}
578445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
5785f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
57866bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CodeGen::CodeGenFunction &CGF,
57876bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCInterfaceDecl *Interface,
57886bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  const ObjCIvarDecl *Ivar) {
57892da84ff228a231adbd3f6f236b857f752d02959aDaniel Dunbar  return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
5790f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian}
5791f63aa3fd429cdb9145d78f0b656bc78754efedb9Fariborz Jahanian
5792b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCallstatic void appendSelectorForMessageRefTable(std::string &buffer,
5793b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                             Selector selector) {
5794b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  if (selector.isUnarySelector()) {
5795b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    buffer += selector.getNameForSlot(0);
5796b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    return;
5797b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  }
57986bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5799b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
5800b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    buffer += selector.getNameForSlot(i);
5801b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    buffer += '_';
5802b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  }
5803b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall}
5804b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5805944c84313da15477eb18d90babb0890d10d98082John McCall/// Emit a "v-table" message send.  We emit a weak hidden-visibility
5806944c84313da15477eb18d90babb0890d10d98082John McCall/// struct, initially containing the selector pointer and a pointer to
5807944c84313da15477eb18d90babb0890d10d98082John McCall/// a "fixup" variant of the appropriate objc_msgSend.  To call, we
5808944c84313da15477eb18d90babb0890d10d98082John McCall/// load and call the function pointer, passing the address of the
5809944c84313da15477eb18d90babb0890d10d98082John McCall/// struct as the second parameter.  The runtime determines whether
5810944c84313da15477eb18d90babb0890d10d98082John McCall/// the selector is currently emitted using vtable dispatch; if so, it
5811944c84313da15477eb18d90babb0890d10d98082John McCall/// substitutes a stub function which simply tail-calls through the
5812944c84313da15477eb18d90babb0890d10d98082John McCall/// appropriate vtable slot, and if not, it substitues a stub function
5813944c84313da15477eb18d90babb0890d10d98082John McCall/// which tail-calls objc_msgSend.  Both stubs adjust the selector
5814944c84313da15477eb18d90babb0890d10d98082John McCall/// argument to correctly point to the selector.
5815944c84313da15477eb18d90babb0890d10d98082John McCallRValue
5816944c84313da15477eb18d90babb0890d10d98082John McCallCGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
5817944c84313da15477eb18d90babb0890d10d98082John McCall                                              ReturnValueSlot returnSlot,
5818944c84313da15477eb18d90babb0890d10d98082John McCall                                              QualType resultType,
5819944c84313da15477eb18d90babb0890d10d98082John McCall                                              Selector selector,
5820944c84313da15477eb18d90babb0890d10d98082John McCall                                              llvm::Value *arg0,
5821944c84313da15477eb18d90babb0890d10d98082John McCall                                              QualType arg0Type,
5822944c84313da15477eb18d90babb0890d10d98082John McCall                                              bool isSuper,
5823944c84313da15477eb18d90babb0890d10d98082John McCall                                              const CallArgList &formalArgs,
5824944c84313da15477eb18d90babb0890d10d98082John McCall                                              const ObjCMethodDecl *method) {
5825b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  // Compute the actual arguments.
5826b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  CallArgList args;
5827b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5828944c84313da15477eb18d90babb0890d10d98082John McCall  // First argument: the receiver / super-call structure.
5829b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  if (!isSuper)
5830944c84313da15477eb18d90babb0890d10d98082John McCall    arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
5831944c84313da15477eb18d90babb0890d10d98082John McCall  args.add(RValue::get(arg0), arg0Type);
5832b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5833944c84313da15477eb18d90babb0890d10d98082John McCall  // Second argument: a pointer to the message ref structure.  Leave
5834944c84313da15477eb18d90babb0890d10d98082John McCall  // the actual argument value blank for now.
5835b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy);
5836b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5837b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  args.insert(args.end(), formalArgs.begin(), formalArgs.end());
5838b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5839de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
5840b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5841cba681af356e24ec4335bcf2b6bb6515072ace99John McCall  NullReturnState nullReturn;
5842cba681af356e24ec4335bcf2b6bb6515072ace99John McCall
5843944c84313da15477eb18d90babb0890d10d98082John McCall  // Find the function to call and the mangled name for the message
5844944c84313da15477eb18d90babb0890d10d98082John McCall  // ref structure.  Using a different mangled name wouldn't actually
5845944c84313da15477eb18d90babb0890d10d98082John McCall  // be a problem; it would just be a waste.
5846944c84313da15477eb18d90babb0890d10d98082John McCall  //
5847944c84313da15477eb18d90babb0890d10d98082John McCall  // The runtime currently never uses vtable dispatch for anything
5848944c84313da15477eb18d90babb0890d10d98082John McCall  // except normal, non-super message-sends.
5849944c84313da15477eb18d90babb0890d10d98082John McCall  // FIXME: don't use this for that.
5850b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  llvm::Constant *fn = 0;
5851b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  std::string messageRefName("\01l_");
5852de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
5853b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    if (isSuper) {
5854b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
5855b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      messageRefName += "objc_msgSendSuper2_stret_fixup";
58569b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner    } else {
5857cba681af356e24ec4335bcf2b6bb6515072ace99John McCall      nullReturn.init(CGF, arg0);
5858b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      fn = ObjCTypes.getMessageSendStretFixupFn();
5859b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      messageRefName += "objc_msgSend_stret_fixup";
58609b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner    }
5861b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
5862b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    fn = ObjCTypes.getMessageSendFpretFixupFn();
5863b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRefName += "objc_msgSend_fpret_fixup";
5864b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
5865b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    if (isSuper) {
5866b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      fn = ObjCTypes.getMessageSendSuper2FixupFn();
5867b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      messageRefName += "objc_msgSendSuper2_fixup";
58689b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner    } else {
5869b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      fn = ObjCTypes.getMessageSendFixupFn();
5870b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall      messageRefName += "objc_msgSend_fixup";
58719b7d6701dabc24387cc152e4d13bf9aec6aa461aChris Lattner    }
587283a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  }
5873b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
5874b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  messageRefName += '_';
5875b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5876b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  // Append the selector name, except use underscores anywhere we
5877b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  // would have used colons.
5878b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  appendSelectorForMessageRefTable(messageRefName, selector);
5879b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5880b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  llvm::GlobalVariable *messageRef
5881b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    = CGM.getModule().getGlobalVariable(messageRefName);
5882b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  if (!messageRef) {
5883944c84313da15477eb18d90babb0890d10d98082John McCall    // Build the message ref structure.
5884b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
5885c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner    llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
5886b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRef = new llvm::GlobalVariable(CGM.getModule(),
5887b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          init->getType(),
5888b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          /*constant*/ false,
5889b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          llvm::GlobalValue::WeakAnyLinkage,
5890b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          init,
5891b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall                                          messageRefName);
5892b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
5893b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRef->setAlignment(16);
5894b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
589583a8a7534c6766c2df2745eca35effa3e6f9d092Fariborz Jahanian  }
58963c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian
58973c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian  bool requiresnullCheck = false;
58984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().ObjCAutoRefCount && method)
58993c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian    for (ObjCMethodDecl::param_const_iterator i = method->param_begin(),
59003c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian         e = method->param_end(); i != e; ++i) {
59013c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian      const ParmVarDecl *ParamDecl = (*i);
59023c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian      if (ParamDecl->hasAttr<NSConsumedAttr>()) {
59033c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian        if (!nullReturn.NullBB)
59043c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian          nullReturn.init(CGF, arg0);
59053c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian        requiresnullCheck = true;
59063c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian        break;
59073c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian      }
59083c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian    }
59093c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian
5910b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  llvm::Value *mref =
5911b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall    CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
59126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
5913944c84313da15477eb18d90babb0890d10d98082John McCall  // Update the message ref argument.
5914b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  args[1].RV = RValue::get(mref);
5915b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5916b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  // Load the function to call from the message ref table.
5917b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
5918b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall  callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
5919b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5920de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
5921b1e8144a9620a16281a8b56a8b49d4cf37db3242John McCall
5922de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
59233c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian  return nullReturn.complete(CGF, result, resultType, formalArgs,
59243c52d3633707453fbc08898935c45bed16953cfbFariborz Jahanian                             requiresnullCheck ? method : 0);
59254655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian}
59264655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian
59274655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian/// Generate code for a message send expression in the nonfragile abi.
5928d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCodeGen::RValue
5929d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel DunbarCGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
5930ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                            ReturnValueSlot Return,
5931d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            QualType ResultType,
5932d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            Selector Sel,
5933d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            llvm::Value *Receiver,
5934d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            const CallArgList &CallArgs,
5935c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                            const ObjCInterfaceDecl *Class,
5936d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                            const ObjCMethodDecl *Method) {
5937944c84313da15477eb18d90babb0890d10d98082John McCall  return isVTableDispatchedSelector(Sel)
5938944c84313da15477eb18d90babb0890d10d98082John McCall    ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
59396bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                            Receiver, CGF.getContext().getObjCIdType(),
5940944c84313da15477eb18d90babb0890d10d98082John McCall                            false, CallArgs, Method)
5941944c84313da15477eb18d90babb0890d10d98082John McCall    : EmitMessageSend(CGF, Return, ResultType,
5942944c84313da15477eb18d90babb0890d10d98082John McCall                      EmitSelector(CGF.Builder, Sel),
59436bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                      Receiver, CGF.getContext().getObjCIdType(),
5944944c84313da15477eb18d90babb0890d10d98082John McCall                      false, CallArgs, Method, ObjCTypes);
59454655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian}
59464655112d1c64a098c5f7d665175063f4664a7cf6Fariborz Jahanian
59475a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbarllvm::GlobalVariable *
59480f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz JahanianCGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
59495a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
59505a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar
5951dfff23060b4a3add79a3bb68ccec606ade4f39bfDaniel Dunbar  if (!GV) {
59526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
59531c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                  false, llvm::GlobalValue::ExternalLinkage,
59541c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                  0, Name);
59555a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  }
59565a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar
59575a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar  return GV;
59585a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar}
59595a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar
5960f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder,
5961f85e193739c953358c865005855253af4f68a497John McCall                                                        IdentifierInfo *II) {
5962f85e193739c953358c865005855253af4f68a497John McCall  llvm::GlobalVariable *&Entry = ClassReferences[II];
5963f85e193739c953358c865005855253af4f68a497John McCall
59640e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian  if (!Entry) {
5965f85e193739c953358c865005855253af4f68a497John McCall    std::string ClassName(getClassSymbolPrefix() + II->getName().str());
59665a7379a0d7a89d646322cfa61d80c60ef23d4569Daniel Dunbar    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
59676bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
5968f85e193739c953358c865005855253af4f68a497John McCall    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
5969f85e193739c953358c865005855253af4f68a497John McCall                             false, llvm::GlobalValue::InternalLinkage,
5970f85e193739c953358c865005855253af4f68a497John McCall                             ClassGV,
5971f85e193739c953358c865005855253af4f68a497John McCall                             "\01L_OBJC_CLASSLIST_REFERENCES_$_");
59720e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian    Entry->setAlignment(
5973f85e193739c953358c865005855253af4f68a497John McCall                        CGM.getTargetData().getABITypeAlignment(
5974f85e193739c953358c865005855253af4f68a497John McCall                                                                ObjCTypes.ClassnfABIPtrTy));
59751139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
5976ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(Entry);
59771139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  }
5978f85e193739c953358c865005855253af4f68a497John McCall
5979578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
59801139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar}
59810e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian
5982f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
5983f85e193739c953358c865005855253af4f68a497John McCall                                                  const ObjCInterfaceDecl *ID) {
5984f85e193739c953358c865005855253af4f68a497John McCall  return EmitClassRefFromId(Builder, ID->getIdentifier());
5985f85e193739c953358c865005855253af4f68a497John McCall}
5986f85e193739c953358c865005855253af4f68a497John McCall
5987f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
5988f85e193739c953358c865005855253af4f68a497John McCall                                                    CGBuilderTy &Builder) {
5989f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
5990f85e193739c953358c865005855253af4f68a497John McCall  return EmitClassRefFromId(Builder, II);
5991f85e193739c953358c865005855253af4f68a497John McCall}
5992f85e193739c953358c865005855253af4f68a497John McCall
59931139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbarllvm::Value *
59946bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
59951139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar                                          const ObjCInterfaceDecl *ID) {
59961139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
59976bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
59981139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar  if (!Entry) {
59991139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
60001139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
60016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
60026bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
60031c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                               false, llvm::GlobalValue::InternalLinkage,
60046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               ClassGV,
60051c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                               "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
60061139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    Entry->setAlignment(
60074b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar      CGM.getTargetData().getABITypeAlignment(
60086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar        ObjCTypes.ClassnfABIPtrTy));
60091139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6010ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(Entry);
60110e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian  }
60126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6013578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
60140e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian}
60150e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian
60167a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// EmitMetaClassRef - Return a Value * of the address of _class_t
60177a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// meta-data
60187a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian///
60196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
60206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                      const ObjCInterfaceDecl *ID) {
60217a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
60227a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  if (Entry)
6023578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer    return Builder.CreateLoad(Entry);
60246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
60256ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
60260f9029406b4dcdcf740cf99edc8652c43c9350cdFariborz Jahanian  llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
60276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  Entry =
60281c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
60297a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian                             llvm::GlobalValue::InternalLinkage,
60306bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                             MetaClassGV,
60311c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                             "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
60327a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  Entry->setAlignment(
60334b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar    CGM.getTargetData().getABITypeAlignment(
60346bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      ObjCTypes.ClassnfABIPtrTy));
60356bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
603633af70f0f003d9765b92621f4fdd801e2b6c0ae7Daniel Dunbar  Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6037ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner  CGM.AddUsedGlobal(Entry);
60386bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6039578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  return Builder.CreateLoad(Entry);
60407a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian}
60417a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian
60420e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian/// GetClass - Return a reference to the class for the given interface
60430e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian/// decl.
60440e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanianllvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
60450e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian                                              const ObjCInterfaceDecl *ID) {
60460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (ID->isWeakImported()) {
6047269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6048269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
6049269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
6050269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian  }
6051269f8bc10a33e29e2951df7720cad0abb45c74cbFariborz Jahanian
60520e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian  return EmitClassRef(Builder, ID);
60530e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian}
60540e81f4b58d4e9767efbca7f3e856dcbc2192b1b5Fariborz Jahanian
60557a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// Generates a message send where the super is the receiver.  This is
60567a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// a message send to self with special delivery semantics indicating
60577a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian/// which class's method should be called.
60587a06aae468c94a21c267106ec16bd2c79dab2857Fariborz JahanianCodeGen::RValue
60597a06aae468c94a21c267106ec16bd2c79dab2857Fariborz JahanianCGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
6060ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                                 ReturnValueSlot Return,
60616bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 QualType ResultType,
60626bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 Selector Sel,
60636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 const ObjCInterfaceDecl *Class,
60646bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 bool isCategoryImpl,
60656bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 llvm::Value *Receiver,
60666bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                                 bool IsClassMessage,
6067d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                                 const CodeGen::CallArgList &CallArgs,
6068d6c93d703541c992e06eb9a59a2d826a30da65b2Daniel Dunbar                                                 const ObjCMethodDecl *Method) {
60697a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  // ...
60707a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  // Create and init a super structure; this is a (receiver, class)
60717a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  // pair we will pass to objc_msgSendSuper.
60727a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  llvm::Value *ObjCSuper =
6073604da292483bc94a6a3e4700cd426d4fa7f1a4a8John McCall    CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
60746bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
60757a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  llvm::Value *ReceiverAsObject =
60767a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
60777a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  CGF.Builder.CreateStore(ReceiverAsObject,
60787a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
60796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
60807a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  // If this is a class message the metaclass is passed as the target.
60817ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian  llvm::Value *Target;
60827ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian  if (IsClassMessage) {
60837ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian    if (isCategoryImpl) {
60847ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // Message sent to "super' in a class method defined in
60857ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      // a category implementation.
60861139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar      Target = EmitClassRef(CGF.Builder, Class);
60877ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = CGF.Builder.CreateStructGEP(Target, 0);
60887ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = CGF.Builder.CreateLoad(Target);
6089b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else
60907ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian      Target = EmitMetaClassRef(CGF.Builder, Class);
6091b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else
60921139452ae326e96a11f9740e5fda7f995fd3a6beDaniel Dunbar    Target = EmitSuperClassRef(CGF.Builder, Class);
60936bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6094f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
6095f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ObjCTypes types.
60962acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *ClassTy =
60977a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
60987a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
60997a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian  CGF.Builder.CreateStore(Target,
61007a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian                          CGF.Builder.CreateStructGEP(ObjCSuper, 1));
61016bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6102944c84313da15477eb18d90babb0890d10d98082John McCall  return (isVTableDispatchedSelector(Sel))
6103944c84313da15477eb18d90babb0890d10d98082John McCall    ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
61046bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                            ObjCSuper, ObjCTypes.SuperPtrCTy,
6105944c84313da15477eb18d90babb0890d10d98082John McCall                            true, CallArgs, Method)
6106944c84313da15477eb18d90babb0890d10d98082John McCall    : EmitMessageSend(CGF, Return, ResultType,
6107944c84313da15477eb18d90babb0890d10d98082John McCall                      EmitSelector(CGF.Builder, Sel),
61086bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                      ObjCSuper, ObjCTypes.SuperPtrCTy,
6109944c84313da15477eb18d90babb0890d10d98082John McCall                      true, CallArgs, Method, ObjCTypes);
61107a06aae468c94a21c267106ec16bd2c79dab2857Fariborz Jahanian}
611126cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian
61126bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarllvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
611303b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian                                                  Selector Sel, bool lval) {
611426cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
61156bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
611626cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  if (!Entry) {
61176bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    llvm::Constant *Casted =
61186bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
61196bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                     ObjCTypes.SelectorPtrTy);
61206bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    Entry =
61216bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
61226bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               llvm::GlobalValue::InternalLinkage,
61236bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                               Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
6124d0f8a8d17082266c1e774ca07d58bcd4811b2681Fariborz Jahanian    Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6125ad64e024bd18cf25dcfa44e049004371838decd8Chris Lattner    CGM.AddUsedGlobal(Entry);
612626cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian  }
61276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
612803b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian  if (lval)
612903b2960c14aede6ac82bdef32247094ebb72fa69Fariborz Jahanian    return Entry;
6130b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper  llvm::LoadInst* LI = Builder.CreateLoad(Entry);
6131b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper
6132b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper  LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6133b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper                  llvm::MDNode::get(VMContext,
6134b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper                                    ArrayRef<llvm::Value*>()));
6135b6d7114bcfa29b262f9f043a76da7dba39d65136Pete Cooper  return LI;
613626cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian}
61376948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
61386c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
61396948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
61406948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
61411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                llvm::Value *src,
61426c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                                llvm::Value *dst,
61436c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                                                llvm::Value *ivarOffset) {
61442acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
61450a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
61469408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
61470a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
61480a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
61490a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
61503b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
61513b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
61526948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
61536948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
61546c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian  CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
61556c7a1f364796ce1acb988714e9e42076d1ce332eFariborz Jahanian                          src, dst, ivarOffset);
61566948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return;
61576948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
61586948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian
61596948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
61606948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_strongCast (id src, id *dst)
61616948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
61626948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
61636bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CodeGen::CodeGenFunction &CGF,
61641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *src, llvm::Value *dst) {
61652acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
61660a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
61679408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
61680a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
61690a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
61706bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
61713b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
61723b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
61736948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
61746948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6175bbccd611bb3ccf36703992592ef5209327f259b9Chris Lattner  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
61766948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                          src, dst, "weakassign");
61776948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return;
61786948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
61796948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian
6180082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
61816bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CodeGen::CodeGenFunction &CGF,
61826bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *DestPtr,
61836bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::Value *SrcPtr,
618455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian  llvm::Value *Size) {
6185082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
6186082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
6187082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
618855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                          DestPtr, SrcPtr, Size);
6189082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian  return;
6190082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian}
6191082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian
61926948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCWeakRead - Code gen for loading value of a __weak
61936948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// object: objc_read_weak (id *src)
61946948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
61956948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianllvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
61966bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  CodeGen::CodeGenFunction &CGF,
61971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *AddrWeakObj) {
61982acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type* DestTy =
61996bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
62006bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
620172db6c3db7b3f992f06c880f9039f03b4cdeb517Chris Lattner  llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
62026948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                                                  AddrWeakObj, "weakread");
62038339b35ca05dd040a9a0ecfc92e7b49d80c5a96bEli Friedman  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
62046948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return read_weak;
62056948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
62066948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian
62076948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
62086948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_weak (id src, id *dst)
62096948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
62106948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
62111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                llvm::Value *src, llvm::Value *dst) {
62122acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
62130a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
62149408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
62150a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
62160a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
62170a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
62183b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
62193b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
62206948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
62216948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
622296508e1fea58347b6401ca9a4728c0b268174603Chris Lattner  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
62236948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian                          src, dst, "weakassign");
62246948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return;
62256948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
62266948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian
62276948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
62286948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian/// objc_assign_global (id src, id *dst)
62296948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian///
62306948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanianvoid CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
6231021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                          llvm::Value *src, llvm::Value *dst,
6232021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                                          bool threadlocal) {
62332acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type * SrcTy = src->getType();
62340a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian  if (!isa<llvm::PointerType>(SrcTy)) {
62359408c45009b417e758749b3d95cdfb87dcb68ea9Duncan Sands    unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
62360a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    assert(Size <= 8 && "does not support size > 8");
62370a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
62380a855d0bad7a32d5d0f8a03ac9ce7660c8c98b26Fariborz Jahanian           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
62393b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
62403b8a652d60ddc4419c1fab5c7b5347560283cdc1Fariborz Jahanian  }
62416948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
62426948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6243021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  if (!threadlocal)
6244021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
6245021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                            src, dst, "globalassign");
6246021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian  else
6247021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
6248021a7a63984f0f912dc9e9dae2a1b3e1509a40ceFariborz Jahanian                            src, dst, "threadlocalassign");
62496948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian  return;
62506948aea3664832416031eaac6fb55af3efb99b48Fariborz Jahanian}
625126cc89ffb1cc57313371b4175ceac56a2f975641Fariborz Jahanian
62526bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbarvoid
6253f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
6254f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                             const ObjCAtSynchronizedStmt &S) {
625505dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall  EmitAtSynchronizedStmt(CGF, S,
625605dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
625705dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
6258f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
62594ff36847f44b35c2677330c39e87dff1d745944aDaniel Dunbar
62605a180397870944548aaadeaebf58e415885b9489John McCallllvm::Constant *
6261cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz JahanianCGObjCNonFragileABIMac::GetEHType(QualType T) {
62625a180397870944548aaadeaebf58e415885b9489John McCall  // There's a particular fixed type info for 'id'.
62635a180397870944548aaadeaebf58e415885b9489John McCall  if (T->isObjCIdType() ||
62645a180397870944548aaadeaebf58e415885b9489John McCall      T->isObjCQualifiedIdType()) {
62655a180397870944548aaadeaebf58e415885b9489John McCall    llvm::Constant *IDEHType =
62665a180397870944548aaadeaebf58e415885b9489John McCall      CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
62675a180397870944548aaadeaebf58e415885b9489John McCall    if (!IDEHType)
62685a180397870944548aaadeaebf58e415885b9489John McCall      IDEHType =
62695a180397870944548aaadeaebf58e415885b9489John McCall        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
62705a180397870944548aaadeaebf58e415885b9489John McCall                                 false,
62715a180397870944548aaadeaebf58e415885b9489John McCall                                 llvm::GlobalValue::ExternalLinkage,
62725a180397870944548aaadeaebf58e415885b9489John McCall                                 0, "OBJC_EHTYPE_id");
62735a180397870944548aaadeaebf58e415885b9489John McCall    return IDEHType;
62745a180397870944548aaadeaebf58e415885b9489John McCall  }
62755a180397870944548aaadeaebf58e415885b9489John McCall
62765a180397870944548aaadeaebf58e415885b9489John McCall  // All other types should be Objective-C interface pointer types.
62775a180397870944548aaadeaebf58e415885b9489John McCall  const ObjCObjectPointerType *PT =
62785a180397870944548aaadeaebf58e415885b9489John McCall    T->getAs<ObjCObjectPointerType>();
62795a180397870944548aaadeaebf58e415885b9489John McCall  assert(PT && "Invalid @catch type.");
62805a180397870944548aaadeaebf58e415885b9489John McCall  const ObjCInterfaceType *IT = PT->getInterfaceType();
62815a180397870944548aaadeaebf58e415885b9489John McCall  assert(IT && "Invalid @catch type.");
62825a180397870944548aaadeaebf58e415885b9489John McCall  return GetInterfaceEHType(IT->getDecl(), false);
62835a180397870944548aaadeaebf58e415885b9489John McCall}
62845a180397870944548aaadeaebf58e415885b9489John McCall
6285f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
6286f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                         const ObjCAtTryStmt &S) {
628705dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall  EmitTryCatchStmt(CGF, S,
628805dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
628905dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
629005dc91bc772f6dc46f90d927048bbef05ba03392David Chisnall      cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
62918ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar}
62928ecbaf25c1373be6fb5a9d332b08b6be16d9fd4eDaniel Dunbar
6293f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson/// EmitThrowStmt - Generate code for a throw statement.
6294f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlssonvoid CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6295f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson                                           const ObjCAtThrowStmt &S) {
6296f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson  if (const Expr *ThrowExpr = S.getThrowExpr()) {
62972b014d6c0c6b8ac94b416ac37dfc7931f20777a7John McCall    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
6298578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer    Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
62994c7d9f1507d0f102bd4133bba63348636facd469Jay Foad    CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
63007ec404c40e42ce274d956a289ffa91e8f4befc43John McCall      .setDoesNotReturn();
6301f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else {
63024c7d9f1507d0f102bd4133bba63348636facd469Jay Foad    CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
63037ec404c40e42ce274d956a289ffa91e8f4befc43John McCall      .setDoesNotReturn();
6304f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
63054ff36847f44b35c2677330c39e87dff1d745944aDaniel Dunbar
63067ec404c40e42ce274d956a289ffa91e8f4befc43John McCall  CGF.Builder.CreateUnreachable();
6307f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson  CGF.Builder.ClearInsertionPoint();
6308f57c5b2ef767223f349be6adba9bf1b4f9d19283Anders Carlsson}
6309e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
63105a180397870944548aaadeaebf58e415885b9489John McCallllvm::Constant *
63116bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel DunbarCGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
63128158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar                                           bool ForDefinition) {
6313e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
63147e075cb62c06e0b0023fd12875c95da9c5ddefb7Daniel Dunbar
63158158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // If we don't need a definition, return the entry if found or check
63168158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // if we use an external reference.
63178158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (!ForDefinition) {
63188158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    if (Entry)
63198158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar      return Entry;
63208158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
63218158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    // If this type (or a super class) has the __objc_exception__
63228158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    // attribute, emit an external reference.
632368584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor    if (hasObjCExceptionAttribute(CGM.getContext(), ID))
63246bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar      return Entry =
63251c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
63268158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar                                 llvm::GlobalValue::ExternalLinkage,
63276bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                 0,
63289c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                 ("OBJC_EHTYPE_$_" +
632901eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar                                  ID->getIdentifier()->getName()));
63308158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  }
63316bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
63328158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // Otherwise we need to either make a new entry or fill in the
63338158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  // initializer.
63348158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
63356ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar  std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6336e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  std::string VTableName = "objc_ehtype_vtable";
63376bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar  llvm::GlobalVariable *VTableGV =
6338e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar    CGM.getModule().getGlobalVariable(VTableName);
6339e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  if (!VTableGV)
63406bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar    VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
63416bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                        false,
6342e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar                                        llvm::GlobalValue::ExternalLinkage,
63431c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                                        0, VTableName);
6344e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
63458b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner  llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
6346e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
63471d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  llvm::Constant *Values[] = {
63481d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
63491d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetClassName(ID->getIdentifier()),
63501d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer    GetClassGlobal(ClassName)
63511d236ab930816f5da27bade92904914c44b73b4cBenjamin Kramer  };
6352a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  llvm::Constant *Init =
635308e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson    llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
6354e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
63558158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (Entry) {
63568158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    Entry->setInitializer(Init);
63578158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  } else {
63581c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
63598158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar                                     llvm::GlobalValue::WeakAnyLinkage,
63606bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar                                     Init,
63619c29bf597ee1d085ecce1e1fcbd3c6beed18127aDaniel Dunbar                                     ("OBJC_EHTYPE_$_" +
636201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar                                      ID->getIdentifier()->getName()));
63638158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  }
63648158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
63654e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGM.getLangOpts().getVisibilityMode() == HiddenVisibility)
63666ab187a49a42de6d351248d8a6e0206e39743a0cDaniel Dunbar    Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
63674b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar  Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
63684b429ae34d80dd21661c91009c559746e553bc1eDaniel Dunbar      ObjCTypes.EHTypeTy));
63698158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar
63708158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  if (ForDefinition) {
63718158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    Entry->setSection("__DATA,__objc_const");
63728158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
63738158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  } else {
63748158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar    Entry->setSection("__DATA,__datacoal_nt,coalesced");
63758158a2f78c47bf332dbd8b0b680de8a9b8d0511eDaniel Dunbar  }
6376e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar
6377e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar  return Entry;
6378e588b9924fb36975fada46d48e74a948653e7526Daniel Dunbar}
63796bff2513b041eb84d4902b106d1b9023e5bb7c8eDaniel Dunbar
6380bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar/* *** */
6381bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar
63826efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel DunbarCodeGen::CGObjCRuntime *
63836efc0c559b5f9861d4bbd4aef5b4897c02b2ae74Daniel DunbarCodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
6384260611a32535c851237926bfcf78869b13c07d5bJohn McCall  switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
6385260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::FragileMacOSX:
6386c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar  return new CGObjCMac(CGM);
6387260611a32535c851237926bfcf78869b13c07d5bJohn McCall
6388260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::MacOSX:
6389260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::iOS:
6390260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return new CGObjCNonFragileABIMac(CGM);
6391260611a32535c851237926bfcf78869b13c07d5bJohn McCall
639211d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  case ObjCRuntime::GNUstep:
639311d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  case ObjCRuntime::GCC:
6394f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall  case ObjCRuntime::ObjFW:
6395260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm_unreachable("these runtimes are not Mac runtimes");
6396260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
6397260611a32535c851237926bfcf78869b13c07d5bJohn McCall  llvm_unreachable("bad runtime");
6398c17a4d3b16a2624a76de5d7508805534545bd3bfDaniel Dunbar}
6399