CGObjCGNU.cpp revision 207619
1193326Sed//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This provides Objective-C code generation targetting the GNU runtime.  The
11193326Sed// class in this file generates structures used by the GNU Objective-C runtime
12193326Sed// library.  These structures are defined in objc/objc.h and objc/objc-api.h in
13193326Sed// the GNU runtime distribution.
14193326Sed//
15193326Sed//===----------------------------------------------------------------------===//
16193326Sed
17193326Sed#include "CGObjCRuntime.h"
18193326Sed#include "CodeGenModule.h"
19193326Sed#include "CodeGenFunction.h"
20193326Sed
21193326Sed#include "clang/AST/ASTContext.h"
22193326Sed#include "clang/AST/Decl.h"
23193326Sed#include "clang/AST/DeclObjC.h"
24193326Sed#include "clang/AST/RecordLayout.h"
25193326Sed#include "clang/AST/StmtObjC.h"
26193326Sed
27193326Sed#include "llvm/Intrinsics.h"
28193326Sed#include "llvm/Module.h"
29207619Srdivacky#include "llvm/LLVMContext.h"
30193326Sed#include "llvm/ADT/SmallVector.h"
31193326Sed#include "llvm/ADT/StringMap.h"
32193326Sed#include "llvm/Support/Compiler.h"
33193326Sed#include "llvm/Target/TargetData.h"
34193326Sed
35193326Sed#include <map>
36193326Sed
37193326Sed
38193326Sedusing namespace clang;
39193326Sedusing namespace CodeGen;
40193326Sedusing llvm::dyn_cast;
41193326Sed
42193326Sed// The version of the runtime that this class targets.  Must match the version
43193326Sed// in the runtime.
44193326Sedstatic const int RuntimeVersion = 8;
45193326Sedstatic const int NonFragileRuntimeVersion = 9;
46193326Sedstatic const int ProtocolVersion = 2;
47198092Srdivackystatic const int NonFragileProtocolVersion = 3;
48193326Sed
49193326Sednamespace {
50193326Sedclass CGObjCGNU : public CodeGen::CGObjCRuntime {
51193326Sedprivate:
52193326Sed  CodeGen::CodeGenModule &CGM;
53193326Sed  llvm::Module &TheModule;
54193326Sed  const llvm::PointerType *SelectorTy;
55198092Srdivacky  const llvm::IntegerType *Int8Ty;
56193326Sed  const llvm::PointerType *PtrToInt8Ty;
57193326Sed  const llvm::FunctionType *IMPTy;
58193326Sed  const llvm::PointerType *IdTy;
59203955Srdivacky  const llvm::PointerType *PtrToIdTy;
60204643Srdivacky  CanQualType ASTIdTy;
61193326Sed  const llvm::IntegerType *IntTy;
62193326Sed  const llvm::PointerType *PtrTy;
63193326Sed  const llvm::IntegerType *LongTy;
64193326Sed  const llvm::PointerType *PtrToIntTy;
65193326Sed  llvm::GlobalAlias *ClassPtrAlias;
66193326Sed  llvm::GlobalAlias *MetaClassPtrAlias;
67193326Sed  std::vector<llvm::Constant*> Classes;
68193326Sed  std::vector<llvm::Constant*> Categories;
69193326Sed  std::vector<llvm::Constant*> ConstantStrings;
70203955Srdivacky  llvm::StringMap<llvm::Constant*> ObjCStrings;
71193326Sed  llvm::Function *LoadFunction;
72193326Sed  llvm::StringMap<llvm::Constant*> ExistingProtocols;
73193326Sed  typedef std::pair<std::string, std::string> TypedSelector;
74193326Sed  std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors;
75193326Sed  llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors;
76203955Srdivacky  // Selectors that we don't emit in GC mode
77203955Srdivacky  Selector RetainSel, ReleaseSel, AutoreleaseSel;
78203955Srdivacky  // Functions used for GC.
79203955Srdivacky  llvm::Constant *IvarAssignFn, *StrongCastAssignFn, *MemMoveFn, *WeakReadFn,
80203955Srdivacky    *WeakAssignFn, *GlobalAssignFn;
81193326Sed  // Some zeros used for GEPs in lots of places.
82193326Sed  llvm::Constant *Zeros[2];
83193326Sed  llvm::Constant *NULLPtr;
84198092Srdivacky  llvm::LLVMContext &VMContext;
85207619Srdivacky  /// Metadata kind used to tie method lookups to message sends.
86207619Srdivacky  unsigned msgSendMDKind;
87193326Sedprivate:
88193326Sed  llvm::Constant *GenerateIvarList(
89193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
90193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
91193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets);
92193326Sed  llvm::Constant *GenerateMethodList(const std::string &ClassName,
93193326Sed      const std::string &CategoryName,
94198092Srdivacky      const llvm::SmallVectorImpl<Selector>  &MethodSels,
95198092Srdivacky      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes,
96193326Sed      bool isClassMethodList);
97193326Sed  llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName);
98198092Srdivacky  llvm::Constant *GeneratePropertyList(const ObjCImplementationDecl *OID,
99198092Srdivacky        llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
100198092Srdivacky        llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes);
101193326Sed  llvm::Constant *GenerateProtocolList(
102193326Sed      const llvm::SmallVectorImpl<std::string> &Protocols);
103198092Srdivacky  // To ensure that all protocols are seen by the runtime, we add a category on
104198092Srdivacky  // a class defined in the runtime, declaring no methods, but adopting the
105198092Srdivacky  // protocols.
106198092Srdivacky  void GenerateProtocolHolderCategory(void);
107193326Sed  llvm::Constant *GenerateClassStructure(
108193326Sed      llvm::Constant *MetaClass,
109193326Sed      llvm::Constant *SuperClass,
110193326Sed      unsigned info,
111193326Sed      const char *Name,
112193326Sed      llvm::Constant *Version,
113193326Sed      llvm::Constant *InstanceSize,
114193326Sed      llvm::Constant *IVars,
115193326Sed      llvm::Constant *Methods,
116198092Srdivacky      llvm::Constant *Protocols,
117198092Srdivacky      llvm::Constant *IvarOffsets,
118207619Srdivacky      llvm::Constant *Properties,
119207619Srdivacky      bool isMeta=false);
120193326Sed  llvm::Constant *GenerateProtocolMethodList(
121193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
122193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes);
123193326Sed  llvm::Constant *MakeConstantString(const std::string &Str, const std::string
124193326Sed      &Name="");
125198092Srdivacky  llvm::Constant *ExportUniqueString(const std::string &Str, const std::string
126198092Srdivacky          prefix);
127193326Sed  llvm::Constant *MakeGlobal(const llvm::StructType *Ty,
128203955Srdivacky    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
129202379Srdivacky    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
130193326Sed  llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty,
131203955Srdivacky    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
132202379Srdivacky    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
133193326Sed  llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
134193326Sed      const ObjCIvarDecl *Ivar);
135194613Sed  void EmitClassRef(const std::string &className);
136203955Srdivacky  llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, const llvm::Type *Ty){
137203955Srdivacky    if (V->getType() == Ty) return V;
138203955Srdivacky    return B.CreateBitCast(V, Ty);
139203955Srdivacky  }
140193326Sedpublic:
141193326Sed  CGObjCGNU(CodeGen::CodeGenModule &cgm);
142202879Srdivacky  virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
143198092Srdivacky  virtual CodeGen::RValue
144193326Sed  GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
145193326Sed                      QualType ResultType,
146193326Sed                      Selector Sel,
147193326Sed                      llvm::Value *Receiver,
148193326Sed                      const CallArgList &CallArgs,
149207619Srdivacky                      const ObjCInterfaceDecl *Class,
150193326Sed                      const ObjCMethodDecl *Method);
151198092Srdivacky  virtual CodeGen::RValue
152193326Sed  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
153193326Sed                           QualType ResultType,
154193326Sed                           Selector Sel,
155193326Sed                           const ObjCInterfaceDecl *Class,
156193326Sed                           bool isCategoryImpl,
157193326Sed                           llvm::Value *Receiver,
158193326Sed                           bool IsClassMessage,
159198092Srdivacky                           const CallArgList &CallArgs,
160198092Srdivacky                           const ObjCMethodDecl *Method);
161193326Sed  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
162193326Sed                                const ObjCInterfaceDecl *OID);
163193326Sed  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
164193326Sed  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
165193326Sed      *Method);
166198092Srdivacky
167198092Srdivacky  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
168193326Sed                                         const ObjCContainerDecl *CD);
169193326Sed  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
170193326Sed  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
171193326Sed  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
172193326Sed                                           const ObjCProtocolDecl *PD);
173193326Sed  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
174193326Sed  virtual llvm::Function *ModuleInitFunction();
175193326Sed  virtual llvm::Function *GetPropertyGetFunction();
176193326Sed  virtual llvm::Function *GetPropertySetFunction();
177207619Srdivacky  virtual llvm::Function *GetCopyStructFunction();
178198092Srdivacky  virtual llvm::Constant *EnumerationMutationFunction();
179198092Srdivacky
180193326Sed  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
181193326Sed                                         const Stmt &S);
182193326Sed  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
183193326Sed                             const ObjCAtThrowStmt &S);
184193326Sed  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
185193326Sed                                         llvm::Value *AddrWeakObj);
186193326Sed  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
187193326Sed                                  llvm::Value *src, llvm::Value *dst);
188193326Sed  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
189193326Sed                                    llvm::Value *src, llvm::Value *dest);
190193326Sed  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
191198092Srdivacky                                    llvm::Value *src, llvm::Value *dest,
192198092Srdivacky                                    llvm::Value *ivarOffset);
193193326Sed  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
194193326Sed                                        llvm::Value *src, llvm::Value *dest);
195198092Srdivacky  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
196198092Srdivacky                                        llvm::Value *DestPtr,
197198092Srdivacky                                        llvm::Value *SrcPtr,
198198092Srdivacky                                        QualType Ty);
199193326Sed  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
200193326Sed                                      QualType ObjectTy,
201193326Sed                                      llvm::Value *BaseValue,
202193326Sed                                      const ObjCIvarDecl *Ivar,
203193326Sed                                      unsigned CVRQualifiers);
204193326Sed  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
205193326Sed                                      const ObjCInterfaceDecl *Interface,
206193326Sed                                      const ObjCIvarDecl *Ivar);
207193326Sed};
208193326Sed} // end anonymous namespace
209193326Sed
210193326Sed
211194613Sed/// Emits a reference to a dummy variable which is emitted with each class.
212194613Sed/// This ensures that a linker error will be generated when trying to link
213194613Sed/// together modules where a referenced class is not defined.
214198092Srdivackyvoid CGObjCGNU::EmitClassRef(const std::string &className) {
215194613Sed  std::string symbolRef = "__objc_class_ref_" + className;
216194613Sed  // Don't emit two copies of the same symbol
217198092Srdivacky  if (TheModule.getGlobalVariable(symbolRef))
218198092Srdivacky    return;
219194613Sed  std::string symbolName = "__objc_class_name_" + className;
220194613Sed  llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
221194613Sed  if (!ClassSymbol) {
222198092Srdivacky    ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
223198092Srdivacky        llvm::GlobalValue::ExternalLinkage, 0, symbolName);
224194613Sed  }
225198092Srdivacky  new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true,
226198092Srdivacky    llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
227194613Sed}
228193326Sed
229193326Sedstatic std::string SymbolNameForMethod(const std::string &ClassName, const
230193326Sed  std::string &CategoryName, const std::string &MethodName, bool isClassMethod)
231193326Sed{
232202379Srdivacky  std::string MethodNameColonStripped = MethodName;
233202379Srdivacky  std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
234202379Srdivacky      ':', '_');
235202379Srdivacky  return std::string(isClassMethod ? "_c_" : "_i_") + ClassName + "_" +
236202379Srdivacky    CategoryName + "_" + MethodNameColonStripped;
237193326Sed}
238193326Sed
239193326SedCGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
240193326Sed  : CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
241198092Srdivacky    MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
242207619Srdivacky
243207619Srdivacky  msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
244207619Srdivacky
245193326Sed  IntTy = cast<llvm::IntegerType>(
246193326Sed      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
247193326Sed  LongTy = cast<llvm::IntegerType>(
248193326Sed      CGM.getTypes().ConvertType(CGM.getContext().LongTy));
249198092Srdivacky
250198092Srdivacky  Int8Ty = llvm::Type::getInt8Ty(VMContext);
251198092Srdivacky  // C string type.  Used in lots of places.
252198092Srdivacky  PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
253198092Srdivacky
254193326Sed  Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
255193326Sed  Zeros[1] = Zeros[0];
256198092Srdivacky  NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
257193326Sed  // Get the selector Type.
258202879Srdivacky  QualType selTy = CGM.getContext().getObjCSelType();
259202879Srdivacky  if (QualType() == selTy) {
260202879Srdivacky    SelectorTy = PtrToInt8Ty;
261202879Srdivacky  } else {
262202879Srdivacky    SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
263202879Srdivacky  }
264193326Sed
265193326Sed  PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
266193326Sed  PtrTy = PtrToInt8Ty;
267198092Srdivacky
268193326Sed  // Object type
269204643Srdivacky  ASTIdTy = CGM.getContext().getCanonicalType(CGM.getContext().getObjCIdType());
270202879Srdivacky  if (QualType() == ASTIdTy) {
271202879Srdivacky    IdTy = PtrToInt8Ty;
272202879Srdivacky  } else {
273202879Srdivacky    IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
274202879Srdivacky  }
275203955Srdivacky  PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
276198092Srdivacky
277193326Sed  // IMP type
278193326Sed  std::vector<const llvm::Type*> IMPArgs;
279193326Sed  IMPArgs.push_back(IdTy);
280193326Sed  IMPArgs.push_back(SelectorTy);
281193326Sed  IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
282203955Srdivacky
283203955Srdivacky  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
284203955Srdivacky    // Get selectors needed in GC mode
285203955Srdivacky    RetainSel = GetNullarySelector("retain", CGM.getContext());
286203955Srdivacky    ReleaseSel = GetNullarySelector("release", CGM.getContext());
287203955Srdivacky    AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext());
288203955Srdivacky
289203955Srdivacky    // Get functions needed in GC mode
290203955Srdivacky
291203955Srdivacky    // id objc_assign_ivar(id, id, ptrdiff_t);
292203955Srdivacky    std::vector<const llvm::Type*> Args(1, IdTy);
293203955Srdivacky    Args.push_back(PtrToIdTy);
294203955Srdivacky    // FIXME: ptrdiff_t
295203955Srdivacky    Args.push_back(LongTy);
296203955Srdivacky    llvm::FunctionType *FTy = llvm::FunctionType::get(IdTy, Args, false);
297203955Srdivacky    IvarAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
298203955Srdivacky    // id objc_assign_strongCast (id, id*)
299203955Srdivacky    Args.pop_back();
300203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
301203955Srdivacky    StrongCastAssignFn =
302203955Srdivacky        CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
303203955Srdivacky    // id objc_assign_global(id, id*);
304203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
305203955Srdivacky    GlobalAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
306203955Srdivacky    // id objc_assign_weak(id, id*);
307203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
308203955Srdivacky    WeakAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
309203955Srdivacky    // id objc_read_weak(id*);
310203955Srdivacky    Args.clear();
311203955Srdivacky    Args.push_back(PtrToIdTy);
312203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
313203955Srdivacky    WeakReadFn = CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
314203955Srdivacky    // void *objc_memmove_collectable(void*, void *, size_t);
315203955Srdivacky    Args.clear();
316203955Srdivacky    Args.push_back(PtrToInt8Ty);
317203955Srdivacky    Args.push_back(PtrToInt8Ty);
318203955Srdivacky    // FIXME: size_t
319203955Srdivacky    Args.push_back(LongTy);
320203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
321203955Srdivacky    MemMoveFn = CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
322203955Srdivacky  }
323193326Sed}
324198092Srdivacky
325193326Sed// This has to perform the lookup every time, since posing and related
326193326Sed// techniques can modify the name -> class mapping.
327193326Sedllvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder,
328193326Sed                                 const ObjCInterfaceDecl *OID) {
329193326Sed  llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString());
330202379Srdivacky  // With the incompatible ABI, this will need to be replaced with a direct
331202379Srdivacky  // reference to the class symbol.  For the compatible nonfragile ABI we are
332202379Srdivacky  // still performing this lookup at run time but emitting the symbol for the
333202379Srdivacky  // class externally so that we can make the switch later.
334194613Sed  EmitClassRef(OID->getNameAsString());
335193326Sed  ClassName = Builder.CreateStructGEP(ClassName, 0);
336193326Sed
337193326Sed  std::vector<const llvm::Type*> Params(1, PtrToInt8Ty);
338193326Sed  llvm::Constant *ClassLookupFn =
339193326Sed    CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy,
340193326Sed                                                      Params,
341193326Sed                                                      true),
342193326Sed                              "objc_lookup_class");
343193326Sed  return Builder.CreateCall(ClassLookupFn, ClassName);
344193326Sed}
345193326Sed
346193326Sedllvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
347193326Sed  llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()];
348193326Sed  if (US == 0)
349193326Sed    US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
350198092Srdivacky                               llvm::GlobalValue::PrivateLinkage,
351198092Srdivacky                               ".objc_untyped_selector_alias"+Sel.getAsString(),
352193326Sed                               NULL, &TheModule);
353198092Srdivacky
354193326Sed  return Builder.CreateLoad(US);
355193326Sed}
356193326Sed
357193326Sedllvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
358193326Sed    *Method) {
359193326Sed
360193326Sed  std::string SelName = Method->getSelector().getAsString();
361193326Sed  std::string SelTypes;
362193326Sed  CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
363193326Sed  // Typed selectors
364193326Sed  TypedSelector Selector = TypedSelector(SelName,
365193326Sed          SelTypes);
366193326Sed
367193326Sed  // If it's already cached, return it.
368198092Srdivacky  if (TypedSelectors[Selector]) {
369198092Srdivacky    return Builder.CreateLoad(TypedSelectors[Selector]);
370193326Sed  }
371193326Sed
372193326Sed  // If it isn't, cache it.
373193326Sed  llvm::GlobalAlias *Sel = new llvm::GlobalAlias(
374193326Sed          llvm::PointerType::getUnqual(SelectorTy),
375198092Srdivacky          llvm::GlobalValue::PrivateLinkage, ".objc_selector_alias" + SelName,
376193326Sed          NULL, &TheModule);
377193326Sed  TypedSelectors[Selector] = Sel;
378193326Sed
379193326Sed  return Builder.CreateLoad(Sel);
380193326Sed}
381193326Sed
382193326Sedllvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
383193326Sed                                              const std::string &Name) {
384198092Srdivacky  llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
385193326Sed  return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
386193326Sed}
387198092Srdivackyllvm::Constant *CGObjCGNU::ExportUniqueString(const std::string &Str,
388198092Srdivacky        const std::string prefix) {
389198092Srdivacky  std::string name = prefix + Str;
390198092Srdivacky  llvm::Constant *ConstStr = TheModule.getGlobalVariable(name);
391198092Srdivacky  if (!ConstStr) {
392198092Srdivacky    llvm::Constant *value = llvm::ConstantArray::get(VMContext, Str, true);
393198092Srdivacky    ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true,
394198092Srdivacky            llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str);
395198092Srdivacky  }
396198092Srdivacky  return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
397198092Srdivacky}
398198092Srdivacky
399193326Sedllvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty,
400203955Srdivacky    std::vector<llvm::Constant*> &V, llvm::StringRef Name,
401202379Srdivacky    llvm::GlobalValue::LinkageTypes linkage) {
402193326Sed  llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
403198092Srdivacky  return new llvm::GlobalVariable(TheModule, Ty, false,
404198092Srdivacky      llvm::GlobalValue::InternalLinkage, C, Name);
405193326Sed}
406198092Srdivacky
407193326Sedllvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty,
408203955Srdivacky    std::vector<llvm::Constant*> &V, llvm::StringRef Name,
409202379Srdivacky    llvm::GlobalValue::LinkageTypes linkage) {
410193326Sed  llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
411198092Srdivacky  return new llvm::GlobalVariable(TheModule, Ty, false,
412198092Srdivacky                                  llvm::GlobalValue::InternalLinkage, C, Name);
413193326Sed}
414193326Sed
415193326Sed/// Generate an NSConstantString object.
416202879Srdivackyllvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
417203955Srdivacky
418202879Srdivacky  std::string Str(SL->getStrData(), SL->getByteLength());
419202879Srdivacky
420203955Srdivacky  // Look for an existing one
421203955Srdivacky  llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
422203955Srdivacky  if (old != ObjCStrings.end())
423203955Srdivacky    return old->getValue();
424203955Srdivacky
425193326Sed  std::vector<llvm::Constant*> Ivars;
426193326Sed  Ivars.push_back(NULLPtr);
427193326Sed  Ivars.push_back(MakeConstantString(Str));
428193326Sed  Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
429193326Sed  llvm::Constant *ObjCStr = MakeGlobal(
430198092Srdivacky    llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL),
431193326Sed    Ivars, ".objc_str");
432203955Srdivacky  ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
433203955Srdivacky  ObjCStrings[Str] = ObjCStr;
434203955Srdivacky  ConstantStrings.push_back(ObjCStr);
435193326Sed  return ObjCStr;
436193326Sed}
437193326Sed
438193326Sed///Generates a message send where the super is the receiver.  This is a message
439193326Sed///send to self with special delivery semantics indicating which class's method
440193326Sed///should be called.
441193326SedCodeGen::RValue
442193326SedCGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
443193326Sed                                    QualType ResultType,
444193326Sed                                    Selector Sel,
445193326Sed                                    const ObjCInterfaceDecl *Class,
446193326Sed                                    bool isCategoryImpl,
447193326Sed                                    llvm::Value *Receiver,
448193326Sed                                    bool IsClassMessage,
449198092Srdivacky                                    const CallArgList &CallArgs,
450198092Srdivacky                                    const ObjCMethodDecl *Method) {
451203955Srdivacky  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
452203955Srdivacky    if (Sel == RetainSel || Sel == AutoreleaseSel) {
453203955Srdivacky      return RValue::get(Receiver);
454203955Srdivacky    }
455203955Srdivacky    if (Sel == ReleaseSel) {
456203955Srdivacky      return RValue::get(0);
457203955Srdivacky    }
458203955Srdivacky  }
459193326Sed
460207619Srdivacky  CGBuilderTy &Builder = CGF.Builder;
461207619Srdivacky  llvm::Value *cmd = GetSelector(Builder, Sel);
462207619Srdivacky
463207619Srdivacky
464193326Sed  CallArgList ActualArgs;
465193326Sed
466193326Sed  ActualArgs.push_back(
467207619Srdivacky      std::make_pair(RValue::get(Builder.CreateBitCast(Receiver, IdTy)),
468198092Srdivacky      ASTIdTy));
469193326Sed  ActualArgs.push_back(std::make_pair(RValue::get(cmd),
470193326Sed                                      CGF.getContext().getObjCSelType()));
471193326Sed  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
472193326Sed
473193326Sed  CodeGenTypes &Types = CGM.getTypes();
474203955Srdivacky  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
475206084Srdivacky                                                       FunctionType::ExtInfo());
476198092Srdivacky  const llvm::FunctionType *impType =
477198092Srdivacky    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
478193326Sed
479193326Sed  llvm::Value *ReceiverClass = 0;
480193326Sed  if (isCategoryImpl) {
481193326Sed    llvm::Constant *classLookupFunction = 0;
482193326Sed    std::vector<const llvm::Type*> Params;
483193326Sed    Params.push_back(PtrTy);
484193326Sed    if (IsClassMessage)  {
485193326Sed      classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
486193326Sed            IdTy, Params, true), "objc_get_meta_class");
487193326Sed    } else {
488193326Sed      classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
489193326Sed            IdTy, Params, true), "objc_get_class");
490193326Sed    }
491207619Srdivacky    ReceiverClass = Builder.CreateCall(classLookupFunction,
492193326Sed        MakeConstantString(Class->getNameAsString()));
493193326Sed  } else {
494193326Sed    // Set up global aliases for the metaclass or class pointer if they do not
495193326Sed    // already exist.  These will are forward-references which will be set to
496198092Srdivacky    // pointers to the class and metaclass structure created for the runtime
497198092Srdivacky    // load function.  To send a message to super, we look up the value of the
498193326Sed    // super_class pointer from either the class or metaclass structure.
499193326Sed    if (IsClassMessage)  {
500193326Sed      if (!MetaClassPtrAlias) {
501193326Sed        MetaClassPtrAlias = new llvm::GlobalAlias(IdTy,
502193326Sed            llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" +
503193326Sed            Class->getNameAsString(), NULL, &TheModule);
504193326Sed      }
505193326Sed      ReceiverClass = MetaClassPtrAlias;
506193326Sed    } else {
507193326Sed      if (!ClassPtrAlias) {
508193326Sed        ClassPtrAlias = new llvm::GlobalAlias(IdTy,
509193326Sed            llvm::GlobalValue::InternalLinkage, ".objc_class_ref" +
510193326Sed            Class->getNameAsString(), NULL, &TheModule);
511193326Sed      }
512193326Sed      ReceiverClass = ClassPtrAlias;
513193326Sed    }
514193326Sed  }
515193326Sed  // Cast the pointer to a simplified version of the class structure
516207619Srdivacky  ReceiverClass = Builder.CreateBitCast(ReceiverClass,
517198092Srdivacky      llvm::PointerType::getUnqual(
518198092Srdivacky        llvm::StructType::get(VMContext, IdTy, IdTy, NULL)));
519193326Sed  // Get the superclass pointer
520207619Srdivacky  ReceiverClass = Builder.CreateStructGEP(ReceiverClass, 1);
521193326Sed  // Load the superclass pointer
522207619Srdivacky  ReceiverClass = Builder.CreateLoad(ReceiverClass);
523193326Sed  // Construct the structure used to look up the IMP
524198092Srdivacky  llvm::StructType *ObjCSuperTy = llvm::StructType::get(VMContext,
525198092Srdivacky      Receiver->getType(), IdTy, NULL);
526207619Srdivacky  llvm::Value *ObjCSuper = Builder.CreateAlloca(ObjCSuperTy);
527193326Sed
528207619Srdivacky  Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
529207619Srdivacky  Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
530193326Sed
531193326Sed  // Get the IMP
532193326Sed  std::vector<const llvm::Type*> Params;
533193326Sed  Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy));
534193326Sed  Params.push_back(SelectorTy);
535207619Srdivacky
536207619Srdivacky  llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
537207619Srdivacky  llvm::Value *imp;
538207619Srdivacky
539207619Srdivacky  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
540207619Srdivacky    // The lookup function returns a slot, which can be safely cached.
541207619Srdivacky    llvm::Type *SlotTy = llvm::StructType::get(VMContext, PtrTy, PtrTy, PtrTy,
542207619Srdivacky            IntTy, llvm::PointerType::getUnqual(impType), NULL);
543207619Srdivacky
544207619Srdivacky    llvm::Constant *lookupFunction =
545207619Srdivacky      CGM.CreateRuntimeFunction(llvm::FunctionType::get(
546207619Srdivacky            llvm::PointerType::getUnqual(SlotTy), Params, true),
547207619Srdivacky          "objc_slot_lookup_super");
548207619Srdivacky
549207619Srdivacky    llvm::CallInst *slot = Builder.CreateCall(lookupFunction, lookupArgs,
550207619Srdivacky        lookupArgs+2);
551207619Srdivacky    slot->setOnlyReadsMemory();
552207619Srdivacky
553207619Srdivacky    imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
554207619Srdivacky  } else {
555198092Srdivacky  llvm::Constant *lookupFunction =
556193326Sed    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
557193326Sed          llvm::PointerType::getUnqual(impType), Params, true),
558193326Sed        "objc_msg_lookup_super");
559207619Srdivacky    imp = Builder.CreateCall(lookupFunction, lookupArgs, lookupArgs+2);
560207619Srdivacky  }
561193326Sed
562207619Srdivacky  llvm::Value *impMD[] = {
563207619Srdivacky      llvm::MDString::get(VMContext, Sel.getAsString()),
564207619Srdivacky      llvm::MDString::get(VMContext, Class->getSuperClass()->getNameAsString()),
565207619Srdivacky      llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsClassMessage)
566207619Srdivacky   };
567207619Srdivacky  llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD, 3);
568193326Sed
569207619Srdivacky  llvm::Instruction *call;
570207619Srdivacky  RValue msgRet = CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs,
571207619Srdivacky      0, &call);
572207619Srdivacky  call->setMetadata(msgSendMDKind, node);
573207619Srdivacky  return msgRet;
574193326Sed}
575193326Sed
576198092Srdivacky/// Generate code for a message send expression.
577193326SedCodeGen::RValue
578193326SedCGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
579193326Sed                               QualType ResultType,
580193326Sed                               Selector Sel,
581193326Sed                               llvm::Value *Receiver,
582193326Sed                               const CallArgList &CallArgs,
583207619Srdivacky                               const ObjCInterfaceDecl *Class,
584193326Sed                               const ObjCMethodDecl *Method) {
585207619Srdivacky  // Strip out message sends to retain / release in GC mode
586203955Srdivacky  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
587203955Srdivacky    if (Sel == RetainSel || Sel == AutoreleaseSel) {
588203955Srdivacky      return RValue::get(Receiver);
589203955Srdivacky    }
590203955Srdivacky    if (Sel == ReleaseSel) {
591203955Srdivacky      return RValue::get(0);
592203955Srdivacky    }
593203955Srdivacky  }
594207619Srdivacky
595198092Srdivacky  CGBuilderTy &Builder = CGF.Builder;
596207619Srdivacky
597207619Srdivacky  // If the return type is something that goes in an integer register, the
598207619Srdivacky  // runtime will handle 0 returns.  For other cases, we fill in the 0 value
599207619Srdivacky  // ourselves.
600207619Srdivacky  //
601207619Srdivacky  // The language spec says the result of this kind of message send is
602207619Srdivacky  // undefined, but lots of people seem to have forgotten to read that
603207619Srdivacky  // paragraph and insist on sending messages to nil that have structure
604207619Srdivacky  // returns.  With GCC, this generates a random return value (whatever happens
605207619Srdivacky  // to be on the stack / in those registers at the time) on most platforms,
606207619Srdivacky  // and generates a SegV on SPARC.  With LLVM it corrupts the stack.
607207619Srdivacky  bool isPointerSizedReturn = false;
608207619Srdivacky  if (ResultType->isAnyPointerType() || ResultType->isIntegralType() ||
609207619Srdivacky      ResultType->isVoidType())
610207619Srdivacky    isPointerSizedReturn = true;
611207619Srdivacky
612207619Srdivacky  llvm::BasicBlock *startBB = 0;
613207619Srdivacky  llvm::BasicBlock *messageBB = 0;
614207619Srdivacky  llvm::BasicBlock *contiueBB = 0;
615207619Srdivacky
616207619Srdivacky  if (!isPointerSizedReturn) {
617207619Srdivacky    startBB = Builder.GetInsertBlock();
618207619Srdivacky    messageBB = CGF.createBasicBlock("msgSend");
619207619Srdivacky    contiueBB = CGF.createBasicBlock("continue");
620207619Srdivacky
621207619Srdivacky    llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
622207619Srdivacky            llvm::Constant::getNullValue(Receiver->getType()));
623207619Srdivacky    Builder.CreateCondBr(isNil, contiueBB, messageBB);
624207619Srdivacky    CGF.EmitBlock(messageBB);
625207619Srdivacky  }
626207619Srdivacky
627198092Srdivacky  IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
628193326Sed  llvm::Value *cmd;
629193326Sed  if (Method)
630198092Srdivacky    cmd = GetSelector(Builder, Method);
631193326Sed  else
632198092Srdivacky    cmd = GetSelector(Builder, Sel);
633193326Sed  CallArgList ActualArgs;
634193326Sed
635198092Srdivacky  Receiver = Builder.CreateBitCast(Receiver, IdTy);
636193326Sed  ActualArgs.push_back(
637198092Srdivacky    std::make_pair(RValue::get(Receiver), ASTIdTy));
638193326Sed  ActualArgs.push_back(std::make_pair(RValue::get(cmd),
639193326Sed                                      CGF.getContext().getObjCSelType()));
640193326Sed  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
641193326Sed
642193326Sed  CodeGenTypes &Types = CGM.getTypes();
643203955Srdivacky  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
644206084Srdivacky                                                       FunctionType::ExtInfo());
645198092Srdivacky  const llvm::FunctionType *impType =
646198092Srdivacky    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
647193326Sed
648207619Srdivacky  llvm::Value *impMD[] = {
649207619Srdivacky        llvm::MDString::get(VMContext, Sel.getAsString()),
650207619Srdivacky        llvm::MDString::get(VMContext, Class ? Class->getNameAsString() :""),
651207619Srdivacky        llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), Class!=0)
652207619Srdivacky   };
653207619Srdivacky  llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD, 3);
654207619Srdivacky
655207619Srdivacky
656193326Sed  llvm::Value *imp;
657193326Sed  // For sender-aware dispatch, we pass the sender as the third argument to a
658193326Sed  // lookup function.  When sending messages from C code, the sender is nil.
659198092Srdivacky  // objc_msg_lookup_sender(id *receiver, SEL selector, id sender);
660198092Srdivacky  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
661198092Srdivacky
662198092Srdivacky    std::vector<const llvm::Type*> Params;
663198092Srdivacky    llvm::Value *ReceiverPtr = CGF.CreateTempAlloca(Receiver->getType());
664198092Srdivacky    Builder.CreateStore(Receiver, ReceiverPtr);
665198092Srdivacky    Params.push_back(ReceiverPtr->getType());
666198092Srdivacky    Params.push_back(SelectorTy);
667193326Sed    llvm::Value *self;
668193326Sed
669193326Sed    if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) {
670193326Sed      self = CGF.LoadObjCSelf();
671193326Sed    } else {
672193326Sed      self = llvm::ConstantPointerNull::get(IdTy);
673193326Sed    }
674198092Srdivacky
675193326Sed    Params.push_back(self->getType());
676198092Srdivacky
677198092Srdivacky    // The lookup function returns a slot, which can be safely cached.
678198092Srdivacky    llvm::Type *SlotTy = llvm::StructType::get(VMContext, PtrTy, PtrTy, PtrTy,
679198092Srdivacky            IntTy, llvm::PointerType::getUnqual(impType), NULL);
680198092Srdivacky    llvm::Constant *lookupFunction =
681193326Sed      CGM.CreateRuntimeFunction(llvm::FunctionType::get(
682198092Srdivacky          llvm::PointerType::getUnqual(SlotTy), Params, true),
683193326Sed        "objc_msg_lookup_sender");
684193326Sed
685198092Srdivacky    // The lookup function is guaranteed not to capture the receiver pointer.
686198092Srdivacky    if (llvm::Function *LookupFn = dyn_cast<llvm::Function>(lookupFunction)) {
687198092Srdivacky      LookupFn->setDoesNotCapture(1);
688198092Srdivacky    }
689198092Srdivacky
690207619Srdivacky    llvm::CallInst *slot =
691198092Srdivacky        Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
692207619Srdivacky    slot->setOnlyReadsMemory();
693207619Srdivacky    slot->setMetadata(msgSendMDKind, node);
694207619Srdivacky
695198092Srdivacky    imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
696207619Srdivacky
697198092Srdivacky    // The lookup function may have changed the receiver, so make sure we use
698198092Srdivacky    // the new one.
699198092Srdivacky    ActualArgs[0] =
700198092Srdivacky        std::make_pair(RValue::get(Builder.CreateLoad(ReceiverPtr)), ASTIdTy);
701193326Sed  } else {
702198092Srdivacky    std::vector<const llvm::Type*> Params;
703198092Srdivacky    Params.push_back(Receiver->getType());
704198092Srdivacky    Params.push_back(SelectorTy);
705198092Srdivacky    llvm::Constant *lookupFunction =
706193326Sed    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
707193326Sed        llvm::PointerType::getUnqual(impType), Params, true),
708193326Sed      "objc_msg_lookup");
709193326Sed
710198092Srdivacky    imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
711207619Srdivacky    cast<llvm::CallInst>(imp)->setMetadata(msgSendMDKind, node);
712193326Sed  }
713207619Srdivacky  llvm::Instruction *call;
714207619Srdivacky  RValue msgRet = CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs,
715207619Srdivacky      0, &call);
716207619Srdivacky  call->setMetadata(msgSendMDKind, node);
717193326Sed
718207619Srdivacky  if (!isPointerSizedReturn) {
719207619Srdivacky    CGF.EmitBlock(contiueBB);
720207619Srdivacky    if (msgRet.isScalar()) {
721207619Srdivacky      llvm::Value *v = msgRet.getScalarVal();
722207619Srdivacky      llvm::PHINode *phi = Builder.CreatePHI(v->getType());
723207619Srdivacky      phi->addIncoming(v, messageBB);
724207619Srdivacky      phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
725207619Srdivacky      msgRet = RValue::get(phi);
726207619Srdivacky    } else if (msgRet.isAggregate()) {
727207619Srdivacky      llvm::Value *v = msgRet.getAggregateAddr();
728207619Srdivacky      llvm::PHINode *phi = Builder.CreatePHI(v->getType());
729207619Srdivacky      const llvm::PointerType *RetTy = cast<llvm::PointerType>(v->getType());
730207619Srdivacky      llvm::AllocaInst *NullVal =
731207619Srdivacky          CGF.CreateTempAlloca(RetTy->getElementType(), "null");
732207619Srdivacky      CGF.InitTempAlloca(NullVal,
733207619Srdivacky          llvm::Constant::getNullValue(RetTy->getElementType()));
734207619Srdivacky      phi->addIncoming(v, messageBB);
735207619Srdivacky      phi->addIncoming(NullVal, startBB);
736207619Srdivacky      msgRet = RValue::getAggregate(phi);
737207619Srdivacky    } else /* isComplex() */ {
738207619Srdivacky      std::pair<llvm::Value*,llvm::Value*> v = msgRet.getComplexVal();
739207619Srdivacky      llvm::PHINode *phi = Builder.CreatePHI(v.first->getType());
740207619Srdivacky      phi->addIncoming(v.first, messageBB);
741207619Srdivacky      phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
742207619Srdivacky          startBB);
743207619Srdivacky      llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType());
744207619Srdivacky      phi2->addIncoming(v.second, messageBB);
745207619Srdivacky      phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
746207619Srdivacky          startBB);
747207619Srdivacky      msgRet = RValue::getComplex(phi, phi2);
748207619Srdivacky    }
749207619Srdivacky  }
750207619Srdivacky  return msgRet;
751193326Sed}
752193326Sed
753198092Srdivacky/// Generates a MethodList.  Used in construction of a objc_class and
754193326Sed/// objc_category structures.
755193326Sedllvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
756198092Srdivacky                                              const std::string &CategoryName,
757198092Srdivacky    const llvm::SmallVectorImpl<Selector> &MethodSels,
758198092Srdivacky    const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
759193326Sed    bool isClassMethodList) {
760198092Srdivacky  if (MethodSels.empty())
761198092Srdivacky    return NULLPtr;
762198092Srdivacky  // Get the method structure type.
763198092Srdivacky  llvm::StructType *ObjCMethodTy = llvm::StructType::get(VMContext,
764193326Sed    PtrToInt8Ty, // Really a selector, but the runtime creates it us.
765193326Sed    PtrToInt8Ty, // Method types
766193326Sed    llvm::PointerType::getUnqual(IMPTy), //Method pointer
767193326Sed    NULL);
768193326Sed  std::vector<llvm::Constant*> Methods;
769193326Sed  std::vector<llvm::Constant*> Elements;
770193326Sed  for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
771193326Sed    Elements.clear();
772193326Sed    if (llvm::Constant *Method =
773193326Sed      TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
774193326Sed                                                MethodSels[i].getAsString(),
775193326Sed                                                isClassMethodList))) {
776198092Srdivacky      llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString());
777198092Srdivacky      Elements.push_back(C);
778198092Srdivacky      Elements.push_back(MethodTypes[i]);
779193326Sed      Method = llvm::ConstantExpr::getBitCast(Method,
780193326Sed          llvm::PointerType::getUnqual(IMPTy));
781193326Sed      Elements.push_back(Method);
782193326Sed      Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
783193326Sed    }
784193326Sed  }
785193326Sed
786193326Sed  // Array of method structures
787193326Sed  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
788193326Sed                                                            Methods.size());
789193326Sed  llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
790193326Sed                                                         Methods);
791193326Sed
792193326Sed  // Structure containing list pointer, array and array count
793193326Sed  llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields;
794198092Srdivacky  llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get(VMContext);
795193326Sed  llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy);
796198092Srdivacky  llvm::StructType *ObjCMethodListTy = llvm::StructType::get(VMContext,
797198092Srdivacky      NextPtrTy,
798198092Srdivacky      IntTy,
799193326Sed      ObjCMethodArrayTy,
800193326Sed      NULL);
801193326Sed  // Refine next pointer type to concrete type
802193326Sed  llvm::cast<llvm::OpaqueType>(
803193326Sed      OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy);
804193326Sed  ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get());
805193326Sed
806193326Sed  Methods.clear();
807193326Sed  Methods.push_back(llvm::ConstantPointerNull::get(
808193326Sed        llvm::PointerType::getUnqual(ObjCMethodListTy)));
809198092Srdivacky  Methods.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
810193326Sed        MethodTypes.size()));
811193326Sed  Methods.push_back(MethodArray);
812198092Srdivacky
813193326Sed  // Create an instance of the structure
814193326Sed  return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list");
815193326Sed}
816193326Sed
817193326Sed/// Generates an IvarList.  Used in construction of a objc_class.
818193326Sedllvm::Constant *CGObjCGNU::GenerateIvarList(
819193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
820193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
821193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets) {
822199482Srdivacky  if (IvarNames.size() == 0)
823199482Srdivacky    return NULLPtr;
824198092Srdivacky  // Get the method structure type.
825198092Srdivacky  llvm::StructType *ObjCIvarTy = llvm::StructType::get(VMContext,
826193326Sed    PtrToInt8Ty,
827193326Sed    PtrToInt8Ty,
828193326Sed    IntTy,
829193326Sed    NULL);
830193326Sed  std::vector<llvm::Constant*> Ivars;
831193326Sed  std::vector<llvm::Constant*> Elements;
832193326Sed  for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
833193326Sed    Elements.clear();
834198092Srdivacky    Elements.push_back(IvarNames[i]);
835198092Srdivacky    Elements.push_back(IvarTypes[i]);
836193326Sed    Elements.push_back(IvarOffsets[i]);
837193326Sed    Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements));
838193326Sed  }
839193326Sed
840193326Sed  // Array of method structures
841193326Sed  llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
842193326Sed      IvarNames.size());
843193326Sed
844198092Srdivacky
845193326Sed  Elements.clear();
846193326Sed  Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size()));
847193326Sed  Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars));
848193326Sed  // Structure containing array and array count
849198092Srdivacky  llvm::StructType *ObjCIvarListTy = llvm::StructType::get(VMContext, IntTy,
850193326Sed    ObjCIvarArrayTy,
851193326Sed    NULL);
852193326Sed
853193326Sed  // Create an instance of the structure
854193326Sed  return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list");
855193326Sed}
856193326Sed
857193326Sed/// Generate a class structure
858193326Sedllvm::Constant *CGObjCGNU::GenerateClassStructure(
859193326Sed    llvm::Constant *MetaClass,
860193326Sed    llvm::Constant *SuperClass,
861193326Sed    unsigned info,
862193326Sed    const char *Name,
863193326Sed    llvm::Constant *Version,
864193326Sed    llvm::Constant *InstanceSize,
865193326Sed    llvm::Constant *IVars,
866193326Sed    llvm::Constant *Methods,
867198092Srdivacky    llvm::Constant *Protocols,
868198092Srdivacky    llvm::Constant *IvarOffsets,
869207619Srdivacky    llvm::Constant *Properties,
870207619Srdivacky    bool isMeta) {
871193326Sed  // Set up the class structure
872193326Sed  // Note:  Several of these are char*s when they should be ids.  This is
873193326Sed  // because the runtime performs this translation on load.
874198092Srdivacky  //
875198092Srdivacky  // Fields marked New ABI are part of the GNUstep runtime.  We emit them
876198092Srdivacky  // anyway; the classes will still work with the GNU runtime, they will just
877198092Srdivacky  // be ignored.
878198092Srdivacky  llvm::StructType *ClassTy = llvm::StructType::get(VMContext,
879193326Sed      PtrToInt8Ty,        // class_pointer
880193326Sed      PtrToInt8Ty,        // super_class
881193326Sed      PtrToInt8Ty,        // name
882193326Sed      LongTy,             // version
883193326Sed      LongTy,             // info
884193326Sed      LongTy,             // instance_size
885193326Sed      IVars->getType(),   // ivars
886193326Sed      Methods->getType(), // methods
887198092Srdivacky      // These are all filled in by the runtime, so we pretend
888193326Sed      PtrTy,              // dtable
889193326Sed      PtrTy,              // subclass_list
890193326Sed      PtrTy,              // sibling_class
891193326Sed      PtrTy,              // protocols
892193326Sed      PtrTy,              // gc_object_type
893198092Srdivacky      // New ABI:
894198092Srdivacky      LongTy,                 // abi_version
895198092Srdivacky      IvarOffsets->getType(), // ivar_offsets
896198092Srdivacky      Properties->getType(),  // properties
897193326Sed      NULL);
898193326Sed  llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
899193326Sed  // Fill in the structure
900193326Sed  std::vector<llvm::Constant*> Elements;
901193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
902193326Sed  Elements.push_back(SuperClass);
903193326Sed  Elements.push_back(MakeConstantString(Name, ".class_name"));
904193326Sed  Elements.push_back(Zero);
905193326Sed  Elements.push_back(llvm::ConstantInt::get(LongTy, info));
906193326Sed  Elements.push_back(InstanceSize);
907193326Sed  Elements.push_back(IVars);
908193326Sed  Elements.push_back(Methods);
909198092Srdivacky  Elements.push_back(NULLPtr);
910198092Srdivacky  Elements.push_back(NULLPtr);
911198092Srdivacky  Elements.push_back(NULLPtr);
912193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
913198092Srdivacky  Elements.push_back(NULLPtr);
914198092Srdivacky  Elements.push_back(Zero);
915198092Srdivacky  Elements.push_back(IvarOffsets);
916198092Srdivacky  Elements.push_back(Properties);
917193326Sed  // Create an instance of the structure
918202379Srdivacky  // This is now an externally visible symbol, so that we can speed up class
919202379Srdivacky  // messages in the next ABI.
920207619Srdivacky  return MakeGlobal(ClassTy, Elements, (isMeta ? "_OBJC_METACLASS_":
921207619Srdivacky      "_OBJC_CLASS_") + std::string(Name), llvm::GlobalValue::ExternalLinkage);
922193326Sed}
923193326Sed
924193326Sedllvm::Constant *CGObjCGNU::GenerateProtocolMethodList(
925193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
926193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes) {
927198092Srdivacky  // Get the method structure type.
928198092Srdivacky  llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(VMContext,
929193326Sed    PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.
930193326Sed    PtrToInt8Ty,
931193326Sed    NULL);
932193326Sed  std::vector<llvm::Constant*> Methods;
933193326Sed  std::vector<llvm::Constant*> Elements;
934193326Sed  for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
935193326Sed    Elements.clear();
936198092Srdivacky    Elements.push_back(MethodNames[i]);
937198092Srdivacky    Elements.push_back(MethodTypes[i]);
938193326Sed    Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements));
939193326Sed  }
940193326Sed  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
941193326Sed      MethodNames.size());
942198092Srdivacky  llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
943198092Srdivacky                                                   Methods);
944198092Srdivacky  llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(VMContext,
945193326Sed      IntTy, ObjCMethodArrayTy, NULL);
946193326Sed  Methods.clear();
947193326Sed  Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
948193326Sed  Methods.push_back(Array);
949193326Sed  return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list");
950193326Sed}
951198092Srdivacky
952193326Sed// Create the protocol list structure used in classes, categories and so on
953193326Sedllvm::Constant *CGObjCGNU::GenerateProtocolList(
954193326Sed    const llvm::SmallVectorImpl<std::string> &Protocols) {
955193326Sed  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
956193326Sed      Protocols.size());
957198092Srdivacky  llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext,
958193326Sed      PtrTy, //Should be a recurisve pointer, but it's always NULL here.
959193326Sed      LongTy,//FIXME: Should be size_t
960193326Sed      ProtocolArrayTy,
961193326Sed      NULL);
962198092Srdivacky  std::vector<llvm::Constant*> Elements;
963193326Sed  for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
964193326Sed      iter != endIter ; iter++) {
965199990Srdivacky    llvm::Constant *protocol = 0;
966199990Srdivacky    llvm::StringMap<llvm::Constant*>::iterator value =
967199990Srdivacky      ExistingProtocols.find(*iter);
968199990Srdivacky    if (value == ExistingProtocols.end()) {
969193326Sed      protocol = GenerateEmptyProtocol(*iter);
970199990Srdivacky    } else {
971199990Srdivacky      protocol = value->getValue();
972199990Srdivacky    }
973198092Srdivacky    llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
974198092Srdivacky                                                           PtrToInt8Ty);
975193326Sed    Elements.push_back(Ptr);
976193326Sed  }
977193326Sed  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
978193326Sed      Elements);
979193326Sed  Elements.clear();
980193326Sed  Elements.push_back(NULLPtr);
981193326Sed  Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
982193326Sed  Elements.push_back(ProtocolArray);
983193326Sed  return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list");
984193326Sed}
985193326Sed
986198092Srdivackyllvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder,
987193326Sed                                            const ObjCProtocolDecl *PD) {
988193326Sed  llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()];
989198092Srdivacky  const llvm::Type *T =
990193326Sed    CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
991193326Sed  return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
992193326Sed}
993193326Sed
994193326Sedllvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
995193326Sed  const std::string &ProtocolName) {
996193326Sed  llvm::SmallVector<std::string, 0> EmptyStringVector;
997193326Sed  llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector;
998193326Sed
999193326Sed  llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
1000198092Srdivacky  llvm::Constant *MethodList =
1001193326Sed    GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
1002193326Sed  // Protocols are objects containing lists of the methods implemented and
1003193326Sed  // protocols adopted.
1004198092Srdivacky  llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy,
1005193326Sed      PtrToInt8Ty,
1006193326Sed      ProtocolList->getType(),
1007198092Srdivacky      MethodList->getType(),
1008198092Srdivacky      MethodList->getType(),
1009198092Srdivacky      MethodList->getType(),
1010198092Srdivacky      MethodList->getType(),
1011193326Sed      NULL);
1012198092Srdivacky  std::vector<llvm::Constant*> Elements;
1013193326Sed  // The isa pointer must be set to a magic number so the runtime knows it's
1014193326Sed  // the correct layout.
1015198092Srdivacky  int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ?
1016198092Srdivacky      NonFragileProtocolVersion : ProtocolVersion;
1017193326Sed  Elements.push_back(llvm::ConstantExpr::getIntToPtr(
1018198092Srdivacky        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy));
1019193326Sed  Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
1020193326Sed  Elements.push_back(ProtocolList);
1021198092Srdivacky  Elements.push_back(MethodList);
1022198092Srdivacky  Elements.push_back(MethodList);
1023198092Srdivacky  Elements.push_back(MethodList);
1024198092Srdivacky  Elements.push_back(MethodList);
1025193326Sed  return MakeGlobal(ProtocolTy, Elements, ".objc_protocol");
1026193326Sed}
1027193326Sed
1028193326Sedvoid CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
1029193326Sed  ASTContext &Context = CGM.getContext();
1030193326Sed  std::string ProtocolName = PD->getNameAsString();
1031193326Sed  llvm::SmallVector<std::string, 16> Protocols;
1032193326Sed  for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
1033193326Sed       E = PD->protocol_end(); PI != E; ++PI)
1034193326Sed    Protocols.push_back((*PI)->getNameAsString());
1035193326Sed  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
1036193326Sed  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
1037198092Srdivacky  llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodNames;
1038198092Srdivacky  llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodTypes;
1039195341Sed  for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
1040195341Sed       E = PD->instmeth_end(); iter != E; iter++) {
1041193326Sed    std::string TypeStr;
1042193326Sed    Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
1043198092Srdivacky    if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
1044198092Srdivacky      InstanceMethodNames.push_back(
1045198092Srdivacky          MakeConstantString((*iter)->getSelector().getAsString()));
1046198092Srdivacky      InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1047198092Srdivacky    } else {
1048198092Srdivacky      OptionalInstanceMethodNames.push_back(
1049198092Srdivacky          MakeConstantString((*iter)->getSelector().getAsString()));
1050198092Srdivacky      OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1051198092Srdivacky    }
1052193326Sed  }
1053193326Sed  // Collect information about class methods:
1054193326Sed  llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
1055193326Sed  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
1056198092Srdivacky  llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodNames;
1057198092Srdivacky  llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodTypes;
1058198092Srdivacky  for (ObjCProtocolDecl::classmeth_iterator
1059195341Sed         iter = PD->classmeth_begin(), endIter = PD->classmeth_end();
1060195341Sed       iter != endIter ; iter++) {
1061193326Sed    std::string TypeStr;
1062193326Sed    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
1063198092Srdivacky    if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
1064198092Srdivacky      ClassMethodNames.push_back(
1065198092Srdivacky          MakeConstantString((*iter)->getSelector().getAsString()));
1066198092Srdivacky      ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1067198092Srdivacky    } else {
1068198092Srdivacky      OptionalClassMethodNames.push_back(
1069198092Srdivacky          MakeConstantString((*iter)->getSelector().getAsString()));
1070198092Srdivacky      OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
1071198092Srdivacky    }
1072193326Sed  }
1073193326Sed
1074193326Sed  llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1075193326Sed  llvm::Constant *InstanceMethodList =
1076193326Sed    GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
1077193326Sed  llvm::Constant *ClassMethodList =
1078193326Sed    GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
1079198092Srdivacky  llvm::Constant *OptionalInstanceMethodList =
1080198092Srdivacky    GenerateProtocolMethodList(OptionalInstanceMethodNames,
1081198092Srdivacky            OptionalInstanceMethodTypes);
1082198092Srdivacky  llvm::Constant *OptionalClassMethodList =
1083198092Srdivacky    GenerateProtocolMethodList(OptionalClassMethodNames,
1084198092Srdivacky            OptionalClassMethodTypes);
1085198092Srdivacky
1086198092Srdivacky  // Property metadata: name, attributes, isSynthesized, setter name, setter
1087198092Srdivacky  // types, getter name, getter types.
1088198092Srdivacky  // The isSynthesized value is always set to 0 in a protocol.  It exists to
1089198092Srdivacky  // simplify the runtime library by allowing it to use the same data
1090198092Srdivacky  // structures for protocol metadata everywhere.
1091198092Srdivacky  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext,
1092198092Srdivacky          PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
1093198092Srdivacky          PtrToInt8Ty, NULL);
1094198092Srdivacky  std::vector<llvm::Constant*> Properties;
1095198092Srdivacky  std::vector<llvm::Constant*> OptionalProperties;
1096198092Srdivacky
1097198092Srdivacky  // Add all of the property methods need adding to the method list and to the
1098198092Srdivacky  // property metadata list.
1099198092Srdivacky  for (ObjCContainerDecl::prop_iterator
1100198092Srdivacky         iter = PD->prop_begin(), endIter = PD->prop_end();
1101198092Srdivacky       iter != endIter ; iter++) {
1102198092Srdivacky    std::vector<llvm::Constant*> Fields;
1103198092Srdivacky    ObjCPropertyDecl *property = (*iter);
1104198092Srdivacky
1105198092Srdivacky    Fields.push_back(MakeConstantString(property->getNameAsString()));
1106198092Srdivacky    Fields.push_back(llvm::ConstantInt::get(Int8Ty,
1107198092Srdivacky                property->getPropertyAttributes()));
1108198092Srdivacky    Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
1109198092Srdivacky    if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
1110198092Srdivacky      std::string TypeStr;
1111198092Srdivacky      Context.getObjCEncodingForMethodDecl(getter,TypeStr);
1112198092Srdivacky      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1113198092Srdivacky      InstanceMethodTypes.push_back(TypeEncoding);
1114198092Srdivacky      Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
1115198092Srdivacky      Fields.push_back(TypeEncoding);
1116198092Srdivacky    } else {
1117198092Srdivacky      Fields.push_back(NULLPtr);
1118198092Srdivacky      Fields.push_back(NULLPtr);
1119198092Srdivacky    }
1120198092Srdivacky    if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
1121198092Srdivacky      std::string TypeStr;
1122198092Srdivacky      Context.getObjCEncodingForMethodDecl(setter,TypeStr);
1123198092Srdivacky      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1124198092Srdivacky      InstanceMethodTypes.push_back(TypeEncoding);
1125198092Srdivacky      Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
1126198092Srdivacky      Fields.push_back(TypeEncoding);
1127198092Srdivacky    } else {
1128198092Srdivacky      Fields.push_back(NULLPtr);
1129198092Srdivacky      Fields.push_back(NULLPtr);
1130198092Srdivacky    }
1131198092Srdivacky    if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) {
1132198092Srdivacky      OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1133198092Srdivacky    } else {
1134198092Srdivacky      Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1135198092Srdivacky    }
1136198092Srdivacky  }
1137198092Srdivacky  llvm::Constant *PropertyArray = llvm::ConstantArray::get(
1138198092Srdivacky      llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
1139198092Srdivacky  llvm::Constant* PropertyListInitFields[] =
1140198092Srdivacky    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
1141198092Srdivacky
1142198092Srdivacky  llvm::Constant *PropertyListInit =
1143198092Srdivacky      llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false);
1144198092Srdivacky  llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule,
1145198092Srdivacky      PropertyListInit->getType(), false, llvm::GlobalValue::InternalLinkage,
1146198092Srdivacky      PropertyListInit, ".objc_property_list");
1147198092Srdivacky
1148198092Srdivacky  llvm::Constant *OptionalPropertyArray =
1149198092Srdivacky      llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
1150198092Srdivacky          OptionalProperties.size()) , OptionalProperties);
1151198092Srdivacky  llvm::Constant* OptionalPropertyListInitFields[] = {
1152198092Srdivacky      llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
1153198092Srdivacky      OptionalPropertyArray };
1154198092Srdivacky
1155198092Srdivacky  llvm::Constant *OptionalPropertyListInit =
1156198092Srdivacky      llvm::ConstantStruct::get(VMContext, OptionalPropertyListInitFields, 3, false);
1157198092Srdivacky  llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(TheModule,
1158198092Srdivacky          OptionalPropertyListInit->getType(), false,
1159198092Srdivacky          llvm::GlobalValue::InternalLinkage, OptionalPropertyListInit,
1160198092Srdivacky          ".objc_property_list");
1161198092Srdivacky
1162193326Sed  // Protocols are objects containing lists of the methods implemented and
1163193326Sed  // protocols adopted.
1164198092Srdivacky  llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy,
1165193326Sed      PtrToInt8Ty,
1166193326Sed      ProtocolList->getType(),
1167193326Sed      InstanceMethodList->getType(),
1168193326Sed      ClassMethodList->getType(),
1169198092Srdivacky      OptionalInstanceMethodList->getType(),
1170198092Srdivacky      OptionalClassMethodList->getType(),
1171198092Srdivacky      PropertyList->getType(),
1172198092Srdivacky      OptionalPropertyList->getType(),
1173193326Sed      NULL);
1174198092Srdivacky  std::vector<llvm::Constant*> Elements;
1175193326Sed  // The isa pointer must be set to a magic number so the runtime knows it's
1176193326Sed  // the correct layout.
1177198092Srdivacky  int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ?
1178198092Srdivacky      NonFragileProtocolVersion : ProtocolVersion;
1179193326Sed  Elements.push_back(llvm::ConstantExpr::getIntToPtr(
1180198092Srdivacky        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy));
1181193326Sed  Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
1182193326Sed  Elements.push_back(ProtocolList);
1183193326Sed  Elements.push_back(InstanceMethodList);
1184193326Sed  Elements.push_back(ClassMethodList);
1185198092Srdivacky  Elements.push_back(OptionalInstanceMethodList);
1186198092Srdivacky  Elements.push_back(OptionalClassMethodList);
1187198092Srdivacky  Elements.push_back(PropertyList);
1188198092Srdivacky  Elements.push_back(OptionalPropertyList);
1189198092Srdivacky  ExistingProtocols[ProtocolName] =
1190193326Sed    llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
1191193326Sed          ".objc_protocol"), IdTy);
1192193326Sed}
1193198092Srdivackyvoid CGObjCGNU::GenerateProtocolHolderCategory(void) {
1194198092Srdivacky  // Collect information about instance methods
1195198092Srdivacky  llvm::SmallVector<Selector, 1> MethodSels;
1196198092Srdivacky  llvm::SmallVector<llvm::Constant*, 1> MethodTypes;
1197193326Sed
1198198092Srdivacky  std::vector<llvm::Constant*> Elements;
1199198092Srdivacky  const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack";
1200198092Srdivacky  const std::string CategoryName = "AnotherHack";
1201198092Srdivacky  Elements.push_back(MakeConstantString(CategoryName));
1202198092Srdivacky  Elements.push_back(MakeConstantString(ClassName));
1203198092Srdivacky  // Instance method list
1204198092Srdivacky  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1205198092Srdivacky          ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy));
1206198092Srdivacky  // Class method list
1207198092Srdivacky  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1208198092Srdivacky          ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy));
1209198092Srdivacky  // Protocol list
1210198092Srdivacky  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
1211198092Srdivacky      ExistingProtocols.size());
1212198092Srdivacky  llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext,
1213198092Srdivacky      PtrTy, //Should be a recurisve pointer, but it's always NULL here.
1214198092Srdivacky      LongTy,//FIXME: Should be size_t
1215198092Srdivacky      ProtocolArrayTy,
1216198092Srdivacky      NULL);
1217198092Srdivacky  std::vector<llvm::Constant*> ProtocolElements;
1218198092Srdivacky  for (llvm::StringMapIterator<llvm::Constant*> iter =
1219198092Srdivacky       ExistingProtocols.begin(), endIter = ExistingProtocols.end();
1220198092Srdivacky       iter != endIter ; iter++) {
1221198092Srdivacky    llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(),
1222198092Srdivacky            PtrTy);
1223198092Srdivacky    ProtocolElements.push_back(Ptr);
1224198092Srdivacky  }
1225198092Srdivacky  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1226198092Srdivacky      ProtocolElements);
1227198092Srdivacky  ProtocolElements.clear();
1228198092Srdivacky  ProtocolElements.push_back(NULLPtr);
1229198092Srdivacky  ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
1230198092Srdivacky              ExistingProtocols.size()));
1231198092Srdivacky  ProtocolElements.push_back(ProtocolArray);
1232198092Srdivacky  Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy,
1233198092Srdivacky                  ProtocolElements, ".objc_protocol_list"), PtrTy));
1234198092Srdivacky  Categories.push_back(llvm::ConstantExpr::getBitCast(
1235198092Srdivacky        MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty,
1236198092Srdivacky            PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
1237198092Srdivacky}
1238198092Srdivacky
1239193326Sedvoid CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
1240193326Sed  std::string ClassName = OCD->getClassInterface()->getNameAsString();
1241193326Sed  std::string CategoryName = OCD->getNameAsString();
1242193326Sed  // Collect information about instance methods
1243193326Sed  llvm::SmallVector<Selector, 16> InstanceMethodSels;
1244193326Sed  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
1245193326Sed  for (ObjCCategoryImplDecl::instmeth_iterator
1246195341Sed         iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end();
1247193326Sed       iter != endIter ; iter++) {
1248193326Sed    InstanceMethodSels.push_back((*iter)->getSelector());
1249193326Sed    std::string TypeStr;
1250193326Sed    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
1251198092Srdivacky    InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1252193326Sed  }
1253193326Sed
1254193326Sed  // Collect information about class methods
1255193326Sed  llvm::SmallVector<Selector, 16> ClassMethodSels;
1256193326Sed  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
1257198092Srdivacky  for (ObjCCategoryImplDecl::classmeth_iterator
1258195341Sed         iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end();
1259193326Sed       iter != endIter ; iter++) {
1260193326Sed    ClassMethodSels.push_back((*iter)->getSelector());
1261193326Sed    std::string TypeStr;
1262193326Sed    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
1263198092Srdivacky    ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1264193326Sed  }
1265193326Sed
1266193326Sed  // Collect the names of referenced protocols
1267193326Sed  llvm::SmallVector<std::string, 16> Protocols;
1268205219Srdivacky  const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl();
1269205219Srdivacky  const ObjCList<ObjCProtocolDecl> &Protos = CatDecl->getReferencedProtocols();
1270193326Sed  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
1271193326Sed       E = Protos.end(); I != E; ++I)
1272193326Sed    Protocols.push_back((*I)->getNameAsString());
1273193326Sed
1274193326Sed  std::vector<llvm::Constant*> Elements;
1275193326Sed  Elements.push_back(MakeConstantString(CategoryName));
1276193326Sed  Elements.push_back(MakeConstantString(ClassName));
1277198092Srdivacky  // Instance method list
1278193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1279193326Sed          ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
1280193326Sed          false), PtrTy));
1281193326Sed  // Class method list
1282193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1283193326Sed          ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true),
1284193326Sed        PtrTy));
1285193326Sed  // Protocol list
1286193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(
1287193326Sed        GenerateProtocolList(Protocols), PtrTy));
1288193326Sed  Categories.push_back(llvm::ConstantExpr::getBitCast(
1289198092Srdivacky        MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty,
1290198092Srdivacky            PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
1291193326Sed}
1292193326Sed
1293198092Srdivackyllvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OID,
1294198092Srdivacky        llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
1295198092Srdivacky        llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) {
1296198092Srdivacky  ASTContext &Context = CGM.getContext();
1297198092Srdivacky  //
1298198092Srdivacky  // Property metadata: name, attributes, isSynthesized, setter name, setter
1299198092Srdivacky  // types, getter name, getter types.
1300198092Srdivacky  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext,
1301198092Srdivacky          PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
1302198092Srdivacky          PtrToInt8Ty, NULL);
1303198092Srdivacky  std::vector<llvm::Constant*> Properties;
1304198092Srdivacky
1305198092Srdivacky
1306198092Srdivacky  // Add all of the property methods need adding to the method list and to the
1307198092Srdivacky  // property metadata list.
1308198092Srdivacky  for (ObjCImplDecl::propimpl_iterator
1309198092Srdivacky         iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
1310198092Srdivacky       iter != endIter ; iter++) {
1311198092Srdivacky    std::vector<llvm::Constant*> Fields;
1312198092Srdivacky    ObjCPropertyDecl *property = (*iter)->getPropertyDecl();
1313204643Srdivacky    ObjCPropertyImplDecl *propertyImpl = *iter;
1314204643Srdivacky    bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
1315204643Srdivacky        ObjCPropertyImplDecl::Synthesize);
1316198092Srdivacky
1317198092Srdivacky    Fields.push_back(MakeConstantString(property->getNameAsString()));
1318198092Srdivacky    Fields.push_back(llvm::ConstantInt::get(Int8Ty,
1319198092Srdivacky                property->getPropertyAttributes()));
1320204643Srdivacky    Fields.push_back(llvm::ConstantInt::get(Int8Ty, isSynthesized));
1321198092Srdivacky    if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
1322198092Srdivacky      std::string TypeStr;
1323198092Srdivacky      Context.getObjCEncodingForMethodDecl(getter,TypeStr);
1324198092Srdivacky      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1325204643Srdivacky      if (isSynthesized) {
1326204643Srdivacky        InstanceMethodTypes.push_back(TypeEncoding);
1327204643Srdivacky        InstanceMethodSels.push_back(getter->getSelector());
1328204643Srdivacky      }
1329198092Srdivacky      Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
1330198092Srdivacky      Fields.push_back(TypeEncoding);
1331198092Srdivacky    } else {
1332198092Srdivacky      Fields.push_back(NULLPtr);
1333198092Srdivacky      Fields.push_back(NULLPtr);
1334198092Srdivacky    }
1335198092Srdivacky    if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
1336198092Srdivacky      std::string TypeStr;
1337198092Srdivacky      Context.getObjCEncodingForMethodDecl(setter,TypeStr);
1338198092Srdivacky      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1339204643Srdivacky      if (isSynthesized) {
1340204643Srdivacky        InstanceMethodTypes.push_back(TypeEncoding);
1341204643Srdivacky        InstanceMethodSels.push_back(setter->getSelector());
1342204643Srdivacky      }
1343198092Srdivacky      Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
1344198092Srdivacky      Fields.push_back(TypeEncoding);
1345198092Srdivacky    } else {
1346198092Srdivacky      Fields.push_back(NULLPtr);
1347198092Srdivacky      Fields.push_back(NULLPtr);
1348198092Srdivacky    }
1349198092Srdivacky    Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1350198092Srdivacky  }
1351198092Srdivacky  llvm::ArrayType *PropertyArrayTy =
1352198092Srdivacky      llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
1353198092Srdivacky  llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
1354198092Srdivacky          Properties);
1355198092Srdivacky  llvm::Constant* PropertyListInitFields[] =
1356198092Srdivacky    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
1357198092Srdivacky
1358198092Srdivacky  llvm::Constant *PropertyListInit =
1359198092Srdivacky      llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false);
1360198092Srdivacky  return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(), false,
1361198092Srdivacky          llvm::GlobalValue::InternalLinkage, PropertyListInit,
1362198092Srdivacky          ".objc_property_list");
1363198092Srdivacky}
1364198092Srdivacky
1365193326Sedvoid CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
1366193326Sed  ASTContext &Context = CGM.getContext();
1367193326Sed
1368193326Sed  // Get the superclass name.
1369198092Srdivacky  const ObjCInterfaceDecl * SuperClassDecl =
1370193326Sed    OID->getClassInterface()->getSuperClass();
1371193326Sed  std::string SuperClassName;
1372194613Sed  if (SuperClassDecl) {
1373193326Sed    SuperClassName = SuperClassDecl->getNameAsString();
1374194613Sed    EmitClassRef(SuperClassName);
1375194613Sed  }
1376193326Sed
1377193326Sed  // Get the class name
1378193326Sed  ObjCInterfaceDecl *ClassDecl =
1379193326Sed    const_cast<ObjCInterfaceDecl *>(OID->getClassInterface());
1380193326Sed  std::string ClassName = ClassDecl->getNameAsString();
1381194613Sed  // Emit the symbol that is used to generate linker errors if this class is
1382194613Sed  // referenced in other modules but not declared.
1383195341Sed  std::string classSymbolName = "__objc_class_name_" + ClassName;
1384198092Srdivacky  if (llvm::GlobalVariable *symbol =
1385195341Sed      TheModule.getGlobalVariable(classSymbolName)) {
1386195341Sed    symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
1387195341Sed  } else {
1388198092Srdivacky    new llvm::GlobalVariable(TheModule, LongTy, false,
1389198092Srdivacky    llvm::GlobalValue::ExternalLinkage, llvm::ConstantInt::get(LongTy, 0),
1390198092Srdivacky    classSymbolName);
1391195341Sed  }
1392198092Srdivacky
1393193326Sed  // Get the size of instances.
1394193326Sed  int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8;
1395193326Sed
1396193326Sed  // Collect information about instance variables.
1397193326Sed  llvm::SmallVector<llvm::Constant*, 16> IvarNames;
1398193326Sed  llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
1399193326Sed  llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
1400198092Srdivacky
1401198092Srdivacky  std::vector<llvm::Constant*> IvarOffsetValues;
1402198092Srdivacky
1403198092Srdivacky  int superInstanceSize = !SuperClassDecl ? 0 :
1404193326Sed    Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8;
1405193326Sed  // For non-fragile ivars, set the instance size to 0 - {the size of just this
1406193326Sed  // class}.  The runtime will then set this to the correct value on load.
1407193326Sed  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
1408193326Sed    instanceSize = 0 - (instanceSize - superInstanceSize);
1409193326Sed  }
1410207619Srdivacky
1411207619Srdivacky  // Collect declared and synthesized ivars.
1412207619Srdivacky  llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
1413207619Srdivacky  CGM.getContext().ShallowCollectObjCIvars(ClassDecl, OIvars);
1414207619Srdivacky
1415207619Srdivacky  for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
1416207619Srdivacky      ObjCIvarDecl *IVD = OIvars[i];
1417193326Sed      // Store the name
1418207619Srdivacky      IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
1419193326Sed      // Get the type encoding for this ivar
1420193326Sed      std::string TypeStr;
1421207619Srdivacky      Context.getObjCEncodingForType(IVD->getType(), TypeStr);
1422198092Srdivacky      IvarTypes.push_back(MakeConstantString(TypeStr));
1423193326Sed      // Get the offset
1424207619Srdivacky      uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1425199482Srdivacky      uint64_t Offset = BaseOffset;
1426193326Sed      if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
1427198092Srdivacky        Offset = BaseOffset - superInstanceSize;
1428193326Sed      }
1429193326Sed      IvarOffsets.push_back(
1430198092Srdivacky          llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset));
1431198092Srdivacky      IvarOffsetValues.push_back(new llvm::GlobalVariable(TheModule, IntTy,
1432198092Srdivacky          false, llvm::GlobalValue::ExternalLinkage,
1433198092Srdivacky          llvm::ConstantInt::get(IntTy, BaseOffset),
1434198092Srdivacky          "__objc_ivar_offset_value_" + ClassName +"." +
1435207619Srdivacky          IVD->getNameAsString()));
1436193326Sed  }
1437198092Srdivacky  llvm::Constant *IvarOffsetArrayInit =
1438198092Srdivacky      llvm::ConstantArray::get(llvm::ArrayType::get(PtrToIntTy,
1439198092Srdivacky                  IvarOffsetValues.size()), IvarOffsetValues);
1440198092Srdivacky  llvm::GlobalVariable *IvarOffsetArray = new llvm::GlobalVariable(TheModule,
1441198092Srdivacky          IvarOffsetArrayInit->getType(), false,
1442198092Srdivacky          llvm::GlobalValue::InternalLinkage, IvarOffsetArrayInit,
1443198092Srdivacky          ".ivar.offsets");
1444193326Sed
1445193326Sed  // Collect information about instance methods
1446193326Sed  llvm::SmallVector<Selector, 16> InstanceMethodSels;
1447193326Sed  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
1448198092Srdivacky  for (ObjCImplementationDecl::instmeth_iterator
1449195341Sed         iter = OID->instmeth_begin(), endIter = OID->instmeth_end();
1450193326Sed       iter != endIter ; iter++) {
1451193326Sed    InstanceMethodSels.push_back((*iter)->getSelector());
1452193326Sed    std::string TypeStr;
1453193326Sed    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
1454198092Srdivacky    InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1455193326Sed  }
1456193326Sed
1457198092Srdivacky  llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
1458198092Srdivacky          InstanceMethodTypes);
1459198092Srdivacky
1460198092Srdivacky
1461193326Sed  // Collect information about class methods
1462193326Sed  llvm::SmallVector<Selector, 16> ClassMethodSels;
1463193326Sed  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
1464193326Sed  for (ObjCImplementationDecl::classmeth_iterator
1465195341Sed         iter = OID->classmeth_begin(), endIter = OID->classmeth_end();
1466193326Sed       iter != endIter ; iter++) {
1467193326Sed    ClassMethodSels.push_back((*iter)->getSelector());
1468193326Sed    std::string TypeStr;
1469193326Sed    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
1470198092Srdivacky    ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1471193326Sed  }
1472193326Sed  // Collect the names of referenced protocols
1473193326Sed  llvm::SmallVector<std::string, 16> Protocols;
1474193326Sed  const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
1475193326Sed  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
1476193326Sed       E = Protos.end(); I != E; ++I)
1477193326Sed    Protocols.push_back((*I)->getNameAsString());
1478193326Sed
1479193326Sed
1480193326Sed
1481193326Sed  // Get the superclass pointer.
1482193326Sed  llvm::Constant *SuperClass;
1483193326Sed  if (!SuperClassName.empty()) {
1484193326Sed    SuperClass = MakeConstantString(SuperClassName, ".super_class_name");
1485193326Sed  } else {
1486193326Sed    SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
1487193326Sed  }
1488193326Sed  // Empty vector used to construct empty method lists
1489193326Sed  llvm::SmallVector<llvm::Constant*, 1>  empty;
1490193326Sed  // Generate the method and instance variable lists
1491193326Sed  llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
1492193326Sed      InstanceMethodSels, InstanceMethodTypes, false);
1493193326Sed  llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
1494193326Sed      ClassMethodSels, ClassMethodTypes, true);
1495193326Sed  llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
1496193326Sed      IvarOffsets);
1497198092Srdivacky  // Irrespective of whether we are compiling for a fragile or non-fragile ABI,
1498198092Srdivacky  // we emit a symbol containing the offset for each ivar in the class.  This
1499198092Srdivacky  // allows code compiled for the non-Fragile ABI to inherit from code compiled
1500198092Srdivacky  // for the legacy ABI, without causing problems.  The converse is also
1501198092Srdivacky  // possible, but causes all ivar accesses to be fragile.
1502198092Srdivacky  int i = 0;
1503198092Srdivacky  // Offset pointer for getting at the correct field in the ivar list when
1504198092Srdivacky  // setting up the alias.  These are: The base address for the global, the
1505198092Srdivacky  // ivar array (second field), the ivar in this list (set for each ivar), and
1506198092Srdivacky  // the offset (third field in ivar structure)
1507198092Srdivacky  const llvm::Type *IndexTy = llvm::Type::getInt32Ty(VMContext);
1508198092Srdivacky  llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
1509198092Srdivacky      llvm::ConstantInt::get(IndexTy, 1), 0,
1510198092Srdivacky      llvm::ConstantInt::get(IndexTy, 2) };
1511198092Srdivacky
1512198092Srdivacky  for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
1513198092Srdivacky      endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
1514198092Srdivacky      const std::string Name = "__objc_ivar_offset_" + ClassName + '.'
1515198092Srdivacky          +(*iter)->getNameAsString();
1516198092Srdivacky      offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i++);
1517198092Srdivacky      // Get the correct ivar field
1518198092Srdivacky      llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
1519198092Srdivacky              IvarList, offsetPointerIndexes, 4);
1520198092Srdivacky      // Get the existing alias, if one exists.
1521198092Srdivacky      llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
1522198092Srdivacky      if (offset) {
1523198092Srdivacky          offset->setInitializer(offsetValue);
1524198092Srdivacky          // If this is the real definition, change its linkage type so that
1525198092Srdivacky          // different modules will use this one, rather than their private
1526198092Srdivacky          // copy.
1527198092Srdivacky          offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
1528198092Srdivacky      } else {
1529198092Srdivacky          // Add a new alias if there isn't one already.
1530198092Srdivacky          offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(),
1531198092Srdivacky                  false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
1532198092Srdivacky      }
1533198092Srdivacky  }
1534193326Sed  //Generate metaclass for class methods
1535193326Sed  llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
1536199482Srdivacky      NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList(
1537207619Srdivacky        empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr, NULLPtr, true);
1538193326Sed
1539193326Sed  // Generate the class structure
1540193326Sed  llvm::Constant *ClassStruct =
1541198092Srdivacky    GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L,
1542193326Sed                           ClassName.c_str(), 0,
1543193326Sed      llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
1544198092Srdivacky      MethodList, GenerateProtocolList(Protocols), IvarOffsetArray,
1545198092Srdivacky      Properties);
1546193326Sed
1547193326Sed  // Resolve the class aliases, if they exist.
1548193326Sed  if (ClassPtrAlias) {
1549193326Sed    ClassPtrAlias->setAliasee(
1550193326Sed        llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
1551193326Sed    ClassPtrAlias = 0;
1552193326Sed  }
1553193326Sed  if (MetaClassPtrAlias) {
1554193326Sed    MetaClassPtrAlias->setAliasee(
1555193326Sed        llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
1556193326Sed    MetaClassPtrAlias = 0;
1557193326Sed  }
1558193326Sed
1559193326Sed  // Add class structure to list to be added to the symtab later
1560193326Sed  ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
1561193326Sed  Classes.push_back(ClassStruct);
1562193326Sed}
1563193326Sed
1564195099Sed
1565198092Srdivackyllvm::Function *CGObjCGNU::ModuleInitFunction() {
1566193326Sed  // Only emit an ObjC load function if no Objective-C stuff has been called
1567193326Sed  if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
1568193326Sed      ExistingProtocols.empty() && TypedSelectors.empty() &&
1569193326Sed      UntypedSelectors.empty())
1570193326Sed    return NULL;
1571193326Sed
1572198092Srdivacky  // Add all referenced protocols to a category.
1573198092Srdivacky  GenerateProtocolHolderCategory();
1574198092Srdivacky
1575193326Sed  const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
1576193326Sed          SelectorTy->getElementType());
1577193326Sed  const llvm::Type *SelStructPtrTy = SelectorTy;
1578193326Sed  bool isSelOpaque = false;
1579193326Sed  if (SelStructTy == 0) {
1580198092Srdivacky    SelStructTy = llvm::StructType::get(VMContext, PtrToInt8Ty,
1581198092Srdivacky                                        PtrToInt8Ty, NULL);
1582193326Sed    SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
1583193326Sed    isSelOpaque = true;
1584193326Sed  }
1585193326Sed
1586193326Sed  // Name the ObjC types to make the IR a bit easier to read
1587193326Sed  TheModule.addTypeName(".objc_selector", SelStructPtrTy);
1588193326Sed  TheModule.addTypeName(".objc_id", IdTy);
1589193326Sed  TheModule.addTypeName(".objc_imp", IMPTy);
1590193326Sed
1591193326Sed  std::vector<llvm::Constant*> Elements;
1592193326Sed  llvm::Constant *Statics = NULLPtr;
1593193326Sed  // Generate statics list:
1594193326Sed  if (ConstantStrings.size()) {
1595193326Sed    llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
1596193326Sed        ConstantStrings.size() + 1);
1597193326Sed    ConstantStrings.push_back(NULLPtr);
1598198092Srdivacky
1599199990Srdivacky    llvm::StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass;
1600199990Srdivacky    if (StringClass.empty()) StringClass = "NXConstantString";
1601198092Srdivacky    Elements.push_back(MakeConstantString(StringClass,
1602198092Srdivacky                ".objc_static_class_name"));
1603193326Sed    Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
1604193326Sed       ConstantStrings));
1605198092Srdivacky    llvm::StructType *StaticsListTy =
1606198092Srdivacky      llvm::StructType::get(VMContext, PtrToInt8Ty, StaticsArrayTy, NULL);
1607198092Srdivacky    llvm::Type *StaticsListPtrTy =
1608198092Srdivacky      llvm::PointerType::getUnqual(StaticsListTy);
1609193326Sed    Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics");
1610193326Sed    llvm::ArrayType *StaticsListArrayTy =
1611193326Sed      llvm::ArrayType::get(StaticsListPtrTy, 2);
1612193326Sed    Elements.clear();
1613193326Sed    Elements.push_back(Statics);
1614193326Sed    Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
1615193326Sed    Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr");
1616193326Sed    Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
1617193326Sed  }
1618193326Sed  // Array of classes, categories, and constant objects
1619193326Sed  llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
1620193326Sed      Classes.size() + Categories.size()  + 2);
1621198092Srdivacky  llvm::StructType *SymTabTy = llvm::StructType::get(VMContext,
1622198092Srdivacky                                                     LongTy, SelStructPtrTy,
1623198092Srdivacky                                                     llvm::Type::getInt16Ty(VMContext),
1624198092Srdivacky                                                     llvm::Type::getInt16Ty(VMContext),
1625193326Sed                                                     ClassListTy, NULL);
1626193326Sed
1627193326Sed  Elements.clear();
1628193326Sed  // Pointer to an array of selectors used in this module.
1629193326Sed  std::vector<llvm::Constant*> Selectors;
1630193326Sed  for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
1631193326Sed     iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end();
1632193326Sed     iter != iterEnd ; ++iter) {
1633198092Srdivacky    Elements.push_back(ExportUniqueString(iter->first.first, ".objc_sel_name"));
1634193326Sed    Elements.push_back(MakeConstantString(iter->first.second,
1635193326Sed                                          ".objc_sel_types"));
1636193326Sed    Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
1637193326Sed    Elements.clear();
1638193326Sed  }
1639193326Sed  for (llvm::StringMap<llvm::GlobalAlias*>::iterator
1640193326Sed      iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
1641193326Sed      iter != iterEnd; ++iter) {
1642193326Sed    Elements.push_back(
1643198092Srdivacky        ExportUniqueString(iter->getKeyData(), ".objc_sel_name"));
1644193326Sed    Elements.push_back(NULLPtr);
1645193326Sed    Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
1646193326Sed    Elements.clear();
1647193326Sed  }
1648193326Sed  Elements.push_back(NULLPtr);
1649193326Sed  Elements.push_back(NULLPtr);
1650193326Sed  Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
1651193326Sed  Elements.clear();
1652193326Sed  // Number of static selectors
1653193326Sed  Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() ));
1654193326Sed  llvm::Constant *SelectorList = MakeGlobal(
1655193326Sed          llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors,
1656193326Sed          ".objc_selector_list");
1657198092Srdivacky  Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
1658193326Sed    SelStructPtrTy));
1659193326Sed
1660193326Sed  // Now that all of the static selectors exist, create pointers to them.
1661193326Sed  int index = 0;
1662193326Sed  for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
1663193326Sed     iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end();
1664193326Sed     iter != iterEnd; ++iter) {
1665193326Sed    llvm::Constant *Idxs[] = {Zeros[0],
1666198092Srdivacky      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]};
1667198092Srdivacky    llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy,
1668193326Sed        true, llvm::GlobalValue::InternalLinkage,
1669193326Sed        llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
1670198092Srdivacky        ".objc_sel_ptr");
1671193326Sed    // If selectors are defined as an opaque type, cast the pointer to this
1672193326Sed    // type.
1673193326Sed    if (isSelOpaque) {
1674193326Sed      SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
1675193326Sed        llvm::PointerType::getUnqual(SelectorTy));
1676193326Sed    }
1677193326Sed    (*iter).second->setAliasee(SelPtr);
1678193326Sed  }
1679193326Sed  for (llvm::StringMap<llvm::GlobalAlias*>::iterator
1680193326Sed      iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
1681193326Sed      iter != iterEnd; iter++) {
1682193326Sed    llvm::Constant *Idxs[] = {Zeros[0],
1683198092Srdivacky      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]};
1684198092Srdivacky    llvm::Constant *SelPtr = new llvm::GlobalVariable
1685198092Srdivacky      (TheModule, SelStructPtrTy,
1686198092Srdivacky       true, llvm::GlobalValue::InternalLinkage,
1687198092Srdivacky       llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
1688198092Srdivacky       ".objc_sel_ptr");
1689193326Sed    // If selectors are defined as an opaque type, cast the pointer to this
1690193326Sed    // type.
1691193326Sed    if (isSelOpaque) {
1692193326Sed      SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
1693193326Sed        llvm::PointerType::getUnqual(SelectorTy));
1694193326Sed    }
1695193326Sed    (*iter).second->setAliasee(SelPtr);
1696193326Sed  }
1697193326Sed  // Number of classes defined.
1698198092Srdivacky  Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
1699193326Sed        Classes.size()));
1700193326Sed  // Number of categories defined
1701198092Srdivacky  Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
1702193326Sed        Categories.size()));
1703193326Sed  // Create an array of classes, then categories, then static object instances
1704193326Sed  Classes.insert(Classes.end(), Categories.begin(), Categories.end());
1705193326Sed  //  NULL-terminated list of static object instances (mainly constant strings)
1706193326Sed  Classes.push_back(Statics);
1707193326Sed  Classes.push_back(NULLPtr);
1708193326Sed  llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
1709193326Sed  Elements.push_back(ClassList);
1710198092Srdivacky  // Construct the symbol table
1711193326Sed  llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements);
1712193326Sed
1713193326Sed  // The symbol table is contained in a module which has some version-checking
1714193326Sed  // constants
1715198092Srdivacky  llvm::StructType * ModuleTy = llvm::StructType::get(VMContext, LongTy, LongTy,
1716193326Sed      PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL);
1717193326Sed  Elements.clear();
1718193326Sed  // Runtime version used for compatibility checking.
1719193326Sed  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
1720198092Srdivacky    Elements.push_back(llvm::ConstantInt::get(LongTy,
1721193326Sed        NonFragileRuntimeVersion));
1722193326Sed  } else {
1723193326Sed    Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
1724193326Sed  }
1725193326Sed  // sizeof(ModuleTy)
1726203955Srdivacky  llvm::TargetData td(&TheModule);
1727198092Srdivacky  Elements.push_back(llvm::ConstantInt::get(LongTy,
1728198092Srdivacky                     td.getTypeSizeInBits(ModuleTy)/8));
1729193326Sed  //FIXME: Should be the path to the file where this module was declared
1730193326Sed  Elements.push_back(NULLPtr);
1731193326Sed  Elements.push_back(SymTab);
1732193326Sed  llvm::Value *Module = MakeGlobal(ModuleTy, Elements);
1733193326Sed
1734193326Sed  // Create the load function calling the runtime entry point with the module
1735193326Sed  // structure
1736193326Sed  llvm::Function * LoadFunction = llvm::Function::Create(
1737198092Srdivacky      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
1738193326Sed      llvm::GlobalValue::InternalLinkage, ".objc_load_function",
1739193326Sed      &TheModule);
1740198092Srdivacky  llvm::BasicBlock *EntryBB =
1741198092Srdivacky      llvm::BasicBlock::Create(VMContext, "entry", LoadFunction);
1742198092Srdivacky  CGBuilderTy Builder(VMContext);
1743193326Sed  Builder.SetInsertPoint(EntryBB);
1744193326Sed
1745193326Sed  std::vector<const llvm::Type*> Params(1,
1746193326Sed      llvm::PointerType::getUnqual(ModuleTy));
1747193326Sed  llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1748198092Srdivacky        llvm::Type::getVoidTy(VMContext), Params, true), "__objc_exec_class");
1749193326Sed  Builder.CreateCall(Register, Module);
1750193326Sed  Builder.CreateRetVoid();
1751193326Sed
1752193326Sed  return LoadFunction;
1753193326Sed}
1754193326Sed
1755193326Sedllvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
1756198092Srdivacky                                          const ObjCContainerDecl *CD) {
1757198092Srdivacky  const ObjCCategoryImplDecl *OCD =
1758193326Sed    dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext());
1759193326Sed  std::string CategoryName = OCD ? OCD->getNameAsString() : "";
1760205408Srdivacky  std::string ClassName = CD->getName();
1761193326Sed  std::string MethodName = OMD->getSelector().getAsString();
1762193326Sed  bool isClassMethod = !OMD->isInstanceMethod();
1763193326Sed
1764193326Sed  CodeGenTypes &Types = CGM.getTypes();
1765198092Srdivacky  const llvm::FunctionType *MethodTy =
1766193326Sed    Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
1767193326Sed  std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
1768193326Sed      MethodName, isClassMethod);
1769193326Sed
1770198092Srdivacky  llvm::Function *Method
1771198092Srdivacky    = llvm::Function::Create(MethodTy,
1772198092Srdivacky                             llvm::GlobalValue::InternalLinkage,
1773198092Srdivacky                             FunctionName,
1774198092Srdivacky                             &TheModule);
1775193326Sed  return Method;
1776193326Sed}
1777193326Sed
1778193326Sedllvm::Function *CGObjCGNU::GetPropertyGetFunction() {
1779198092Srdivacky  std::vector<const llvm::Type*> Params;
1780198092Srdivacky  const llvm::Type *BoolTy =
1781198092Srdivacky    CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
1782198092Srdivacky  Params.push_back(IdTy);
1783198092Srdivacky  Params.push_back(SelectorTy);
1784207619Srdivacky  Params.push_back(IntTy);
1785198092Srdivacky  Params.push_back(BoolTy);
1786207619Srdivacky  // void objc_getProperty (id, SEL, int, bool)
1787198092Srdivacky  const llvm::FunctionType *FTy =
1788198092Srdivacky    llvm::FunctionType::get(IdTy, Params, false);
1789198092Srdivacky  return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy,
1790198092Srdivacky                                                        "objc_getProperty"));
1791193326Sed}
1792193326Sed
1793193326Sedllvm::Function *CGObjCGNU::GetPropertySetFunction() {
1794198092Srdivacky  std::vector<const llvm::Type*> Params;
1795198092Srdivacky  const llvm::Type *BoolTy =
1796198092Srdivacky    CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
1797198092Srdivacky  Params.push_back(IdTy);
1798198092Srdivacky  Params.push_back(SelectorTy);
1799207619Srdivacky  Params.push_back(IntTy);
1800198092Srdivacky  Params.push_back(IdTy);
1801198092Srdivacky  Params.push_back(BoolTy);
1802198092Srdivacky  Params.push_back(BoolTy);
1803207619Srdivacky  // void objc_setProperty (id, SEL, int, id, bool, bool)
1804198092Srdivacky  const llvm::FunctionType *FTy =
1805198092Srdivacky    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
1806198092Srdivacky  return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy,
1807198092Srdivacky                                                        "objc_setProperty"));
1808193326Sed}
1809193326Sed
1810207619Srdivacky// FIXME. Implement this.
1811207619Srdivackyllvm::Function *CGObjCGNU::GetCopyStructFunction() {
1812207619Srdivacky  return 0;
1813207619Srdivacky}
1814207619Srdivacky
1815198092Srdivackyllvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
1816198092Srdivacky  CodeGen::CodeGenTypes &Types = CGM.getTypes();
1817198092Srdivacky  ASTContext &Ctx = CGM.getContext();
1818198092Srdivacky  // void objc_enumerationMutation (id)
1819204643Srdivacky  llvm::SmallVector<CanQualType,1> Params;
1820198092Srdivacky  Params.push_back(ASTIdTy);
1821198092Srdivacky  const llvm::FunctionType *FTy =
1822203955Srdivacky    Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
1823206084Srdivacky                                              FunctionType::ExtInfo()), false);
1824198092Srdivacky  return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
1825193326Sed}
1826193326Sed
1827193326Sedvoid CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1828193326Sed                                          const Stmt &S) {
1829193326Sed  // Pointer to the personality function
1830193326Sed  llvm::Constant *Personality =
1831198092Srdivacky    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
1832195341Sed          true),
1833193326Sed        "__gnu_objc_personality_v0");
1834193326Sed  Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy);
1835193326Sed  std::vector<const llvm::Type*> Params;
1836193326Sed  Params.push_back(PtrTy);
1837193326Sed  llvm::Value *RethrowFn =
1838198092Srdivacky    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
1839202379Srdivacky          Params, false), "_Unwind_Resume");
1840193326Sed
1841193326Sed  bool isTry = isa<ObjCAtTryStmt>(S);
1842193326Sed  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
1843193326Sed  llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
1844193326Sed  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
1845193326Sed  llvm::BasicBlock *CatchInCatch = CGF.createBasicBlock("catch.rethrow");
1846193326Sed  llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
1847193326Sed  llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
1848193326Sed  llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
1849193326Sed
1850201361Srdivacky  // @synchronized()
1851193326Sed  if (!isTry) {
1852193326Sed    std::vector<const llvm::Type*> Args(1, IdTy);
1853193326Sed    llvm::FunctionType *FTy =
1854198092Srdivacky      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
1855193326Sed    llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
1856198092Srdivacky    llvm::Value *SyncArg =
1857193326Sed      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
1858193326Sed    SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
1859193326Sed    CGF.Builder.CreateCall(SyncEnter, SyncArg);
1860193326Sed  }
1861193326Sed
1862193326Sed
1863193326Sed  // Push an EH context entry, used for handling rethrows and jumps
1864193326Sed  // through finally.
1865193326Sed  CGF.PushCleanupBlock(FinallyBlock);
1866193326Sed
1867193326Sed  // Emit the statements in the @try {} block
1868193326Sed  CGF.setInvokeDest(TryHandler);
1869193326Sed
1870193326Sed  CGF.EmitBlock(TryBlock);
1871198092Srdivacky  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
1872193326Sed                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
1873193326Sed
1874193326Sed  // Jump to @finally if there is no exception
1875193326Sed  CGF.EmitBranchThroughCleanup(FinallyEnd);
1876193326Sed
1877193326Sed  // Emit the handlers
1878193326Sed  CGF.EmitBlock(TryHandler);
1879193326Sed
1880193326Sed  // Get the correct versions of the exception handling intrinsics
1881198092Srdivacky  llvm::Value *llvm_eh_exception =
1882193326Sed    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
1883198092Srdivacky  llvm::Value *llvm_eh_selector =
1884198092Srdivacky    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
1885198092Srdivacky  llvm::Value *llvm_eh_typeid_for =
1886198092Srdivacky    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
1887193326Sed
1888193326Sed  // Exception object
1889193326Sed  llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
1890193326Sed  llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow");
1891193326Sed
1892193326Sed  llvm::SmallVector<llvm::Value*, 8> ESelArgs;
1893207619Srdivacky  llvm::SmallVector<std::pair<const VarDecl*, const Stmt*>, 8> Handlers;
1894193326Sed
1895193326Sed  ESelArgs.push_back(Exc);
1896193326Sed  ESelArgs.push_back(Personality);
1897193326Sed
1898193326Sed  bool HasCatchAll = false;
1899193326Sed  // Only @try blocks are allowed @catch blocks, but both can have @finally
1900193326Sed  if (isTry) {
1901207619Srdivacky    if (cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
1902207619Srdivacky      const ObjCAtTryStmt &AtTry = cast<ObjCAtTryStmt>(S);
1903193326Sed      CGF.setInvokeDest(CatchInCatch);
1904193326Sed
1905207619Srdivacky      for (unsigned I = 0, N = AtTry.getNumCatchStmts(); I != N; ++I) {
1906207619Srdivacky        const ObjCAtCatchStmt *CatchStmt = AtTry.getCatchStmt(I);
1907207619Srdivacky        const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
1908198092Srdivacky        Handlers.push_back(std::make_pair(CatchDecl,
1909198092Srdivacky                                          CatchStmt->getCatchBody()));
1910193326Sed
1911193326Sed        // @catch() and @catch(id) both catch any ObjC exception
1912198092Srdivacky        if (!CatchDecl || CatchDecl->getType()->isObjCIdType()
1913193326Sed            || CatchDecl->getType()->isObjCQualifiedIdType()) {
1914193326Sed          // Use i8* null here to signal this is a catch all, not a cleanup.
1915193326Sed          ESelArgs.push_back(NULLPtr);
1916193326Sed          HasCatchAll = true;
1917193326Sed          // No further catches after this one will ever by reached
1918193326Sed          break;
1919198092Srdivacky        }
1920193326Sed
1921193326Sed        // All other types should be Objective-C interface pointer types.
1922198092Srdivacky        const ObjCObjectPointerType *OPT =
1923198092Srdivacky          CatchDecl->getType()->getAs<ObjCObjectPointerType>();
1924198092Srdivacky        assert(OPT && "Invalid @catch type.");
1925198092Srdivacky        const ObjCInterfaceType *IT =
1926198092Srdivacky          OPT->getPointeeType()->getAs<ObjCInterfaceType>();
1927193326Sed        assert(IT && "Invalid @catch type.");
1928193326Sed        llvm::Value *EHType =
1929193326Sed          MakeConstantString(IT->getDecl()->getNameAsString());
1930193326Sed        ESelArgs.push_back(EHType);
1931193326Sed      }
1932193326Sed    }
1933193326Sed  }
1934193326Sed
1935193326Sed  // We use a cleanup unless there was already a catch all.
1936193326Sed  if (!HasCatchAll) {
1937198092Srdivacky    ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
1938193326Sed    Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0));
1939193326Sed  }
1940193326Sed
1941193326Sed  // Find which handler was matched.
1942193326Sed  llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector,
1943193326Sed      ESelArgs.begin(), ESelArgs.end(), "selector");
1944193326Sed
1945193326Sed  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
1946207619Srdivacky    const VarDecl *CatchParam = Handlers[i].first;
1947193326Sed    const Stmt *CatchBody = Handlers[i].second;
1948193326Sed
1949193326Sed    llvm::BasicBlock *Next = 0;
1950193326Sed
1951193326Sed    // The last handler always matches.
1952193326Sed    if (i + 1 != e) {
1953193326Sed      assert(CatchParam && "Only last handler can be a catch all.");
1954193326Sed
1955193326Sed      // Test whether this block matches the type for the selector and branch
1956193326Sed      // to Match if it does, or to the next BB if it doesn't.
1957193326Sed      llvm::BasicBlock *Match = CGF.createBasicBlock("match");
1958193326Sed      Next = CGF.createBasicBlock("catch.next");
1959193326Sed      llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for,
1960193326Sed          CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy));
1961193326Sed      CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match,
1962193326Sed          Next);
1963193326Sed
1964193326Sed      CGF.EmitBlock(Match);
1965193326Sed    }
1966198092Srdivacky
1967193326Sed    if (CatchBody) {
1968193326Sed      llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc,
1969193326Sed          CGF.ConvertType(CatchParam->getType()));
1970198092Srdivacky
1971193326Sed      // Bind the catch parameter if it exists.
1972193326Sed      if (CatchParam) {
1973193326Sed        // CatchParam is a ParmVarDecl because of the grammar
1974193326Sed        // construction used to handle this, but for codegen purposes
1975193326Sed        // we treat this as a local decl.
1976193326Sed        CGF.EmitLocalBlockVarDecl(*CatchParam);
1977193326Sed        CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam));
1978193326Sed      }
1979193326Sed
1980193326Sed      CGF.ObjCEHValueStack.push_back(ExcObject);
1981193326Sed      CGF.EmitStmt(CatchBody);
1982193326Sed      CGF.ObjCEHValueStack.pop_back();
1983193326Sed
1984193326Sed      CGF.EmitBranchThroughCleanup(FinallyEnd);
1985193326Sed
1986193326Sed      if (Next)
1987193326Sed        CGF.EmitBlock(Next);
1988193326Sed    } else {
1989193326Sed      assert(!Next && "catchup should be last handler.");
1990193326Sed
1991193326Sed      CGF.Builder.CreateStore(Exc, RethrowPtr);
1992193326Sed      CGF.EmitBranchThroughCleanup(FinallyRethrow);
1993193326Sed    }
1994193326Sed  }
1995193326Sed  // The @finally block is a secondary landing pad for any exceptions thrown in
1996193326Sed  // @catch() blocks
1997193326Sed  CGF.EmitBlock(CatchInCatch);
1998193326Sed  Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
1999193326Sed  ESelArgs.clear();
2000193326Sed  ESelArgs.push_back(Exc);
2001193326Sed  ESelArgs.push_back(Personality);
2002201361Srdivacky  // If there is a @catch or @finally clause in outside of this one then we
2003201361Srdivacky  // need to make sure that we catch and rethrow it.
2004201361Srdivacky  if (PrevLandingPad) {
2005201361Srdivacky    ESelArgs.push_back(NULLPtr);
2006201361Srdivacky  } else {
2007201361Srdivacky    ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
2008201361Srdivacky  }
2009193326Sed  CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(),
2010193326Sed      "selector");
2011193326Sed  CGF.Builder.CreateCall(llvm_eh_typeid_for,
2012193326Sed      CGF.Builder.CreateIntToPtr(ESelArgs[2], PtrTy));
2013193326Sed  CGF.Builder.CreateStore(Exc, RethrowPtr);
2014193326Sed  CGF.EmitBranchThroughCleanup(FinallyRethrow);
2015193326Sed
2016193326Sed  CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
2017193326Sed
2018193326Sed  CGF.setInvokeDest(PrevLandingPad);
2019193326Sed
2020193326Sed  CGF.EmitBlock(FinallyBlock);
2021193326Sed
2022193326Sed
2023193326Sed  if (isTry) {
2024198092Srdivacky    if (const ObjCAtFinallyStmt* FinallyStmt =
2025193326Sed        cast<ObjCAtTryStmt>(S).getFinallyStmt())
2026193326Sed      CGF.EmitStmt(FinallyStmt->getFinallyBody());
2027193326Sed  } else {
2028193326Sed    // Emit 'objc_sync_exit(expr)' as finally's sole statement for
2029193326Sed    // @synchronized.
2030193326Sed    std::vector<const llvm::Type*> Args(1, IdTy);
2031193326Sed    llvm::FunctionType *FTy =
2032198092Srdivacky      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
2033193326Sed    llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
2034198092Srdivacky    llvm::Value *SyncArg =
2035193326Sed      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
2036193326Sed    SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
2037193326Sed    CGF.Builder.CreateCall(SyncExit, SyncArg);
2038193326Sed  }
2039193326Sed
2040193326Sed  if (Info.SwitchBlock)
2041193326Sed    CGF.EmitBlock(Info.SwitchBlock);
2042193326Sed  if (Info.EndBlock)
2043193326Sed    CGF.EmitBlock(Info.EndBlock);
2044193326Sed
2045193326Sed  // Branch around the rethrow code.
2046193326Sed  CGF.EmitBranch(FinallyEnd);
2047193326Sed
2048193326Sed  CGF.EmitBlock(FinallyRethrow);
2049198092Srdivacky
2050201361Srdivacky  llvm::Value *ExceptionObject = CGF.Builder.CreateLoad(RethrowPtr);
2051201361Srdivacky  llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
2052201361Srdivacky  if (!UnwindBB) {
2053201361Srdivacky    CGF.Builder.CreateCall(RethrowFn, ExceptionObject);
2054201361Srdivacky    // Exception always thrown, next instruction is never reached.
2055201361Srdivacky    CGF.Builder.CreateUnreachable();
2056201361Srdivacky  } else {
2057201361Srdivacky    // If there is a @catch block outside this scope, we invoke instead of
2058201361Srdivacky    // calling because we may return to this function.  This is very slow, but
2059201361Srdivacky    // some people still do it.  It would be nice to add an optimised path for
2060201361Srdivacky    // this.
2061201361Srdivacky    CGF.Builder.CreateInvoke(RethrowFn, UnwindBB, UnwindBB, &ExceptionObject,
2062201361Srdivacky        &ExceptionObject+1);
2063201361Srdivacky  }
2064201361Srdivacky
2065193326Sed  CGF.EmitBlock(FinallyEnd);
2066193326Sed}
2067193326Sed
2068193326Sedvoid CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
2069193326Sed                              const ObjCAtThrowStmt &S) {
2070193326Sed  llvm::Value *ExceptionAsObject;
2071193326Sed
2072193326Sed  std::vector<const llvm::Type*> Args(1, IdTy);
2073193326Sed  llvm::FunctionType *FTy =
2074198092Srdivacky    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
2075198092Srdivacky  llvm::Value *ThrowFn =
2076193326Sed    CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
2077198092Srdivacky
2078193326Sed  if (const Expr *ThrowExpr = S.getThrowExpr()) {
2079193326Sed    llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
2080193326Sed    ExceptionAsObject = Exception;
2081193326Sed  } else {
2082198092Srdivacky    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
2083193326Sed           "Unexpected rethrow outside @catch block.");
2084193326Sed    ExceptionAsObject = CGF.ObjCEHValueStack.back();
2085193326Sed  }
2086193326Sed  ExceptionAsObject =
2087193326Sed      CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp");
2088198092Srdivacky
2089193326Sed  // Note: This may have to be an invoke, if we want to support constructs like:
2090193326Sed  // @try {
2091193326Sed  //  @throw(obj);
2092193326Sed  // }
2093193326Sed  // @catch(id) ...
2094193326Sed  //
2095193326Sed  // This is effectively turning @throw into an incredibly-expensive goto, but
2096193326Sed  // it may happen as a result of inlining followed by missed optimizations, or
2097193326Sed  // as a result of stupidity.
2098193326Sed  llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
2099193326Sed  if (!UnwindBB) {
2100193326Sed    CGF.Builder.CreateCall(ThrowFn, ExceptionAsObject);
2101193326Sed    CGF.Builder.CreateUnreachable();
2102193326Sed  } else {
2103193326Sed    CGF.Builder.CreateInvoke(ThrowFn, UnwindBB, UnwindBB, &ExceptionAsObject,
2104193326Sed        &ExceptionAsObject+1);
2105193326Sed  }
2106193326Sed  // Clear the insertion point to indicate we are in unreachable code.
2107193326Sed  CGF.Builder.ClearInsertionPoint();
2108193326Sed}
2109193326Sed
2110193326Sedllvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
2111198092Srdivacky                                          llvm::Value *AddrWeakObj) {
2112203955Srdivacky  CGBuilderTy B = CGF.Builder;
2113203955Srdivacky  AddrWeakObj = EnforceType(B, AddrWeakObj, IdTy);
2114203955Srdivacky  return B.CreateCall(WeakReadFn, AddrWeakObj);
2115193326Sed}
2116193326Sed
2117193326Sedvoid CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
2118198092Srdivacky                                   llvm::Value *src, llvm::Value *dst) {
2119203955Srdivacky  CGBuilderTy B = CGF.Builder;
2120203955Srdivacky  src = EnforceType(B, src, IdTy);
2121203955Srdivacky  dst = EnforceType(B, dst, PtrToIdTy);
2122203955Srdivacky  B.CreateCall2(WeakAssignFn, src, dst);
2123193326Sed}
2124193326Sed
2125193326Sedvoid CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
2126198092Srdivacky                                     llvm::Value *src, llvm::Value *dst) {
2127203955Srdivacky  CGBuilderTy B = CGF.Builder;
2128203955Srdivacky  src = EnforceType(B, src, IdTy);
2129203955Srdivacky  dst = EnforceType(B, dst, PtrToIdTy);
2130203955Srdivacky  B.CreateCall2(GlobalAssignFn, src, dst);
2131193326Sed}
2132193326Sed
2133193326Sedvoid CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
2134198092Srdivacky                                   llvm::Value *src, llvm::Value *dst,
2135198092Srdivacky                                   llvm::Value *ivarOffset) {
2136203955Srdivacky  CGBuilderTy B = CGF.Builder;
2137203955Srdivacky  src = EnforceType(B, src, IdTy);
2138203955Srdivacky  dst = EnforceType(B, dst, PtrToIdTy);
2139203955Srdivacky  B.CreateCall3(IvarAssignFn, src, dst, ivarOffset);
2140193326Sed}
2141193326Sed
2142193326Sedvoid CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
2143198092Srdivacky                                         llvm::Value *src, llvm::Value *dst) {
2144203955Srdivacky  CGBuilderTy B = CGF.Builder;
2145203955Srdivacky  src = EnforceType(B, src, IdTy);
2146203955Srdivacky  dst = EnforceType(B, dst, PtrToIdTy);
2147203955Srdivacky  B.CreateCall2(StrongCastAssignFn, src, dst);
2148193326Sed}
2149193326Sed
2150198092Srdivackyvoid CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
2151198092Srdivacky                                         llvm::Value *DestPtr,
2152198092Srdivacky                                         llvm::Value *SrcPtr,
2153198092Srdivacky                                         QualType Ty) {
2154203955Srdivacky  CGBuilderTy B = CGF.Builder;
2155203955Srdivacky  DestPtr = EnforceType(B, DestPtr, IdTy);
2156203955Srdivacky  SrcPtr = EnforceType(B, SrcPtr, PtrToIdTy);
2157203955Srdivacky
2158203955Srdivacky  std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
2159203955Srdivacky  unsigned long size = TypeInfo.first/8;
2160203955Srdivacky  // FIXME: size_t
2161203955Srdivacky  llvm::Value *N = llvm::ConstantInt::get(LongTy, size);
2162203955Srdivacky
2163203955Srdivacky  B.CreateCall3(MemMoveFn, DestPtr, SrcPtr, N);
2164198092Srdivacky}
2165198092Srdivacky
2166193326Sedllvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
2167193326Sed                              const ObjCInterfaceDecl *ID,
2168193326Sed                              const ObjCIvarDecl *Ivar) {
2169193326Sed  const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
2170193326Sed    + '.' + Ivar->getNameAsString();
2171193326Sed  // Emit the variable and initialize it with what we think the correct value
2172193326Sed  // is.  This allows code compiled with non-fragile ivars to work correctly
2173193326Sed  // when linked against code which isn't (most of the time).
2174198092Srdivacky  llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
2175198092Srdivacky  if (!IvarOffsetPointer) {
2176207619Srdivacky    uint64_t Offset;
2177207619Srdivacky    if (ObjCImplementationDecl *OID =
2178207619Srdivacky            CGM.getContext().getObjCImplementation(
2179207619Srdivacky              const_cast<ObjCInterfaceDecl *>(ID)))
2180207619Srdivacky      Offset = ComputeIvarBaseOffset(CGM, OID, Ivar);
2181207619Srdivacky    else
2182207619Srdivacky      Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
2183207619Srdivacky
2184193326Sed    llvm::ConstantInt *OffsetGuess =
2185202379Srdivacky      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset, "ivar");
2186198092Srdivacky    // Don't emit the guess in non-PIC code because the linker will not be able
2187198092Srdivacky    // to replace it with the real version for a library.  In non-PIC code you
2188198092Srdivacky    // must compile with the fragile ABI if you want to use ivars from a
2189198092Srdivacky    // GCC-compiled class.
2190198092Srdivacky    if (CGM.getLangOptions().PICLevel) {
2191198092Srdivacky      llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule,
2192198092Srdivacky            llvm::Type::getInt32Ty(VMContext), false,
2193198092Srdivacky            llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess");
2194198092Srdivacky      IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
2195198092Srdivacky            IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage,
2196198092Srdivacky            IvarOffsetGV, Name);
2197198092Srdivacky    } else {
2198198092Srdivacky      IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
2199198092Srdivacky              llvm::Type::getInt32PtrTy(VMContext), false,
2200198092Srdivacky              llvm::GlobalValue::ExternalLinkage, 0, Name);
2201198092Srdivacky    }
2202193326Sed  }
2203198092Srdivacky  return IvarOffsetPointer;
2204193326Sed}
2205193326Sed
2206193326SedLValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
2207193326Sed                                       QualType ObjectTy,
2208193326Sed                                       llvm::Value *BaseValue,
2209193326Sed                                       const ObjCIvarDecl *Ivar,
2210193326Sed                                       unsigned CVRQualifiers) {
2211198092Srdivacky  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
2212193326Sed  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2213193326Sed                                  EmitIvarOffset(CGF, ID, Ivar));
2214193326Sed}
2215198092Srdivacky
2216193326Sedstatic const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
2217193326Sed                                                  const ObjCInterfaceDecl *OID,
2218193326Sed                                                  const ObjCIvarDecl *OIVD) {
2219193326Sed  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
2220193576Sed  Context.ShallowCollectObjCIvars(OID, Ivars);
2221193326Sed  for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
2222193326Sed    if (OIVD == Ivars[k])
2223193326Sed      return OID;
2224193326Sed  }
2225198092Srdivacky
2226193326Sed  // Otherwise check in the super class.
2227193326Sed  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
2228193326Sed    return FindIvarInterface(Context, Super, OIVD);
2229198092Srdivacky
2230193326Sed  return 0;
2231193326Sed}
2232193326Sed
2233193326Sedllvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
2234193326Sed                         const ObjCInterfaceDecl *Interface,
2235193326Sed                         const ObjCIvarDecl *Ivar) {
2236198092Srdivacky  if (CGM.getLangOptions().ObjCNonFragileABI) {
2237193326Sed    Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar);
2238198092Srdivacky    return CGF.Builder.CreateLoad(CGF.Builder.CreateLoad(
2239198092Srdivacky                ObjCIvarOffsetVariable(Interface, Ivar), false, "ivar"));
2240193326Sed  }
2241193326Sed  uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
2242193326Sed  return llvm::ConstantInt::get(LongTy, Offset, "ivar");
2243193326Sed}
2244193326Sed
2245198092SrdivackyCodeGen::CGObjCRuntime *
2246198092SrdivackyCodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM) {
2247193326Sed  return new CGObjCGNU(CGM);
2248193326Sed}
2249