CGObjCGNU.cpp revision 205408
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"
29193326Sed#include "llvm/ADT/SmallVector.h"
30193326Sed#include "llvm/ADT/StringMap.h"
31193326Sed#include "llvm/Support/Compiler.h"
32193326Sed#include "llvm/Target/TargetData.h"
33193326Sed
34193326Sed#include <map>
35193326Sed
36193326Sed
37193326Sedusing namespace clang;
38193326Sedusing namespace CodeGen;
39193326Sedusing llvm::dyn_cast;
40193326Sed
41193326Sed// The version of the runtime that this class targets.  Must match the version
42193326Sed// in the runtime.
43193326Sedstatic const int RuntimeVersion = 8;
44193326Sedstatic const int NonFragileRuntimeVersion = 9;
45193326Sedstatic const int ProtocolVersion = 2;
46198092Srdivackystatic const int NonFragileProtocolVersion = 3;
47193326Sed
48193326Sednamespace {
49193326Sedclass CGObjCGNU : public CodeGen::CGObjCRuntime {
50193326Sedprivate:
51193326Sed  CodeGen::CodeGenModule &CGM;
52193326Sed  llvm::Module &TheModule;
53193326Sed  const llvm::PointerType *SelectorTy;
54198092Srdivacky  const llvm::IntegerType *Int8Ty;
55193326Sed  const llvm::PointerType *PtrToInt8Ty;
56193326Sed  const llvm::FunctionType *IMPTy;
57193326Sed  const llvm::PointerType *IdTy;
58203955Srdivacky  const llvm::PointerType *PtrToIdTy;
59204643Srdivacky  CanQualType ASTIdTy;
60193326Sed  const llvm::IntegerType *IntTy;
61193326Sed  const llvm::PointerType *PtrTy;
62193326Sed  const llvm::IntegerType *LongTy;
63193326Sed  const llvm::PointerType *PtrToIntTy;
64193326Sed  llvm::GlobalAlias *ClassPtrAlias;
65193326Sed  llvm::GlobalAlias *MetaClassPtrAlias;
66193326Sed  std::vector<llvm::Constant*> Classes;
67193326Sed  std::vector<llvm::Constant*> Categories;
68193326Sed  std::vector<llvm::Constant*> ConstantStrings;
69203955Srdivacky  llvm::StringMap<llvm::Constant*> ObjCStrings;
70193326Sed  llvm::Function *LoadFunction;
71193326Sed  llvm::StringMap<llvm::Constant*> ExistingProtocols;
72193326Sed  typedef std::pair<std::string, std::string> TypedSelector;
73193326Sed  std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors;
74193326Sed  llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors;
75203955Srdivacky  // Selectors that we don't emit in GC mode
76203955Srdivacky  Selector RetainSel, ReleaseSel, AutoreleaseSel;
77203955Srdivacky  // Functions used for GC.
78203955Srdivacky  llvm::Constant *IvarAssignFn, *StrongCastAssignFn, *MemMoveFn, *WeakReadFn,
79203955Srdivacky    *WeakAssignFn, *GlobalAssignFn;
80193326Sed  // Some zeros used for GEPs in lots of places.
81193326Sed  llvm::Constant *Zeros[2];
82193326Sed  llvm::Constant *NULLPtr;
83198092Srdivacky  llvm::LLVMContext &VMContext;
84193326Sedprivate:
85193326Sed  llvm::Constant *GenerateIvarList(
86193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
87193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
88193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets);
89193326Sed  llvm::Constant *GenerateMethodList(const std::string &ClassName,
90193326Sed      const std::string &CategoryName,
91198092Srdivacky      const llvm::SmallVectorImpl<Selector>  &MethodSels,
92198092Srdivacky      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes,
93193326Sed      bool isClassMethodList);
94193326Sed  llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName);
95198092Srdivacky  llvm::Constant *GeneratePropertyList(const ObjCImplementationDecl *OID,
96198092Srdivacky        llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
97198092Srdivacky        llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes);
98193326Sed  llvm::Constant *GenerateProtocolList(
99193326Sed      const llvm::SmallVectorImpl<std::string> &Protocols);
100198092Srdivacky  // To ensure that all protocols are seen by the runtime, we add a category on
101198092Srdivacky  // a class defined in the runtime, declaring no methods, but adopting the
102198092Srdivacky  // protocols.
103198092Srdivacky  void GenerateProtocolHolderCategory(void);
104193326Sed  llvm::Constant *GenerateClassStructure(
105193326Sed      llvm::Constant *MetaClass,
106193326Sed      llvm::Constant *SuperClass,
107193326Sed      unsigned info,
108193326Sed      const char *Name,
109193326Sed      llvm::Constant *Version,
110193326Sed      llvm::Constant *InstanceSize,
111193326Sed      llvm::Constant *IVars,
112193326Sed      llvm::Constant *Methods,
113198092Srdivacky      llvm::Constant *Protocols,
114198092Srdivacky      llvm::Constant *IvarOffsets,
115198092Srdivacky      llvm::Constant *Properties);
116193326Sed  llvm::Constant *GenerateProtocolMethodList(
117193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
118193326Sed      const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes);
119193326Sed  llvm::Constant *MakeConstantString(const std::string &Str, const std::string
120193326Sed      &Name="");
121198092Srdivacky  llvm::Constant *ExportUniqueString(const std::string &Str, const std::string
122198092Srdivacky          prefix);
123193326Sed  llvm::Constant *MakeGlobal(const llvm::StructType *Ty,
124203955Srdivacky    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
125202379Srdivacky    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
126193326Sed  llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty,
127203955Srdivacky    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
128202379Srdivacky    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
129193326Sed  llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
130193326Sed      const ObjCIvarDecl *Ivar);
131194613Sed  void EmitClassRef(const std::string &className);
132203955Srdivacky  llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, const llvm::Type *Ty){
133203955Srdivacky    if (V->getType() == Ty) return V;
134203955Srdivacky    return B.CreateBitCast(V, Ty);
135203955Srdivacky  }
136193326Sedpublic:
137193326Sed  CGObjCGNU(CodeGen::CodeGenModule &cgm);
138202879Srdivacky  virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
139198092Srdivacky  virtual CodeGen::RValue
140193326Sed  GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
141193326Sed                      QualType ResultType,
142193326Sed                      Selector Sel,
143193326Sed                      llvm::Value *Receiver,
144193326Sed                      bool IsClassMessage,
145193326Sed                      const CallArgList &CallArgs,
146193326Sed                      const ObjCMethodDecl *Method);
147198092Srdivacky  virtual CodeGen::RValue
148193326Sed  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
149193326Sed                           QualType ResultType,
150193326Sed                           Selector Sel,
151193326Sed                           const ObjCInterfaceDecl *Class,
152193326Sed                           bool isCategoryImpl,
153193326Sed                           llvm::Value *Receiver,
154193326Sed                           bool IsClassMessage,
155198092Srdivacky                           const CallArgList &CallArgs,
156198092Srdivacky                           const ObjCMethodDecl *Method);
157193326Sed  virtual llvm::Value *GetClass(CGBuilderTy &Builder,
158193326Sed                                const ObjCInterfaceDecl *OID);
159193326Sed  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
160193326Sed  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
161193326Sed      *Method);
162198092Srdivacky
163198092Srdivacky  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
164193326Sed                                         const ObjCContainerDecl *CD);
165193326Sed  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
166193326Sed  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
167193326Sed  virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
168193326Sed                                           const ObjCProtocolDecl *PD);
169193326Sed  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
170193326Sed  virtual llvm::Function *ModuleInitFunction();
171193326Sed  virtual llvm::Function *GetPropertyGetFunction();
172193326Sed  virtual llvm::Function *GetPropertySetFunction();
173198092Srdivacky  virtual llvm::Constant *EnumerationMutationFunction();
174198092Srdivacky
175193326Sed  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
176193326Sed                                         const Stmt &S);
177193326Sed  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
178193326Sed                             const ObjCAtThrowStmt &S);
179193326Sed  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
180193326Sed                                         llvm::Value *AddrWeakObj);
181193326Sed  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
182193326Sed                                  llvm::Value *src, llvm::Value *dst);
183193326Sed  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
184193326Sed                                    llvm::Value *src, llvm::Value *dest);
185193326Sed  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
186198092Srdivacky                                    llvm::Value *src, llvm::Value *dest,
187198092Srdivacky                                    llvm::Value *ivarOffset);
188193326Sed  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
189193326Sed                                        llvm::Value *src, llvm::Value *dest);
190198092Srdivacky  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
191198092Srdivacky                                        llvm::Value *DestPtr,
192198092Srdivacky                                        llvm::Value *SrcPtr,
193198092Srdivacky                                        QualType Ty);
194193326Sed  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
195193326Sed                                      QualType ObjectTy,
196193326Sed                                      llvm::Value *BaseValue,
197193326Sed                                      const ObjCIvarDecl *Ivar,
198193326Sed                                      unsigned CVRQualifiers);
199193326Sed  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
200193326Sed                                      const ObjCInterfaceDecl *Interface,
201193326Sed                                      const ObjCIvarDecl *Ivar);
202193326Sed};
203193326Sed} // end anonymous namespace
204193326Sed
205193326Sed
206194613Sed/// Emits a reference to a dummy variable which is emitted with each class.
207194613Sed/// This ensures that a linker error will be generated when trying to link
208194613Sed/// together modules where a referenced class is not defined.
209198092Srdivackyvoid CGObjCGNU::EmitClassRef(const std::string &className) {
210194613Sed  std::string symbolRef = "__objc_class_ref_" + className;
211194613Sed  // Don't emit two copies of the same symbol
212198092Srdivacky  if (TheModule.getGlobalVariable(symbolRef))
213198092Srdivacky    return;
214194613Sed  std::string symbolName = "__objc_class_name_" + className;
215194613Sed  llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
216194613Sed  if (!ClassSymbol) {
217198092Srdivacky    ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
218198092Srdivacky        llvm::GlobalValue::ExternalLinkage, 0, symbolName);
219194613Sed  }
220198092Srdivacky  new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true,
221198092Srdivacky    llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
222194613Sed}
223193326Sed
224193326Sedstatic std::string SymbolNameForClass(const std::string &ClassName) {
225194613Sed  return "_OBJC_CLASS_" + ClassName;
226193326Sed}
227193326Sed
228193326Sedstatic std::string SymbolNameForMethod(const std::string &ClassName, const
229193326Sed  std::string &CategoryName, const std::string &MethodName, bool isClassMethod)
230193326Sed{
231202379Srdivacky  std::string MethodNameColonStripped = MethodName;
232202379Srdivacky  std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
233202379Srdivacky      ':', '_');
234202379Srdivacky  return std::string(isClassMethod ? "_c_" : "_i_") + ClassName + "_" +
235202379Srdivacky    CategoryName + "_" + MethodNameColonStripped;
236193326Sed}
237193326Sed
238193326SedCGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
239193326Sed  : CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
240198092Srdivacky    MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
241193326Sed  IntTy = cast<llvm::IntegerType>(
242193326Sed      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
243193326Sed  LongTy = cast<llvm::IntegerType>(
244193326Sed      CGM.getTypes().ConvertType(CGM.getContext().LongTy));
245198092Srdivacky
246198092Srdivacky  Int8Ty = llvm::Type::getInt8Ty(VMContext);
247198092Srdivacky  // C string type.  Used in lots of places.
248198092Srdivacky  PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
249198092Srdivacky
250193326Sed  Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
251193326Sed  Zeros[1] = Zeros[0];
252198092Srdivacky  NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
253193326Sed  // Get the selector Type.
254202879Srdivacky  QualType selTy = CGM.getContext().getObjCSelType();
255202879Srdivacky  if (QualType() == selTy) {
256202879Srdivacky    SelectorTy = PtrToInt8Ty;
257202879Srdivacky  } else {
258202879Srdivacky    SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
259202879Srdivacky  }
260193326Sed
261193326Sed  PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
262193326Sed  PtrTy = PtrToInt8Ty;
263198092Srdivacky
264193326Sed  // Object type
265204643Srdivacky  ASTIdTy = CGM.getContext().getCanonicalType(CGM.getContext().getObjCIdType());
266202879Srdivacky  if (QualType() == ASTIdTy) {
267202879Srdivacky    IdTy = PtrToInt8Ty;
268202879Srdivacky  } else {
269202879Srdivacky    IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
270202879Srdivacky  }
271203955Srdivacky  PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
272198092Srdivacky
273193326Sed  // IMP type
274193326Sed  std::vector<const llvm::Type*> IMPArgs;
275193326Sed  IMPArgs.push_back(IdTy);
276193326Sed  IMPArgs.push_back(SelectorTy);
277193326Sed  IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
278203955Srdivacky
279203955Srdivacky  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
280203955Srdivacky    // Get selectors needed in GC mode
281203955Srdivacky    RetainSel = GetNullarySelector("retain", CGM.getContext());
282203955Srdivacky    ReleaseSel = GetNullarySelector("release", CGM.getContext());
283203955Srdivacky    AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext());
284203955Srdivacky
285203955Srdivacky    // Get functions needed in GC mode
286203955Srdivacky
287203955Srdivacky    // id objc_assign_ivar(id, id, ptrdiff_t);
288203955Srdivacky    std::vector<const llvm::Type*> Args(1, IdTy);
289203955Srdivacky    Args.push_back(PtrToIdTy);
290203955Srdivacky    // FIXME: ptrdiff_t
291203955Srdivacky    Args.push_back(LongTy);
292203955Srdivacky    llvm::FunctionType *FTy = llvm::FunctionType::get(IdTy, Args, false);
293203955Srdivacky    IvarAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
294203955Srdivacky    // id objc_assign_strongCast (id, id*)
295203955Srdivacky    Args.pop_back();
296203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
297203955Srdivacky    StrongCastAssignFn =
298203955Srdivacky        CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
299203955Srdivacky    // id objc_assign_global(id, id*);
300203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
301203955Srdivacky    GlobalAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
302203955Srdivacky    // id objc_assign_weak(id, id*);
303203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
304203955Srdivacky    WeakAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
305203955Srdivacky    // id objc_read_weak(id*);
306203955Srdivacky    Args.clear();
307203955Srdivacky    Args.push_back(PtrToIdTy);
308203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
309203955Srdivacky    WeakReadFn = CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
310203955Srdivacky    // void *objc_memmove_collectable(void*, void *, size_t);
311203955Srdivacky    Args.clear();
312203955Srdivacky    Args.push_back(PtrToInt8Ty);
313203955Srdivacky    Args.push_back(PtrToInt8Ty);
314203955Srdivacky    // FIXME: size_t
315203955Srdivacky    Args.push_back(LongTy);
316203955Srdivacky    FTy = llvm::FunctionType::get(IdTy, Args, false);
317203955Srdivacky    MemMoveFn = CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
318203955Srdivacky  }
319193326Sed}
320198092Srdivacky
321193326Sed// This has to perform the lookup every time, since posing and related
322193326Sed// techniques can modify the name -> class mapping.
323193326Sedllvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder,
324193326Sed                                 const ObjCInterfaceDecl *OID) {
325193326Sed  llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString());
326202379Srdivacky  // With the incompatible ABI, this will need to be replaced with a direct
327202379Srdivacky  // reference to the class symbol.  For the compatible nonfragile ABI we are
328202379Srdivacky  // still performing this lookup at run time but emitting the symbol for the
329202379Srdivacky  // class externally so that we can make the switch later.
330194613Sed  EmitClassRef(OID->getNameAsString());
331193326Sed  ClassName = Builder.CreateStructGEP(ClassName, 0);
332193326Sed
333193326Sed  std::vector<const llvm::Type*> Params(1, PtrToInt8Ty);
334193326Sed  llvm::Constant *ClassLookupFn =
335193326Sed    CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy,
336193326Sed                                                      Params,
337193326Sed                                                      true),
338193326Sed                              "objc_lookup_class");
339193326Sed  return Builder.CreateCall(ClassLookupFn, ClassName);
340193326Sed}
341193326Sed
342193326Sedllvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
343193326Sed  llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()];
344193326Sed  if (US == 0)
345193326Sed    US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
346198092Srdivacky                               llvm::GlobalValue::PrivateLinkage,
347198092Srdivacky                               ".objc_untyped_selector_alias"+Sel.getAsString(),
348193326Sed                               NULL, &TheModule);
349198092Srdivacky
350193326Sed  return Builder.CreateLoad(US);
351193326Sed}
352193326Sed
353193326Sedllvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
354193326Sed    *Method) {
355193326Sed
356193326Sed  std::string SelName = Method->getSelector().getAsString();
357193326Sed  std::string SelTypes;
358193326Sed  CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
359193326Sed  // Typed selectors
360193326Sed  TypedSelector Selector = TypedSelector(SelName,
361193326Sed          SelTypes);
362193326Sed
363193326Sed  // If it's already cached, return it.
364198092Srdivacky  if (TypedSelectors[Selector]) {
365198092Srdivacky    return Builder.CreateLoad(TypedSelectors[Selector]);
366193326Sed  }
367193326Sed
368193326Sed  // If it isn't, cache it.
369193326Sed  llvm::GlobalAlias *Sel = new llvm::GlobalAlias(
370193326Sed          llvm::PointerType::getUnqual(SelectorTy),
371198092Srdivacky          llvm::GlobalValue::PrivateLinkage, ".objc_selector_alias" + SelName,
372193326Sed          NULL, &TheModule);
373193326Sed  TypedSelectors[Selector] = Sel;
374193326Sed
375193326Sed  return Builder.CreateLoad(Sel);
376193326Sed}
377193326Sed
378193326Sedllvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
379193326Sed                                              const std::string &Name) {
380198092Srdivacky  llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
381193326Sed  return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
382193326Sed}
383198092Srdivackyllvm::Constant *CGObjCGNU::ExportUniqueString(const std::string &Str,
384198092Srdivacky        const std::string prefix) {
385198092Srdivacky  std::string name = prefix + Str;
386198092Srdivacky  llvm::Constant *ConstStr = TheModule.getGlobalVariable(name);
387198092Srdivacky  if (!ConstStr) {
388198092Srdivacky    llvm::Constant *value = llvm::ConstantArray::get(VMContext, Str, true);
389198092Srdivacky    ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true,
390198092Srdivacky            llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str);
391198092Srdivacky  }
392198092Srdivacky  return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
393198092Srdivacky}
394198092Srdivacky
395193326Sedllvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty,
396203955Srdivacky    std::vector<llvm::Constant*> &V, llvm::StringRef Name,
397202379Srdivacky    llvm::GlobalValue::LinkageTypes linkage) {
398193326Sed  llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
399198092Srdivacky  return new llvm::GlobalVariable(TheModule, Ty, false,
400198092Srdivacky      llvm::GlobalValue::InternalLinkage, C, Name);
401193326Sed}
402198092Srdivacky
403193326Sedllvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty,
404203955Srdivacky    std::vector<llvm::Constant*> &V, llvm::StringRef Name,
405202379Srdivacky    llvm::GlobalValue::LinkageTypes linkage) {
406193326Sed  llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
407198092Srdivacky  return new llvm::GlobalVariable(TheModule, Ty, false,
408198092Srdivacky                                  llvm::GlobalValue::InternalLinkage, C, Name);
409193326Sed}
410193326Sed
411193326Sed/// Generate an NSConstantString object.
412202879Srdivackyllvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
413203955Srdivacky
414202879Srdivacky  std::string Str(SL->getStrData(), SL->getByteLength());
415202879Srdivacky
416203955Srdivacky  // Look for an existing one
417203955Srdivacky  llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
418203955Srdivacky  if (old != ObjCStrings.end())
419203955Srdivacky    return old->getValue();
420203955Srdivacky
421193326Sed  std::vector<llvm::Constant*> Ivars;
422193326Sed  Ivars.push_back(NULLPtr);
423193326Sed  Ivars.push_back(MakeConstantString(Str));
424193326Sed  Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
425193326Sed  llvm::Constant *ObjCStr = MakeGlobal(
426198092Srdivacky    llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL),
427193326Sed    Ivars, ".objc_str");
428203955Srdivacky  ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
429203955Srdivacky  ObjCStrings[Str] = ObjCStr;
430203955Srdivacky  ConstantStrings.push_back(ObjCStr);
431193326Sed  return ObjCStr;
432193326Sed}
433193326Sed
434193326Sed///Generates a message send where the super is the receiver.  This is a message
435193326Sed///send to self with special delivery semantics indicating which class's method
436193326Sed///should be called.
437193326SedCodeGen::RValue
438193326SedCGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
439193326Sed                                    QualType ResultType,
440193326Sed                                    Selector Sel,
441193326Sed                                    const ObjCInterfaceDecl *Class,
442193326Sed                                    bool isCategoryImpl,
443193326Sed                                    llvm::Value *Receiver,
444193326Sed                                    bool IsClassMessage,
445198092Srdivacky                                    const CallArgList &CallArgs,
446198092Srdivacky                                    const ObjCMethodDecl *Method) {
447203955Srdivacky  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
448203955Srdivacky    if (Sel == RetainSel || Sel == AutoreleaseSel) {
449203955Srdivacky      return RValue::get(Receiver);
450203955Srdivacky    }
451203955Srdivacky    if (Sel == ReleaseSel) {
452203955Srdivacky      return RValue::get(0);
453203955Srdivacky    }
454203955Srdivacky  }
455193326Sed  llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
456193326Sed
457193326Sed  CallArgList ActualArgs;
458193326Sed
459193326Sed  ActualArgs.push_back(
460198092Srdivacky      std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
461198092Srdivacky      ASTIdTy));
462193326Sed  ActualArgs.push_back(std::make_pair(RValue::get(cmd),
463193326Sed                                      CGF.getContext().getObjCSelType()));
464193326Sed  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
465193326Sed
466193326Sed  CodeGenTypes &Types = CGM.getTypes();
467203955Srdivacky  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
468203955Srdivacky                                                       CC_Default, false);
469198092Srdivacky  const llvm::FunctionType *impType =
470198092Srdivacky    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
471193326Sed
472193326Sed  llvm::Value *ReceiverClass = 0;
473193326Sed  if (isCategoryImpl) {
474193326Sed    llvm::Constant *classLookupFunction = 0;
475193326Sed    std::vector<const llvm::Type*> Params;
476193326Sed    Params.push_back(PtrTy);
477193326Sed    if (IsClassMessage)  {
478193326Sed      classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
479193326Sed            IdTy, Params, true), "objc_get_meta_class");
480193326Sed    } else {
481193326Sed      classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
482193326Sed            IdTy, Params, true), "objc_get_class");
483193326Sed    }
484193326Sed    ReceiverClass = CGF.Builder.CreateCall(classLookupFunction,
485193326Sed        MakeConstantString(Class->getNameAsString()));
486193326Sed  } else {
487193326Sed    // Set up global aliases for the metaclass or class pointer if they do not
488193326Sed    // already exist.  These will are forward-references which will be set to
489198092Srdivacky    // pointers to the class and metaclass structure created for the runtime
490198092Srdivacky    // load function.  To send a message to super, we look up the value of the
491193326Sed    // super_class pointer from either the class or metaclass structure.
492193326Sed    if (IsClassMessage)  {
493193326Sed      if (!MetaClassPtrAlias) {
494193326Sed        MetaClassPtrAlias = new llvm::GlobalAlias(IdTy,
495193326Sed            llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" +
496193326Sed            Class->getNameAsString(), NULL, &TheModule);
497193326Sed      }
498193326Sed      ReceiverClass = MetaClassPtrAlias;
499193326Sed    } else {
500193326Sed      if (!ClassPtrAlias) {
501193326Sed        ClassPtrAlias = new llvm::GlobalAlias(IdTy,
502193326Sed            llvm::GlobalValue::InternalLinkage, ".objc_class_ref" +
503193326Sed            Class->getNameAsString(), NULL, &TheModule);
504193326Sed      }
505193326Sed      ReceiverClass = ClassPtrAlias;
506193326Sed    }
507193326Sed  }
508193326Sed  // Cast the pointer to a simplified version of the class structure
509198092Srdivacky  ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass,
510198092Srdivacky      llvm::PointerType::getUnqual(
511198092Srdivacky        llvm::StructType::get(VMContext, IdTy, IdTy, NULL)));
512193326Sed  // Get the superclass pointer
513193326Sed  ReceiverClass = CGF.Builder.CreateStructGEP(ReceiverClass, 1);
514193326Sed  // Load the superclass pointer
515193326Sed  ReceiverClass = CGF.Builder.CreateLoad(ReceiverClass);
516193326Sed  // Construct the structure used to look up the IMP
517198092Srdivacky  llvm::StructType *ObjCSuperTy = llvm::StructType::get(VMContext,
518198092Srdivacky      Receiver->getType(), IdTy, NULL);
519193326Sed  llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy);
520193326Sed
521193326Sed  CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0));
522193326Sed  CGF.Builder.CreateStore(ReceiverClass,
523193326Sed      CGF.Builder.CreateStructGEP(ObjCSuper, 1));
524193326Sed
525193326Sed  // Get the IMP
526193326Sed  std::vector<const llvm::Type*> Params;
527193326Sed  Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy));
528193326Sed  Params.push_back(SelectorTy);
529198092Srdivacky  llvm::Constant *lookupFunction =
530193326Sed    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
531193326Sed          llvm::PointerType::getUnqual(impType), Params, true),
532193326Sed        "objc_msg_lookup_super");
533193326Sed
534193326Sed  llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
535193326Sed  llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs,
536193326Sed      lookupArgs+2);
537193326Sed
538201361Srdivacky  return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
539193326Sed}
540193326Sed
541198092Srdivacky/// Generate code for a message send expression.
542193326SedCodeGen::RValue
543193326SedCGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
544193326Sed                               QualType ResultType,
545193326Sed                               Selector Sel,
546193326Sed                               llvm::Value *Receiver,
547193326Sed                               bool IsClassMessage,
548193326Sed                               const CallArgList &CallArgs,
549193326Sed                               const ObjCMethodDecl *Method) {
550203955Srdivacky  if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
551203955Srdivacky    if (Sel == RetainSel || Sel == AutoreleaseSel) {
552203955Srdivacky      return RValue::get(Receiver);
553203955Srdivacky    }
554203955Srdivacky    if (Sel == ReleaseSel) {
555203955Srdivacky      return RValue::get(0);
556203955Srdivacky    }
557203955Srdivacky  }
558198092Srdivacky  CGBuilderTy &Builder = CGF.Builder;
559198092Srdivacky  IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
560193326Sed  llvm::Value *cmd;
561193326Sed  if (Method)
562198092Srdivacky    cmd = GetSelector(Builder, Method);
563193326Sed  else
564198092Srdivacky    cmd = GetSelector(Builder, Sel);
565193326Sed  CallArgList ActualArgs;
566193326Sed
567198092Srdivacky  Receiver = Builder.CreateBitCast(Receiver, IdTy);
568193326Sed  ActualArgs.push_back(
569198092Srdivacky    std::make_pair(RValue::get(Receiver), ASTIdTy));
570193326Sed  ActualArgs.push_back(std::make_pair(RValue::get(cmd),
571193326Sed                                      CGF.getContext().getObjCSelType()));
572193326Sed  ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
573193326Sed
574193326Sed  CodeGenTypes &Types = CGM.getTypes();
575203955Srdivacky  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
576203955Srdivacky                                                       CC_Default, false);
577198092Srdivacky  const llvm::FunctionType *impType =
578198092Srdivacky    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
579193326Sed
580193326Sed  llvm::Value *imp;
581193326Sed  // For sender-aware dispatch, we pass the sender as the third argument to a
582193326Sed  // lookup function.  When sending messages from C code, the sender is nil.
583198092Srdivacky  // objc_msg_lookup_sender(id *receiver, SEL selector, id sender);
584198092Srdivacky  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
585198092Srdivacky
586198092Srdivacky    std::vector<const llvm::Type*> Params;
587198092Srdivacky    llvm::Value *ReceiverPtr = CGF.CreateTempAlloca(Receiver->getType());
588198092Srdivacky    Builder.CreateStore(Receiver, ReceiverPtr);
589198092Srdivacky    Params.push_back(ReceiverPtr->getType());
590198092Srdivacky    Params.push_back(SelectorTy);
591193326Sed    llvm::Value *self;
592193326Sed
593193326Sed    if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) {
594193326Sed      self = CGF.LoadObjCSelf();
595193326Sed    } else {
596193326Sed      self = llvm::ConstantPointerNull::get(IdTy);
597193326Sed    }
598198092Srdivacky
599193326Sed    Params.push_back(self->getType());
600198092Srdivacky
601198092Srdivacky    // The lookup function returns a slot, which can be safely cached.
602198092Srdivacky    llvm::Type *SlotTy = llvm::StructType::get(VMContext, PtrTy, PtrTy, PtrTy,
603198092Srdivacky            IntTy, llvm::PointerType::getUnqual(impType), NULL);
604198092Srdivacky    llvm::Constant *lookupFunction =
605193326Sed      CGM.CreateRuntimeFunction(llvm::FunctionType::get(
606198092Srdivacky          llvm::PointerType::getUnqual(SlotTy), Params, true),
607193326Sed        "objc_msg_lookup_sender");
608193326Sed
609198092Srdivacky    // The lookup function is guaranteed not to capture the receiver pointer.
610198092Srdivacky    if (llvm::Function *LookupFn = dyn_cast<llvm::Function>(lookupFunction)) {
611198092Srdivacky      LookupFn->setDoesNotCapture(1);
612198092Srdivacky    }
613198092Srdivacky
614198092Srdivacky    llvm::Value *slot =
615198092Srdivacky        Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
616198092Srdivacky    imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
617198092Srdivacky    // The lookup function may have changed the receiver, so make sure we use
618198092Srdivacky    // the new one.
619198092Srdivacky    ActualArgs[0] =
620198092Srdivacky        std::make_pair(RValue::get(Builder.CreateLoad(ReceiverPtr)), ASTIdTy);
621193326Sed  } else {
622198092Srdivacky    std::vector<const llvm::Type*> Params;
623198092Srdivacky    Params.push_back(Receiver->getType());
624198092Srdivacky    Params.push_back(SelectorTy);
625198092Srdivacky    llvm::Constant *lookupFunction =
626193326Sed    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
627193326Sed        llvm::PointerType::getUnqual(impType), Params, true),
628193326Sed      "objc_msg_lookup");
629193326Sed
630198092Srdivacky    imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
631193326Sed  }
632193326Sed
633201361Srdivacky  return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
634193326Sed}
635193326Sed
636198092Srdivacky/// Generates a MethodList.  Used in construction of a objc_class and
637193326Sed/// objc_category structures.
638193326Sedllvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
639198092Srdivacky                                              const std::string &CategoryName,
640198092Srdivacky    const llvm::SmallVectorImpl<Selector> &MethodSels,
641198092Srdivacky    const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
642193326Sed    bool isClassMethodList) {
643198092Srdivacky  if (MethodSels.empty())
644198092Srdivacky    return NULLPtr;
645198092Srdivacky  // Get the method structure type.
646198092Srdivacky  llvm::StructType *ObjCMethodTy = llvm::StructType::get(VMContext,
647193326Sed    PtrToInt8Ty, // Really a selector, but the runtime creates it us.
648193326Sed    PtrToInt8Ty, // Method types
649193326Sed    llvm::PointerType::getUnqual(IMPTy), //Method pointer
650193326Sed    NULL);
651193326Sed  std::vector<llvm::Constant*> Methods;
652193326Sed  std::vector<llvm::Constant*> Elements;
653193326Sed  for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
654193326Sed    Elements.clear();
655193326Sed    if (llvm::Constant *Method =
656193326Sed      TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
657193326Sed                                                MethodSels[i].getAsString(),
658193326Sed                                                isClassMethodList))) {
659198092Srdivacky      llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString());
660198092Srdivacky      Elements.push_back(C);
661198092Srdivacky      Elements.push_back(MethodTypes[i]);
662193326Sed      Method = llvm::ConstantExpr::getBitCast(Method,
663193326Sed          llvm::PointerType::getUnqual(IMPTy));
664193326Sed      Elements.push_back(Method);
665193326Sed      Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
666193326Sed    }
667193326Sed  }
668193326Sed
669193326Sed  // Array of method structures
670193326Sed  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
671193326Sed                                                            Methods.size());
672193326Sed  llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
673193326Sed                                                         Methods);
674193326Sed
675193326Sed  // Structure containing list pointer, array and array count
676193326Sed  llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields;
677198092Srdivacky  llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get(VMContext);
678193326Sed  llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy);
679198092Srdivacky  llvm::StructType *ObjCMethodListTy = llvm::StructType::get(VMContext,
680198092Srdivacky      NextPtrTy,
681198092Srdivacky      IntTy,
682193326Sed      ObjCMethodArrayTy,
683193326Sed      NULL);
684193326Sed  // Refine next pointer type to concrete type
685193326Sed  llvm::cast<llvm::OpaqueType>(
686193326Sed      OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy);
687193326Sed  ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get());
688193326Sed
689193326Sed  Methods.clear();
690193326Sed  Methods.push_back(llvm::ConstantPointerNull::get(
691193326Sed        llvm::PointerType::getUnqual(ObjCMethodListTy)));
692198092Srdivacky  Methods.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
693193326Sed        MethodTypes.size()));
694193326Sed  Methods.push_back(MethodArray);
695198092Srdivacky
696193326Sed  // Create an instance of the structure
697193326Sed  return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list");
698193326Sed}
699193326Sed
700193326Sed/// Generates an IvarList.  Used in construction of a objc_class.
701193326Sedllvm::Constant *CGObjCGNU::GenerateIvarList(
702193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
703193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
704193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets) {
705199482Srdivacky  if (IvarNames.size() == 0)
706199482Srdivacky    return NULLPtr;
707198092Srdivacky  // Get the method structure type.
708198092Srdivacky  llvm::StructType *ObjCIvarTy = llvm::StructType::get(VMContext,
709193326Sed    PtrToInt8Ty,
710193326Sed    PtrToInt8Ty,
711193326Sed    IntTy,
712193326Sed    NULL);
713193326Sed  std::vector<llvm::Constant*> Ivars;
714193326Sed  std::vector<llvm::Constant*> Elements;
715193326Sed  for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
716193326Sed    Elements.clear();
717198092Srdivacky    Elements.push_back(IvarNames[i]);
718198092Srdivacky    Elements.push_back(IvarTypes[i]);
719193326Sed    Elements.push_back(IvarOffsets[i]);
720193326Sed    Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements));
721193326Sed  }
722193326Sed
723193326Sed  // Array of method structures
724193326Sed  llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
725193326Sed      IvarNames.size());
726193326Sed
727198092Srdivacky
728193326Sed  Elements.clear();
729193326Sed  Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size()));
730193326Sed  Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars));
731193326Sed  // Structure containing array and array count
732198092Srdivacky  llvm::StructType *ObjCIvarListTy = llvm::StructType::get(VMContext, IntTy,
733193326Sed    ObjCIvarArrayTy,
734193326Sed    NULL);
735193326Sed
736193326Sed  // Create an instance of the structure
737193326Sed  return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list");
738193326Sed}
739193326Sed
740193326Sed/// Generate a class structure
741193326Sedllvm::Constant *CGObjCGNU::GenerateClassStructure(
742193326Sed    llvm::Constant *MetaClass,
743193326Sed    llvm::Constant *SuperClass,
744193326Sed    unsigned info,
745193326Sed    const char *Name,
746193326Sed    llvm::Constant *Version,
747193326Sed    llvm::Constant *InstanceSize,
748193326Sed    llvm::Constant *IVars,
749193326Sed    llvm::Constant *Methods,
750198092Srdivacky    llvm::Constant *Protocols,
751198092Srdivacky    llvm::Constant *IvarOffsets,
752198092Srdivacky    llvm::Constant *Properties) {
753193326Sed  // Set up the class structure
754193326Sed  // Note:  Several of these are char*s when they should be ids.  This is
755193326Sed  // because the runtime performs this translation on load.
756198092Srdivacky  //
757198092Srdivacky  // Fields marked New ABI are part of the GNUstep runtime.  We emit them
758198092Srdivacky  // anyway; the classes will still work with the GNU runtime, they will just
759198092Srdivacky  // be ignored.
760198092Srdivacky  llvm::StructType *ClassTy = llvm::StructType::get(VMContext,
761193326Sed      PtrToInt8Ty,        // class_pointer
762193326Sed      PtrToInt8Ty,        // super_class
763193326Sed      PtrToInt8Ty,        // name
764193326Sed      LongTy,             // version
765193326Sed      LongTy,             // info
766193326Sed      LongTy,             // instance_size
767193326Sed      IVars->getType(),   // ivars
768193326Sed      Methods->getType(), // methods
769198092Srdivacky      // These are all filled in by the runtime, so we pretend
770193326Sed      PtrTy,              // dtable
771193326Sed      PtrTy,              // subclass_list
772193326Sed      PtrTy,              // sibling_class
773193326Sed      PtrTy,              // protocols
774193326Sed      PtrTy,              // gc_object_type
775198092Srdivacky      // New ABI:
776198092Srdivacky      LongTy,                 // abi_version
777198092Srdivacky      IvarOffsets->getType(), // ivar_offsets
778198092Srdivacky      Properties->getType(),  // properties
779193326Sed      NULL);
780193326Sed  llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
781193326Sed  // Fill in the structure
782193326Sed  std::vector<llvm::Constant*> Elements;
783193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
784193326Sed  Elements.push_back(SuperClass);
785193326Sed  Elements.push_back(MakeConstantString(Name, ".class_name"));
786193326Sed  Elements.push_back(Zero);
787193326Sed  Elements.push_back(llvm::ConstantInt::get(LongTy, info));
788193326Sed  Elements.push_back(InstanceSize);
789193326Sed  Elements.push_back(IVars);
790193326Sed  Elements.push_back(Methods);
791198092Srdivacky  Elements.push_back(NULLPtr);
792198092Srdivacky  Elements.push_back(NULLPtr);
793198092Srdivacky  Elements.push_back(NULLPtr);
794193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
795198092Srdivacky  Elements.push_back(NULLPtr);
796198092Srdivacky  Elements.push_back(Zero);
797198092Srdivacky  Elements.push_back(IvarOffsets);
798198092Srdivacky  Elements.push_back(Properties);
799193326Sed  // Create an instance of the structure
800202379Srdivacky  // This is now an externally visible symbol, so that we can speed up class
801202379Srdivacky  // messages in the next ABI.
802202379Srdivacky  return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name),
803202379Srdivacky         llvm::GlobalValue::ExternalLinkage);
804193326Sed}
805193326Sed
806193326Sedllvm::Constant *CGObjCGNU::GenerateProtocolMethodList(
807193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
808193326Sed    const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes) {
809198092Srdivacky  // Get the method structure type.
810198092Srdivacky  llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(VMContext,
811193326Sed    PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.
812193326Sed    PtrToInt8Ty,
813193326Sed    NULL);
814193326Sed  std::vector<llvm::Constant*> Methods;
815193326Sed  std::vector<llvm::Constant*> Elements;
816193326Sed  for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
817193326Sed    Elements.clear();
818198092Srdivacky    Elements.push_back(MethodNames[i]);
819198092Srdivacky    Elements.push_back(MethodTypes[i]);
820193326Sed    Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements));
821193326Sed  }
822193326Sed  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
823193326Sed      MethodNames.size());
824198092Srdivacky  llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
825198092Srdivacky                                                   Methods);
826198092Srdivacky  llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(VMContext,
827193326Sed      IntTy, ObjCMethodArrayTy, NULL);
828193326Sed  Methods.clear();
829193326Sed  Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
830193326Sed  Methods.push_back(Array);
831193326Sed  return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list");
832193326Sed}
833198092Srdivacky
834193326Sed// Create the protocol list structure used in classes, categories and so on
835193326Sedllvm::Constant *CGObjCGNU::GenerateProtocolList(
836193326Sed    const llvm::SmallVectorImpl<std::string> &Protocols) {
837193326Sed  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
838193326Sed      Protocols.size());
839198092Srdivacky  llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext,
840193326Sed      PtrTy, //Should be a recurisve pointer, but it's always NULL here.
841193326Sed      LongTy,//FIXME: Should be size_t
842193326Sed      ProtocolArrayTy,
843193326Sed      NULL);
844198092Srdivacky  std::vector<llvm::Constant*> Elements;
845193326Sed  for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
846193326Sed      iter != endIter ; iter++) {
847199990Srdivacky    llvm::Constant *protocol = 0;
848199990Srdivacky    llvm::StringMap<llvm::Constant*>::iterator value =
849199990Srdivacky      ExistingProtocols.find(*iter);
850199990Srdivacky    if (value == ExistingProtocols.end()) {
851193326Sed      protocol = GenerateEmptyProtocol(*iter);
852199990Srdivacky    } else {
853199990Srdivacky      protocol = value->getValue();
854199990Srdivacky    }
855198092Srdivacky    llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
856198092Srdivacky                                                           PtrToInt8Ty);
857193326Sed    Elements.push_back(Ptr);
858193326Sed  }
859193326Sed  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
860193326Sed      Elements);
861193326Sed  Elements.clear();
862193326Sed  Elements.push_back(NULLPtr);
863193326Sed  Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
864193326Sed  Elements.push_back(ProtocolArray);
865193326Sed  return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list");
866193326Sed}
867193326Sed
868198092Srdivackyllvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder,
869193326Sed                                            const ObjCProtocolDecl *PD) {
870193326Sed  llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()];
871198092Srdivacky  const llvm::Type *T =
872193326Sed    CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
873193326Sed  return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
874193326Sed}
875193326Sed
876193326Sedllvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
877193326Sed  const std::string &ProtocolName) {
878193326Sed  llvm::SmallVector<std::string, 0> EmptyStringVector;
879193326Sed  llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector;
880193326Sed
881193326Sed  llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
882198092Srdivacky  llvm::Constant *MethodList =
883193326Sed    GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
884193326Sed  // Protocols are objects containing lists of the methods implemented and
885193326Sed  // protocols adopted.
886198092Srdivacky  llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy,
887193326Sed      PtrToInt8Ty,
888193326Sed      ProtocolList->getType(),
889198092Srdivacky      MethodList->getType(),
890198092Srdivacky      MethodList->getType(),
891198092Srdivacky      MethodList->getType(),
892198092Srdivacky      MethodList->getType(),
893193326Sed      NULL);
894198092Srdivacky  std::vector<llvm::Constant*> Elements;
895193326Sed  // The isa pointer must be set to a magic number so the runtime knows it's
896193326Sed  // the correct layout.
897198092Srdivacky  int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ?
898198092Srdivacky      NonFragileProtocolVersion : ProtocolVersion;
899193326Sed  Elements.push_back(llvm::ConstantExpr::getIntToPtr(
900198092Srdivacky        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy));
901193326Sed  Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
902193326Sed  Elements.push_back(ProtocolList);
903198092Srdivacky  Elements.push_back(MethodList);
904198092Srdivacky  Elements.push_back(MethodList);
905198092Srdivacky  Elements.push_back(MethodList);
906198092Srdivacky  Elements.push_back(MethodList);
907193326Sed  return MakeGlobal(ProtocolTy, Elements, ".objc_protocol");
908193326Sed}
909193326Sed
910193326Sedvoid CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
911193326Sed  ASTContext &Context = CGM.getContext();
912193326Sed  std::string ProtocolName = PD->getNameAsString();
913193326Sed  llvm::SmallVector<std::string, 16> Protocols;
914193326Sed  for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
915193326Sed       E = PD->protocol_end(); PI != E; ++PI)
916193326Sed    Protocols.push_back((*PI)->getNameAsString());
917193326Sed  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
918193326Sed  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
919198092Srdivacky  llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodNames;
920198092Srdivacky  llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodTypes;
921195341Sed  for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
922195341Sed       E = PD->instmeth_end(); iter != E; iter++) {
923193326Sed    std::string TypeStr;
924193326Sed    Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
925198092Srdivacky    if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
926198092Srdivacky      InstanceMethodNames.push_back(
927198092Srdivacky          MakeConstantString((*iter)->getSelector().getAsString()));
928198092Srdivacky      InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
929198092Srdivacky    } else {
930198092Srdivacky      OptionalInstanceMethodNames.push_back(
931198092Srdivacky          MakeConstantString((*iter)->getSelector().getAsString()));
932198092Srdivacky      OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
933198092Srdivacky    }
934193326Sed  }
935193326Sed  // Collect information about class methods:
936193326Sed  llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
937193326Sed  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
938198092Srdivacky  llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodNames;
939198092Srdivacky  llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodTypes;
940198092Srdivacky  for (ObjCProtocolDecl::classmeth_iterator
941195341Sed         iter = PD->classmeth_begin(), endIter = PD->classmeth_end();
942195341Sed       iter != endIter ; iter++) {
943193326Sed    std::string TypeStr;
944193326Sed    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
945198092Srdivacky    if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
946198092Srdivacky      ClassMethodNames.push_back(
947198092Srdivacky          MakeConstantString((*iter)->getSelector().getAsString()));
948198092Srdivacky      ClassMethodTypes.push_back(MakeConstantString(TypeStr));
949198092Srdivacky    } else {
950198092Srdivacky      OptionalClassMethodNames.push_back(
951198092Srdivacky          MakeConstantString((*iter)->getSelector().getAsString()));
952198092Srdivacky      OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
953198092Srdivacky    }
954193326Sed  }
955193326Sed
956193326Sed  llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
957193326Sed  llvm::Constant *InstanceMethodList =
958193326Sed    GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
959193326Sed  llvm::Constant *ClassMethodList =
960193326Sed    GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
961198092Srdivacky  llvm::Constant *OptionalInstanceMethodList =
962198092Srdivacky    GenerateProtocolMethodList(OptionalInstanceMethodNames,
963198092Srdivacky            OptionalInstanceMethodTypes);
964198092Srdivacky  llvm::Constant *OptionalClassMethodList =
965198092Srdivacky    GenerateProtocolMethodList(OptionalClassMethodNames,
966198092Srdivacky            OptionalClassMethodTypes);
967198092Srdivacky
968198092Srdivacky  // Property metadata: name, attributes, isSynthesized, setter name, setter
969198092Srdivacky  // types, getter name, getter types.
970198092Srdivacky  // The isSynthesized value is always set to 0 in a protocol.  It exists to
971198092Srdivacky  // simplify the runtime library by allowing it to use the same data
972198092Srdivacky  // structures for protocol metadata everywhere.
973198092Srdivacky  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext,
974198092Srdivacky          PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
975198092Srdivacky          PtrToInt8Ty, NULL);
976198092Srdivacky  std::vector<llvm::Constant*> Properties;
977198092Srdivacky  std::vector<llvm::Constant*> OptionalProperties;
978198092Srdivacky
979198092Srdivacky  // Add all of the property methods need adding to the method list and to the
980198092Srdivacky  // property metadata list.
981198092Srdivacky  for (ObjCContainerDecl::prop_iterator
982198092Srdivacky         iter = PD->prop_begin(), endIter = PD->prop_end();
983198092Srdivacky       iter != endIter ; iter++) {
984198092Srdivacky    std::vector<llvm::Constant*> Fields;
985198092Srdivacky    ObjCPropertyDecl *property = (*iter);
986198092Srdivacky
987198092Srdivacky    Fields.push_back(MakeConstantString(property->getNameAsString()));
988198092Srdivacky    Fields.push_back(llvm::ConstantInt::get(Int8Ty,
989198092Srdivacky                property->getPropertyAttributes()));
990198092Srdivacky    Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
991198092Srdivacky    if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
992198092Srdivacky      std::string TypeStr;
993198092Srdivacky      Context.getObjCEncodingForMethodDecl(getter,TypeStr);
994198092Srdivacky      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
995198092Srdivacky      InstanceMethodTypes.push_back(TypeEncoding);
996198092Srdivacky      Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
997198092Srdivacky      Fields.push_back(TypeEncoding);
998198092Srdivacky    } else {
999198092Srdivacky      Fields.push_back(NULLPtr);
1000198092Srdivacky      Fields.push_back(NULLPtr);
1001198092Srdivacky    }
1002198092Srdivacky    if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
1003198092Srdivacky      std::string TypeStr;
1004198092Srdivacky      Context.getObjCEncodingForMethodDecl(setter,TypeStr);
1005198092Srdivacky      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1006198092Srdivacky      InstanceMethodTypes.push_back(TypeEncoding);
1007198092Srdivacky      Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
1008198092Srdivacky      Fields.push_back(TypeEncoding);
1009198092Srdivacky    } else {
1010198092Srdivacky      Fields.push_back(NULLPtr);
1011198092Srdivacky      Fields.push_back(NULLPtr);
1012198092Srdivacky    }
1013198092Srdivacky    if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) {
1014198092Srdivacky      OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1015198092Srdivacky    } else {
1016198092Srdivacky      Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1017198092Srdivacky    }
1018198092Srdivacky  }
1019198092Srdivacky  llvm::Constant *PropertyArray = llvm::ConstantArray::get(
1020198092Srdivacky      llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
1021198092Srdivacky  llvm::Constant* PropertyListInitFields[] =
1022198092Srdivacky    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
1023198092Srdivacky
1024198092Srdivacky  llvm::Constant *PropertyListInit =
1025198092Srdivacky      llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false);
1026198092Srdivacky  llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule,
1027198092Srdivacky      PropertyListInit->getType(), false, llvm::GlobalValue::InternalLinkage,
1028198092Srdivacky      PropertyListInit, ".objc_property_list");
1029198092Srdivacky
1030198092Srdivacky  llvm::Constant *OptionalPropertyArray =
1031198092Srdivacky      llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
1032198092Srdivacky          OptionalProperties.size()) , OptionalProperties);
1033198092Srdivacky  llvm::Constant* OptionalPropertyListInitFields[] = {
1034198092Srdivacky      llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
1035198092Srdivacky      OptionalPropertyArray };
1036198092Srdivacky
1037198092Srdivacky  llvm::Constant *OptionalPropertyListInit =
1038198092Srdivacky      llvm::ConstantStruct::get(VMContext, OptionalPropertyListInitFields, 3, false);
1039198092Srdivacky  llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(TheModule,
1040198092Srdivacky          OptionalPropertyListInit->getType(), false,
1041198092Srdivacky          llvm::GlobalValue::InternalLinkage, OptionalPropertyListInit,
1042198092Srdivacky          ".objc_property_list");
1043198092Srdivacky
1044193326Sed  // Protocols are objects containing lists of the methods implemented and
1045193326Sed  // protocols adopted.
1046198092Srdivacky  llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy,
1047193326Sed      PtrToInt8Ty,
1048193326Sed      ProtocolList->getType(),
1049193326Sed      InstanceMethodList->getType(),
1050193326Sed      ClassMethodList->getType(),
1051198092Srdivacky      OptionalInstanceMethodList->getType(),
1052198092Srdivacky      OptionalClassMethodList->getType(),
1053198092Srdivacky      PropertyList->getType(),
1054198092Srdivacky      OptionalPropertyList->getType(),
1055193326Sed      NULL);
1056198092Srdivacky  std::vector<llvm::Constant*> Elements;
1057193326Sed  // The isa pointer must be set to a magic number so the runtime knows it's
1058193326Sed  // the correct layout.
1059198092Srdivacky  int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ?
1060198092Srdivacky      NonFragileProtocolVersion : ProtocolVersion;
1061193326Sed  Elements.push_back(llvm::ConstantExpr::getIntToPtr(
1062198092Srdivacky        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy));
1063193326Sed  Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
1064193326Sed  Elements.push_back(ProtocolList);
1065193326Sed  Elements.push_back(InstanceMethodList);
1066193326Sed  Elements.push_back(ClassMethodList);
1067198092Srdivacky  Elements.push_back(OptionalInstanceMethodList);
1068198092Srdivacky  Elements.push_back(OptionalClassMethodList);
1069198092Srdivacky  Elements.push_back(PropertyList);
1070198092Srdivacky  Elements.push_back(OptionalPropertyList);
1071198092Srdivacky  ExistingProtocols[ProtocolName] =
1072193326Sed    llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
1073193326Sed          ".objc_protocol"), IdTy);
1074193326Sed}
1075198092Srdivackyvoid CGObjCGNU::GenerateProtocolHolderCategory(void) {
1076198092Srdivacky  // Collect information about instance methods
1077198092Srdivacky  llvm::SmallVector<Selector, 1> MethodSels;
1078198092Srdivacky  llvm::SmallVector<llvm::Constant*, 1> MethodTypes;
1079193326Sed
1080198092Srdivacky  std::vector<llvm::Constant*> Elements;
1081198092Srdivacky  const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack";
1082198092Srdivacky  const std::string CategoryName = "AnotherHack";
1083198092Srdivacky  Elements.push_back(MakeConstantString(CategoryName));
1084198092Srdivacky  Elements.push_back(MakeConstantString(ClassName));
1085198092Srdivacky  // Instance method list
1086198092Srdivacky  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1087198092Srdivacky          ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy));
1088198092Srdivacky  // Class method list
1089198092Srdivacky  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1090198092Srdivacky          ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy));
1091198092Srdivacky  // Protocol list
1092198092Srdivacky  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
1093198092Srdivacky      ExistingProtocols.size());
1094198092Srdivacky  llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext,
1095198092Srdivacky      PtrTy, //Should be a recurisve pointer, but it's always NULL here.
1096198092Srdivacky      LongTy,//FIXME: Should be size_t
1097198092Srdivacky      ProtocolArrayTy,
1098198092Srdivacky      NULL);
1099198092Srdivacky  std::vector<llvm::Constant*> ProtocolElements;
1100198092Srdivacky  for (llvm::StringMapIterator<llvm::Constant*> iter =
1101198092Srdivacky       ExistingProtocols.begin(), endIter = ExistingProtocols.end();
1102198092Srdivacky       iter != endIter ; iter++) {
1103198092Srdivacky    llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(),
1104198092Srdivacky            PtrTy);
1105198092Srdivacky    ProtocolElements.push_back(Ptr);
1106198092Srdivacky  }
1107198092Srdivacky  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1108198092Srdivacky      ProtocolElements);
1109198092Srdivacky  ProtocolElements.clear();
1110198092Srdivacky  ProtocolElements.push_back(NULLPtr);
1111198092Srdivacky  ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
1112198092Srdivacky              ExistingProtocols.size()));
1113198092Srdivacky  ProtocolElements.push_back(ProtocolArray);
1114198092Srdivacky  Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy,
1115198092Srdivacky                  ProtocolElements, ".objc_protocol_list"), PtrTy));
1116198092Srdivacky  Categories.push_back(llvm::ConstantExpr::getBitCast(
1117198092Srdivacky        MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty,
1118198092Srdivacky            PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
1119198092Srdivacky}
1120198092Srdivacky
1121193326Sedvoid CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
1122193326Sed  std::string ClassName = OCD->getClassInterface()->getNameAsString();
1123193326Sed  std::string CategoryName = OCD->getNameAsString();
1124193326Sed  // Collect information about instance methods
1125193326Sed  llvm::SmallVector<Selector, 16> InstanceMethodSels;
1126193326Sed  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
1127193326Sed  for (ObjCCategoryImplDecl::instmeth_iterator
1128195341Sed         iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end();
1129193326Sed       iter != endIter ; iter++) {
1130193326Sed    InstanceMethodSels.push_back((*iter)->getSelector());
1131193326Sed    std::string TypeStr;
1132193326Sed    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
1133198092Srdivacky    InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1134193326Sed  }
1135193326Sed
1136193326Sed  // Collect information about class methods
1137193326Sed  llvm::SmallVector<Selector, 16> ClassMethodSels;
1138193326Sed  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
1139198092Srdivacky  for (ObjCCategoryImplDecl::classmeth_iterator
1140195341Sed         iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end();
1141193326Sed       iter != endIter ; iter++) {
1142193326Sed    ClassMethodSels.push_back((*iter)->getSelector());
1143193326Sed    std::string TypeStr;
1144193326Sed    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
1145198092Srdivacky    ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1146193326Sed  }
1147193326Sed
1148193326Sed  // Collect the names of referenced protocols
1149193326Sed  llvm::SmallVector<std::string, 16> Protocols;
1150205219Srdivacky  const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl();
1151205219Srdivacky  const ObjCList<ObjCProtocolDecl> &Protos = CatDecl->getReferencedProtocols();
1152193326Sed  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
1153193326Sed       E = Protos.end(); I != E; ++I)
1154193326Sed    Protocols.push_back((*I)->getNameAsString());
1155193326Sed
1156193326Sed  std::vector<llvm::Constant*> Elements;
1157193326Sed  Elements.push_back(MakeConstantString(CategoryName));
1158193326Sed  Elements.push_back(MakeConstantString(ClassName));
1159198092Srdivacky  // Instance method list
1160193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1161193326Sed          ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
1162193326Sed          false), PtrTy));
1163193326Sed  // Class method list
1164193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1165193326Sed          ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true),
1166193326Sed        PtrTy));
1167193326Sed  // Protocol list
1168193326Sed  Elements.push_back(llvm::ConstantExpr::getBitCast(
1169193326Sed        GenerateProtocolList(Protocols), PtrTy));
1170193326Sed  Categories.push_back(llvm::ConstantExpr::getBitCast(
1171198092Srdivacky        MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty,
1172198092Srdivacky            PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
1173193326Sed}
1174193326Sed
1175198092Srdivackyllvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OID,
1176198092Srdivacky        llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
1177198092Srdivacky        llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) {
1178198092Srdivacky  ASTContext &Context = CGM.getContext();
1179198092Srdivacky  //
1180198092Srdivacky  // Property metadata: name, attributes, isSynthesized, setter name, setter
1181198092Srdivacky  // types, getter name, getter types.
1182198092Srdivacky  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext,
1183198092Srdivacky          PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
1184198092Srdivacky          PtrToInt8Ty, NULL);
1185198092Srdivacky  std::vector<llvm::Constant*> Properties;
1186198092Srdivacky
1187198092Srdivacky
1188198092Srdivacky  // Add all of the property methods need adding to the method list and to the
1189198092Srdivacky  // property metadata list.
1190198092Srdivacky  for (ObjCImplDecl::propimpl_iterator
1191198092Srdivacky         iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
1192198092Srdivacky       iter != endIter ; iter++) {
1193198092Srdivacky    std::vector<llvm::Constant*> Fields;
1194198092Srdivacky    ObjCPropertyDecl *property = (*iter)->getPropertyDecl();
1195204643Srdivacky    ObjCPropertyImplDecl *propertyImpl = *iter;
1196204643Srdivacky    bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
1197204643Srdivacky        ObjCPropertyImplDecl::Synthesize);
1198198092Srdivacky
1199198092Srdivacky    Fields.push_back(MakeConstantString(property->getNameAsString()));
1200198092Srdivacky    Fields.push_back(llvm::ConstantInt::get(Int8Ty,
1201198092Srdivacky                property->getPropertyAttributes()));
1202204643Srdivacky    Fields.push_back(llvm::ConstantInt::get(Int8Ty, isSynthesized));
1203198092Srdivacky    if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
1204198092Srdivacky      std::string TypeStr;
1205198092Srdivacky      Context.getObjCEncodingForMethodDecl(getter,TypeStr);
1206198092Srdivacky      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1207204643Srdivacky      if (isSynthesized) {
1208204643Srdivacky        InstanceMethodTypes.push_back(TypeEncoding);
1209204643Srdivacky        InstanceMethodSels.push_back(getter->getSelector());
1210204643Srdivacky      }
1211198092Srdivacky      Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
1212198092Srdivacky      Fields.push_back(TypeEncoding);
1213198092Srdivacky    } else {
1214198092Srdivacky      Fields.push_back(NULLPtr);
1215198092Srdivacky      Fields.push_back(NULLPtr);
1216198092Srdivacky    }
1217198092Srdivacky    if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
1218198092Srdivacky      std::string TypeStr;
1219198092Srdivacky      Context.getObjCEncodingForMethodDecl(setter,TypeStr);
1220198092Srdivacky      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1221204643Srdivacky      if (isSynthesized) {
1222204643Srdivacky        InstanceMethodTypes.push_back(TypeEncoding);
1223204643Srdivacky        InstanceMethodSels.push_back(setter->getSelector());
1224204643Srdivacky      }
1225198092Srdivacky      Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
1226198092Srdivacky      Fields.push_back(TypeEncoding);
1227198092Srdivacky    } else {
1228198092Srdivacky      Fields.push_back(NULLPtr);
1229198092Srdivacky      Fields.push_back(NULLPtr);
1230198092Srdivacky    }
1231198092Srdivacky    Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1232198092Srdivacky  }
1233198092Srdivacky  llvm::ArrayType *PropertyArrayTy =
1234198092Srdivacky      llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
1235198092Srdivacky  llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
1236198092Srdivacky          Properties);
1237198092Srdivacky  llvm::Constant* PropertyListInitFields[] =
1238198092Srdivacky    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
1239198092Srdivacky
1240198092Srdivacky  llvm::Constant *PropertyListInit =
1241198092Srdivacky      llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false);
1242198092Srdivacky  return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(), false,
1243198092Srdivacky          llvm::GlobalValue::InternalLinkage, PropertyListInit,
1244198092Srdivacky          ".objc_property_list");
1245198092Srdivacky}
1246198092Srdivacky
1247193326Sedvoid CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
1248193326Sed  ASTContext &Context = CGM.getContext();
1249193326Sed
1250193326Sed  // Get the superclass name.
1251198092Srdivacky  const ObjCInterfaceDecl * SuperClassDecl =
1252193326Sed    OID->getClassInterface()->getSuperClass();
1253193326Sed  std::string SuperClassName;
1254194613Sed  if (SuperClassDecl) {
1255193326Sed    SuperClassName = SuperClassDecl->getNameAsString();
1256194613Sed    EmitClassRef(SuperClassName);
1257194613Sed  }
1258193326Sed
1259193326Sed  // Get the class name
1260193326Sed  ObjCInterfaceDecl *ClassDecl =
1261193326Sed    const_cast<ObjCInterfaceDecl *>(OID->getClassInterface());
1262193326Sed  std::string ClassName = ClassDecl->getNameAsString();
1263194613Sed  // Emit the symbol that is used to generate linker errors if this class is
1264194613Sed  // referenced in other modules but not declared.
1265195341Sed  std::string classSymbolName = "__objc_class_name_" + ClassName;
1266198092Srdivacky  if (llvm::GlobalVariable *symbol =
1267195341Sed      TheModule.getGlobalVariable(classSymbolName)) {
1268195341Sed    symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
1269195341Sed  } else {
1270198092Srdivacky    new llvm::GlobalVariable(TheModule, LongTy, false,
1271198092Srdivacky    llvm::GlobalValue::ExternalLinkage, llvm::ConstantInt::get(LongTy, 0),
1272198092Srdivacky    classSymbolName);
1273195341Sed  }
1274198092Srdivacky
1275193326Sed  // Get the size of instances.
1276193326Sed  int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8;
1277193326Sed
1278193326Sed  // Collect information about instance variables.
1279193326Sed  llvm::SmallVector<llvm::Constant*, 16> IvarNames;
1280193326Sed  llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
1281193326Sed  llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
1282198092Srdivacky
1283198092Srdivacky  std::vector<llvm::Constant*> IvarOffsetValues;
1284198092Srdivacky
1285198092Srdivacky  int superInstanceSize = !SuperClassDecl ? 0 :
1286193326Sed    Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8;
1287193326Sed  // For non-fragile ivars, set the instance size to 0 - {the size of just this
1288193326Sed  // class}.  The runtime will then set this to the correct value on load.
1289193326Sed  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
1290193326Sed    instanceSize = 0 - (instanceSize - superInstanceSize);
1291193326Sed  }
1292193326Sed  for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
1293193326Sed      endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
1294193326Sed      // Store the name
1295198092Srdivacky      IvarNames.push_back(MakeConstantString((*iter)->getNameAsString()));
1296193326Sed      // Get the type encoding for this ivar
1297193326Sed      std::string TypeStr;
1298193326Sed      Context.getObjCEncodingForType((*iter)->getType(), TypeStr);
1299198092Srdivacky      IvarTypes.push_back(MakeConstantString(TypeStr));
1300193326Sed      // Get the offset
1301198092Srdivacky      uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter);
1302199482Srdivacky      uint64_t Offset = BaseOffset;
1303193326Sed      if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
1304198092Srdivacky        Offset = BaseOffset - superInstanceSize;
1305193326Sed      }
1306193326Sed      IvarOffsets.push_back(
1307198092Srdivacky          llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset));
1308198092Srdivacky      IvarOffsetValues.push_back(new llvm::GlobalVariable(TheModule, IntTy,
1309198092Srdivacky          false, llvm::GlobalValue::ExternalLinkage,
1310198092Srdivacky          llvm::ConstantInt::get(IntTy, BaseOffset),
1311198092Srdivacky          "__objc_ivar_offset_value_" + ClassName +"." +
1312198092Srdivacky          (*iter)->getNameAsString()));
1313193326Sed  }
1314198092Srdivacky  llvm::Constant *IvarOffsetArrayInit =
1315198092Srdivacky      llvm::ConstantArray::get(llvm::ArrayType::get(PtrToIntTy,
1316198092Srdivacky                  IvarOffsetValues.size()), IvarOffsetValues);
1317198092Srdivacky  llvm::GlobalVariable *IvarOffsetArray = new llvm::GlobalVariable(TheModule,
1318198092Srdivacky          IvarOffsetArrayInit->getType(), false,
1319198092Srdivacky          llvm::GlobalValue::InternalLinkage, IvarOffsetArrayInit,
1320198092Srdivacky          ".ivar.offsets");
1321193326Sed
1322193326Sed  // Collect information about instance methods
1323193326Sed  llvm::SmallVector<Selector, 16> InstanceMethodSels;
1324193326Sed  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
1325198092Srdivacky  for (ObjCImplementationDecl::instmeth_iterator
1326195341Sed         iter = OID->instmeth_begin(), endIter = OID->instmeth_end();
1327193326Sed       iter != endIter ; iter++) {
1328193326Sed    InstanceMethodSels.push_back((*iter)->getSelector());
1329193326Sed    std::string TypeStr;
1330193326Sed    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
1331198092Srdivacky    InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1332193326Sed  }
1333193326Sed
1334198092Srdivacky  llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
1335198092Srdivacky          InstanceMethodTypes);
1336198092Srdivacky
1337198092Srdivacky
1338193326Sed  // Collect information about class methods
1339193326Sed  llvm::SmallVector<Selector, 16> ClassMethodSels;
1340193326Sed  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
1341193326Sed  for (ObjCImplementationDecl::classmeth_iterator
1342195341Sed         iter = OID->classmeth_begin(), endIter = OID->classmeth_end();
1343193326Sed       iter != endIter ; iter++) {
1344193326Sed    ClassMethodSels.push_back((*iter)->getSelector());
1345193326Sed    std::string TypeStr;
1346193326Sed    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
1347198092Srdivacky    ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1348193326Sed  }
1349193326Sed  // Collect the names of referenced protocols
1350193326Sed  llvm::SmallVector<std::string, 16> Protocols;
1351193326Sed  const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
1352193326Sed  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
1353193326Sed       E = Protos.end(); I != E; ++I)
1354193326Sed    Protocols.push_back((*I)->getNameAsString());
1355193326Sed
1356193326Sed
1357193326Sed
1358193326Sed  // Get the superclass pointer.
1359193326Sed  llvm::Constant *SuperClass;
1360193326Sed  if (!SuperClassName.empty()) {
1361193326Sed    SuperClass = MakeConstantString(SuperClassName, ".super_class_name");
1362193326Sed  } else {
1363193326Sed    SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
1364193326Sed  }
1365193326Sed  // Empty vector used to construct empty method lists
1366193326Sed  llvm::SmallVector<llvm::Constant*, 1>  empty;
1367193326Sed  // Generate the method and instance variable lists
1368193326Sed  llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
1369193326Sed      InstanceMethodSels, InstanceMethodTypes, false);
1370193326Sed  llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
1371193326Sed      ClassMethodSels, ClassMethodTypes, true);
1372193326Sed  llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
1373193326Sed      IvarOffsets);
1374198092Srdivacky  // Irrespective of whether we are compiling for a fragile or non-fragile ABI,
1375198092Srdivacky  // we emit a symbol containing the offset for each ivar in the class.  This
1376198092Srdivacky  // allows code compiled for the non-Fragile ABI to inherit from code compiled
1377198092Srdivacky  // for the legacy ABI, without causing problems.  The converse is also
1378198092Srdivacky  // possible, but causes all ivar accesses to be fragile.
1379198092Srdivacky  int i = 0;
1380198092Srdivacky  // Offset pointer for getting at the correct field in the ivar list when
1381198092Srdivacky  // setting up the alias.  These are: The base address for the global, the
1382198092Srdivacky  // ivar array (second field), the ivar in this list (set for each ivar), and
1383198092Srdivacky  // the offset (third field in ivar structure)
1384198092Srdivacky  const llvm::Type *IndexTy = llvm::Type::getInt32Ty(VMContext);
1385198092Srdivacky  llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
1386198092Srdivacky      llvm::ConstantInt::get(IndexTy, 1), 0,
1387198092Srdivacky      llvm::ConstantInt::get(IndexTy, 2) };
1388198092Srdivacky
1389198092Srdivacky  for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
1390198092Srdivacky      endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
1391198092Srdivacky      const std::string Name = "__objc_ivar_offset_" + ClassName + '.'
1392198092Srdivacky          +(*iter)->getNameAsString();
1393198092Srdivacky      offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i++);
1394198092Srdivacky      // Get the correct ivar field
1395198092Srdivacky      llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
1396198092Srdivacky              IvarList, offsetPointerIndexes, 4);
1397198092Srdivacky      // Get the existing alias, if one exists.
1398198092Srdivacky      llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
1399198092Srdivacky      if (offset) {
1400198092Srdivacky          offset->setInitializer(offsetValue);
1401198092Srdivacky          // If this is the real definition, change its linkage type so that
1402198092Srdivacky          // different modules will use this one, rather than their private
1403198092Srdivacky          // copy.
1404198092Srdivacky          offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
1405198092Srdivacky      } else {
1406198092Srdivacky          // Add a new alias if there isn't one already.
1407198092Srdivacky          offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(),
1408198092Srdivacky                  false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
1409198092Srdivacky      }
1410198092Srdivacky  }
1411193326Sed  //Generate metaclass for class methods
1412193326Sed  llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
1413199482Srdivacky      NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList(
1414198092Srdivacky        empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr, NULLPtr);
1415193326Sed
1416193326Sed  // Generate the class structure
1417193326Sed  llvm::Constant *ClassStruct =
1418198092Srdivacky    GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L,
1419193326Sed                           ClassName.c_str(), 0,
1420193326Sed      llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
1421198092Srdivacky      MethodList, GenerateProtocolList(Protocols), IvarOffsetArray,
1422198092Srdivacky      Properties);
1423193326Sed
1424193326Sed  // Resolve the class aliases, if they exist.
1425193326Sed  if (ClassPtrAlias) {
1426193326Sed    ClassPtrAlias->setAliasee(
1427193326Sed        llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
1428193326Sed    ClassPtrAlias = 0;
1429193326Sed  }
1430193326Sed  if (MetaClassPtrAlias) {
1431193326Sed    MetaClassPtrAlias->setAliasee(
1432193326Sed        llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
1433193326Sed    MetaClassPtrAlias = 0;
1434193326Sed  }
1435193326Sed
1436193326Sed  // Add class structure to list to be added to the symtab later
1437193326Sed  ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
1438193326Sed  Classes.push_back(ClassStruct);
1439193326Sed}
1440193326Sed
1441195099Sed
1442198092Srdivackyllvm::Function *CGObjCGNU::ModuleInitFunction() {
1443193326Sed  // Only emit an ObjC load function if no Objective-C stuff has been called
1444193326Sed  if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
1445193326Sed      ExistingProtocols.empty() && TypedSelectors.empty() &&
1446193326Sed      UntypedSelectors.empty())
1447193326Sed    return NULL;
1448193326Sed
1449198092Srdivacky  // Add all referenced protocols to a category.
1450198092Srdivacky  GenerateProtocolHolderCategory();
1451198092Srdivacky
1452193326Sed  const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
1453193326Sed          SelectorTy->getElementType());
1454193326Sed  const llvm::Type *SelStructPtrTy = SelectorTy;
1455193326Sed  bool isSelOpaque = false;
1456193326Sed  if (SelStructTy == 0) {
1457198092Srdivacky    SelStructTy = llvm::StructType::get(VMContext, PtrToInt8Ty,
1458198092Srdivacky                                        PtrToInt8Ty, NULL);
1459193326Sed    SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
1460193326Sed    isSelOpaque = true;
1461193326Sed  }
1462193326Sed
1463193326Sed  // Name the ObjC types to make the IR a bit easier to read
1464193326Sed  TheModule.addTypeName(".objc_selector", SelStructPtrTy);
1465193326Sed  TheModule.addTypeName(".objc_id", IdTy);
1466193326Sed  TheModule.addTypeName(".objc_imp", IMPTy);
1467193326Sed
1468193326Sed  std::vector<llvm::Constant*> Elements;
1469193326Sed  llvm::Constant *Statics = NULLPtr;
1470193326Sed  // Generate statics list:
1471193326Sed  if (ConstantStrings.size()) {
1472193326Sed    llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
1473193326Sed        ConstantStrings.size() + 1);
1474193326Sed    ConstantStrings.push_back(NULLPtr);
1475198092Srdivacky
1476199990Srdivacky    llvm::StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass;
1477199990Srdivacky    if (StringClass.empty()) StringClass = "NXConstantString";
1478198092Srdivacky    Elements.push_back(MakeConstantString(StringClass,
1479198092Srdivacky                ".objc_static_class_name"));
1480193326Sed    Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
1481193326Sed       ConstantStrings));
1482198092Srdivacky    llvm::StructType *StaticsListTy =
1483198092Srdivacky      llvm::StructType::get(VMContext, PtrToInt8Ty, StaticsArrayTy, NULL);
1484198092Srdivacky    llvm::Type *StaticsListPtrTy =
1485198092Srdivacky      llvm::PointerType::getUnqual(StaticsListTy);
1486193326Sed    Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics");
1487193326Sed    llvm::ArrayType *StaticsListArrayTy =
1488193326Sed      llvm::ArrayType::get(StaticsListPtrTy, 2);
1489193326Sed    Elements.clear();
1490193326Sed    Elements.push_back(Statics);
1491193326Sed    Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
1492193326Sed    Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr");
1493193326Sed    Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
1494193326Sed  }
1495193326Sed  // Array of classes, categories, and constant objects
1496193326Sed  llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
1497193326Sed      Classes.size() + Categories.size()  + 2);
1498198092Srdivacky  llvm::StructType *SymTabTy = llvm::StructType::get(VMContext,
1499198092Srdivacky                                                     LongTy, SelStructPtrTy,
1500198092Srdivacky                                                     llvm::Type::getInt16Ty(VMContext),
1501198092Srdivacky                                                     llvm::Type::getInt16Ty(VMContext),
1502193326Sed                                                     ClassListTy, NULL);
1503193326Sed
1504193326Sed  Elements.clear();
1505193326Sed  // Pointer to an array of selectors used in this module.
1506193326Sed  std::vector<llvm::Constant*> Selectors;
1507193326Sed  for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
1508193326Sed     iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end();
1509193326Sed     iter != iterEnd ; ++iter) {
1510198092Srdivacky    Elements.push_back(ExportUniqueString(iter->first.first, ".objc_sel_name"));
1511193326Sed    Elements.push_back(MakeConstantString(iter->first.second,
1512193326Sed                                          ".objc_sel_types"));
1513193326Sed    Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
1514193326Sed    Elements.clear();
1515193326Sed  }
1516193326Sed  for (llvm::StringMap<llvm::GlobalAlias*>::iterator
1517193326Sed      iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
1518193326Sed      iter != iterEnd; ++iter) {
1519193326Sed    Elements.push_back(
1520198092Srdivacky        ExportUniqueString(iter->getKeyData(), ".objc_sel_name"));
1521193326Sed    Elements.push_back(NULLPtr);
1522193326Sed    Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
1523193326Sed    Elements.clear();
1524193326Sed  }
1525193326Sed  Elements.push_back(NULLPtr);
1526193326Sed  Elements.push_back(NULLPtr);
1527193326Sed  Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
1528193326Sed  Elements.clear();
1529193326Sed  // Number of static selectors
1530193326Sed  Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() ));
1531193326Sed  llvm::Constant *SelectorList = MakeGlobal(
1532193326Sed          llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors,
1533193326Sed          ".objc_selector_list");
1534198092Srdivacky  Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
1535193326Sed    SelStructPtrTy));
1536193326Sed
1537193326Sed  // Now that all of the static selectors exist, create pointers to them.
1538193326Sed  int index = 0;
1539193326Sed  for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
1540193326Sed     iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end();
1541193326Sed     iter != iterEnd; ++iter) {
1542193326Sed    llvm::Constant *Idxs[] = {Zeros[0],
1543198092Srdivacky      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]};
1544198092Srdivacky    llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy,
1545193326Sed        true, llvm::GlobalValue::InternalLinkage,
1546193326Sed        llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
1547198092Srdivacky        ".objc_sel_ptr");
1548193326Sed    // If selectors are defined as an opaque type, cast the pointer to this
1549193326Sed    // type.
1550193326Sed    if (isSelOpaque) {
1551193326Sed      SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
1552193326Sed        llvm::PointerType::getUnqual(SelectorTy));
1553193326Sed    }
1554193326Sed    (*iter).second->setAliasee(SelPtr);
1555193326Sed  }
1556193326Sed  for (llvm::StringMap<llvm::GlobalAlias*>::iterator
1557193326Sed      iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
1558193326Sed      iter != iterEnd; iter++) {
1559193326Sed    llvm::Constant *Idxs[] = {Zeros[0],
1560198092Srdivacky      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]};
1561198092Srdivacky    llvm::Constant *SelPtr = new llvm::GlobalVariable
1562198092Srdivacky      (TheModule, SelStructPtrTy,
1563198092Srdivacky       true, llvm::GlobalValue::InternalLinkage,
1564198092Srdivacky       llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
1565198092Srdivacky       ".objc_sel_ptr");
1566193326Sed    // If selectors are defined as an opaque type, cast the pointer to this
1567193326Sed    // type.
1568193326Sed    if (isSelOpaque) {
1569193326Sed      SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
1570193326Sed        llvm::PointerType::getUnqual(SelectorTy));
1571193326Sed    }
1572193326Sed    (*iter).second->setAliasee(SelPtr);
1573193326Sed  }
1574193326Sed  // Number of classes defined.
1575198092Srdivacky  Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
1576193326Sed        Classes.size()));
1577193326Sed  // Number of categories defined
1578198092Srdivacky  Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
1579193326Sed        Categories.size()));
1580193326Sed  // Create an array of classes, then categories, then static object instances
1581193326Sed  Classes.insert(Classes.end(), Categories.begin(), Categories.end());
1582193326Sed  //  NULL-terminated list of static object instances (mainly constant strings)
1583193326Sed  Classes.push_back(Statics);
1584193326Sed  Classes.push_back(NULLPtr);
1585193326Sed  llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
1586193326Sed  Elements.push_back(ClassList);
1587198092Srdivacky  // Construct the symbol table
1588193326Sed  llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements);
1589193326Sed
1590193326Sed  // The symbol table is contained in a module which has some version-checking
1591193326Sed  // constants
1592198092Srdivacky  llvm::StructType * ModuleTy = llvm::StructType::get(VMContext, LongTy, LongTy,
1593193326Sed      PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL);
1594193326Sed  Elements.clear();
1595193326Sed  // Runtime version used for compatibility checking.
1596193326Sed  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
1597198092Srdivacky    Elements.push_back(llvm::ConstantInt::get(LongTy,
1598193326Sed        NonFragileRuntimeVersion));
1599193326Sed  } else {
1600193326Sed    Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
1601193326Sed  }
1602193326Sed  // sizeof(ModuleTy)
1603203955Srdivacky  llvm::TargetData td(&TheModule);
1604198092Srdivacky  Elements.push_back(llvm::ConstantInt::get(LongTy,
1605198092Srdivacky                     td.getTypeSizeInBits(ModuleTy)/8));
1606193326Sed  //FIXME: Should be the path to the file where this module was declared
1607193326Sed  Elements.push_back(NULLPtr);
1608193326Sed  Elements.push_back(SymTab);
1609193326Sed  llvm::Value *Module = MakeGlobal(ModuleTy, Elements);
1610193326Sed
1611193326Sed  // Create the load function calling the runtime entry point with the module
1612193326Sed  // structure
1613193326Sed  llvm::Function * LoadFunction = llvm::Function::Create(
1614198092Srdivacky      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
1615193326Sed      llvm::GlobalValue::InternalLinkage, ".objc_load_function",
1616193326Sed      &TheModule);
1617198092Srdivacky  llvm::BasicBlock *EntryBB =
1618198092Srdivacky      llvm::BasicBlock::Create(VMContext, "entry", LoadFunction);
1619198092Srdivacky  CGBuilderTy Builder(VMContext);
1620193326Sed  Builder.SetInsertPoint(EntryBB);
1621193326Sed
1622193326Sed  std::vector<const llvm::Type*> Params(1,
1623193326Sed      llvm::PointerType::getUnqual(ModuleTy));
1624193326Sed  llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1625198092Srdivacky        llvm::Type::getVoidTy(VMContext), Params, true), "__objc_exec_class");
1626193326Sed  Builder.CreateCall(Register, Module);
1627193326Sed  Builder.CreateRetVoid();
1628193326Sed
1629193326Sed  return LoadFunction;
1630193326Sed}
1631193326Sed
1632193326Sedllvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
1633198092Srdivacky                                          const ObjCContainerDecl *CD) {
1634198092Srdivacky  const ObjCCategoryImplDecl *OCD =
1635193326Sed    dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext());
1636193326Sed  std::string CategoryName = OCD ? OCD->getNameAsString() : "";
1637205408Srdivacky  std::string ClassName = CD->getName();
1638193326Sed  std::string MethodName = OMD->getSelector().getAsString();
1639193326Sed  bool isClassMethod = !OMD->isInstanceMethod();
1640193326Sed
1641193326Sed  CodeGenTypes &Types = CGM.getTypes();
1642198092Srdivacky  const llvm::FunctionType *MethodTy =
1643193326Sed    Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
1644193326Sed  std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
1645193326Sed      MethodName, isClassMethod);
1646193326Sed
1647198092Srdivacky  llvm::Function *Method
1648198092Srdivacky    = llvm::Function::Create(MethodTy,
1649198092Srdivacky                             llvm::GlobalValue::InternalLinkage,
1650198092Srdivacky                             FunctionName,
1651198092Srdivacky                             &TheModule);
1652193326Sed  return Method;
1653193326Sed}
1654193326Sed
1655193326Sedllvm::Function *CGObjCGNU::GetPropertyGetFunction() {
1656198092Srdivacky  std::vector<const llvm::Type*> Params;
1657198092Srdivacky  const llvm::Type *BoolTy =
1658198092Srdivacky    CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
1659198092Srdivacky  Params.push_back(IdTy);
1660198092Srdivacky  Params.push_back(SelectorTy);
1661198092Srdivacky  // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64
1662198092Srdivacky  Params.push_back(LongTy);
1663198092Srdivacky  Params.push_back(BoolTy);
1664198092Srdivacky  // void objc_getProperty (id, SEL, ptrdiff_t, bool)
1665198092Srdivacky  const llvm::FunctionType *FTy =
1666198092Srdivacky    llvm::FunctionType::get(IdTy, Params, false);
1667198092Srdivacky  return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy,
1668198092Srdivacky                                                        "objc_getProperty"));
1669193326Sed}
1670193326Sed
1671193326Sedllvm::Function *CGObjCGNU::GetPropertySetFunction() {
1672198092Srdivacky  std::vector<const llvm::Type*> Params;
1673198092Srdivacky  const llvm::Type *BoolTy =
1674198092Srdivacky    CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
1675198092Srdivacky  Params.push_back(IdTy);
1676198092Srdivacky  Params.push_back(SelectorTy);
1677198092Srdivacky  // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64
1678198092Srdivacky  Params.push_back(LongTy);
1679198092Srdivacky  Params.push_back(IdTy);
1680198092Srdivacky  Params.push_back(BoolTy);
1681198092Srdivacky  Params.push_back(BoolTy);
1682198092Srdivacky  // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
1683198092Srdivacky  const llvm::FunctionType *FTy =
1684198092Srdivacky    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
1685198092Srdivacky  return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy,
1686198092Srdivacky                                                        "objc_setProperty"));
1687193326Sed}
1688193326Sed
1689198092Srdivackyllvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
1690198092Srdivacky  CodeGen::CodeGenTypes &Types = CGM.getTypes();
1691198092Srdivacky  ASTContext &Ctx = CGM.getContext();
1692198092Srdivacky  // void objc_enumerationMutation (id)
1693204643Srdivacky  llvm::SmallVector<CanQualType,1> Params;
1694198092Srdivacky  Params.push_back(ASTIdTy);
1695198092Srdivacky  const llvm::FunctionType *FTy =
1696203955Srdivacky    Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
1697203955Srdivacky                                                CC_Default, false), false);
1698198092Srdivacky  return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
1699193326Sed}
1700193326Sed
1701193326Sedvoid CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1702193326Sed                                          const Stmt &S) {
1703193326Sed  // Pointer to the personality function
1704193326Sed  llvm::Constant *Personality =
1705198092Srdivacky    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
1706195341Sed          true),
1707193326Sed        "__gnu_objc_personality_v0");
1708193326Sed  Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy);
1709193326Sed  std::vector<const llvm::Type*> Params;
1710193326Sed  Params.push_back(PtrTy);
1711193326Sed  llvm::Value *RethrowFn =
1712198092Srdivacky    CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
1713202379Srdivacky          Params, false), "_Unwind_Resume");
1714193326Sed
1715193326Sed  bool isTry = isa<ObjCAtTryStmt>(S);
1716193326Sed  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
1717193326Sed  llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
1718193326Sed  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
1719193326Sed  llvm::BasicBlock *CatchInCatch = CGF.createBasicBlock("catch.rethrow");
1720193326Sed  llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
1721193326Sed  llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
1722193326Sed  llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
1723193326Sed
1724201361Srdivacky  // @synchronized()
1725193326Sed  if (!isTry) {
1726193326Sed    std::vector<const llvm::Type*> Args(1, IdTy);
1727193326Sed    llvm::FunctionType *FTy =
1728198092Srdivacky      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
1729193326Sed    llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
1730198092Srdivacky    llvm::Value *SyncArg =
1731193326Sed      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
1732193326Sed    SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
1733193326Sed    CGF.Builder.CreateCall(SyncEnter, SyncArg);
1734193326Sed  }
1735193326Sed
1736193326Sed
1737193326Sed  // Push an EH context entry, used for handling rethrows and jumps
1738193326Sed  // through finally.
1739193326Sed  CGF.PushCleanupBlock(FinallyBlock);
1740193326Sed
1741193326Sed  // Emit the statements in the @try {} block
1742193326Sed  CGF.setInvokeDest(TryHandler);
1743193326Sed
1744193326Sed  CGF.EmitBlock(TryBlock);
1745198092Srdivacky  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
1746193326Sed                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
1747193326Sed
1748193326Sed  // Jump to @finally if there is no exception
1749193326Sed  CGF.EmitBranchThroughCleanup(FinallyEnd);
1750193326Sed
1751193326Sed  // Emit the handlers
1752193326Sed  CGF.EmitBlock(TryHandler);
1753193326Sed
1754193326Sed  // Get the correct versions of the exception handling intrinsics
1755198092Srdivacky  llvm::Value *llvm_eh_exception =
1756193326Sed    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
1757198092Srdivacky  llvm::Value *llvm_eh_selector =
1758198092Srdivacky    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
1759198092Srdivacky  llvm::Value *llvm_eh_typeid_for =
1760198092Srdivacky    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
1761193326Sed
1762193326Sed  // Exception object
1763193326Sed  llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
1764193326Sed  llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow");
1765193326Sed
1766193326Sed  llvm::SmallVector<llvm::Value*, 8> ESelArgs;
1767193326Sed  llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers;
1768193326Sed
1769193326Sed  ESelArgs.push_back(Exc);
1770193326Sed  ESelArgs.push_back(Personality);
1771193326Sed
1772193326Sed  bool HasCatchAll = false;
1773193326Sed  // Only @try blocks are allowed @catch blocks, but both can have @finally
1774193326Sed  if (isTry) {
1775193326Sed    if (const ObjCAtCatchStmt* CatchStmt =
1776193326Sed      cast<ObjCAtTryStmt>(S).getCatchStmts())  {
1777193326Sed      CGF.setInvokeDest(CatchInCatch);
1778193326Sed
1779193326Sed      for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
1780193326Sed        const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
1781198092Srdivacky        Handlers.push_back(std::make_pair(CatchDecl,
1782198092Srdivacky                                          CatchStmt->getCatchBody()));
1783193326Sed
1784193326Sed        // @catch() and @catch(id) both catch any ObjC exception
1785198092Srdivacky        if (!CatchDecl || CatchDecl->getType()->isObjCIdType()
1786193326Sed            || CatchDecl->getType()->isObjCQualifiedIdType()) {
1787193326Sed          // Use i8* null here to signal this is a catch all, not a cleanup.
1788193326Sed          ESelArgs.push_back(NULLPtr);
1789193326Sed          HasCatchAll = true;
1790193326Sed          // No further catches after this one will ever by reached
1791193326Sed          break;
1792198092Srdivacky        }
1793193326Sed
1794193326Sed        // All other types should be Objective-C interface pointer types.
1795198092Srdivacky        const ObjCObjectPointerType *OPT =
1796198092Srdivacky          CatchDecl->getType()->getAs<ObjCObjectPointerType>();
1797198092Srdivacky        assert(OPT && "Invalid @catch type.");
1798198092Srdivacky        const ObjCInterfaceType *IT =
1799198092Srdivacky          OPT->getPointeeType()->getAs<ObjCInterfaceType>();
1800193326Sed        assert(IT && "Invalid @catch type.");
1801193326Sed        llvm::Value *EHType =
1802193326Sed          MakeConstantString(IT->getDecl()->getNameAsString());
1803193326Sed        ESelArgs.push_back(EHType);
1804193326Sed      }
1805193326Sed    }
1806193326Sed  }
1807193326Sed
1808193326Sed  // We use a cleanup unless there was already a catch all.
1809193326Sed  if (!HasCatchAll) {
1810198092Srdivacky    ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
1811193326Sed    Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0));
1812193326Sed  }
1813193326Sed
1814193326Sed  // Find which handler was matched.
1815193326Sed  llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector,
1816193326Sed      ESelArgs.begin(), ESelArgs.end(), "selector");
1817193326Sed
1818193326Sed  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
1819193326Sed    const ParmVarDecl *CatchParam = Handlers[i].first;
1820193326Sed    const Stmt *CatchBody = Handlers[i].second;
1821193326Sed
1822193326Sed    llvm::BasicBlock *Next = 0;
1823193326Sed
1824193326Sed    // The last handler always matches.
1825193326Sed    if (i + 1 != e) {
1826193326Sed      assert(CatchParam && "Only last handler can be a catch all.");
1827193326Sed
1828193326Sed      // Test whether this block matches the type for the selector and branch
1829193326Sed      // to Match if it does, or to the next BB if it doesn't.
1830193326Sed      llvm::BasicBlock *Match = CGF.createBasicBlock("match");
1831193326Sed      Next = CGF.createBasicBlock("catch.next");
1832193326Sed      llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for,
1833193326Sed          CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy));
1834193326Sed      CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match,
1835193326Sed          Next);
1836193326Sed
1837193326Sed      CGF.EmitBlock(Match);
1838193326Sed    }
1839198092Srdivacky
1840193326Sed    if (CatchBody) {
1841193326Sed      llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc,
1842193326Sed          CGF.ConvertType(CatchParam->getType()));
1843198092Srdivacky
1844193326Sed      // Bind the catch parameter if it exists.
1845193326Sed      if (CatchParam) {
1846193326Sed        // CatchParam is a ParmVarDecl because of the grammar
1847193326Sed        // construction used to handle this, but for codegen purposes
1848193326Sed        // we treat this as a local decl.
1849193326Sed        CGF.EmitLocalBlockVarDecl(*CatchParam);
1850193326Sed        CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam));
1851193326Sed      }
1852193326Sed
1853193326Sed      CGF.ObjCEHValueStack.push_back(ExcObject);
1854193326Sed      CGF.EmitStmt(CatchBody);
1855193326Sed      CGF.ObjCEHValueStack.pop_back();
1856193326Sed
1857193326Sed      CGF.EmitBranchThroughCleanup(FinallyEnd);
1858193326Sed
1859193326Sed      if (Next)
1860193326Sed        CGF.EmitBlock(Next);
1861193326Sed    } else {
1862193326Sed      assert(!Next && "catchup should be last handler.");
1863193326Sed
1864193326Sed      CGF.Builder.CreateStore(Exc, RethrowPtr);
1865193326Sed      CGF.EmitBranchThroughCleanup(FinallyRethrow);
1866193326Sed    }
1867193326Sed  }
1868193326Sed  // The @finally block is a secondary landing pad for any exceptions thrown in
1869193326Sed  // @catch() blocks
1870193326Sed  CGF.EmitBlock(CatchInCatch);
1871193326Sed  Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
1872193326Sed  ESelArgs.clear();
1873193326Sed  ESelArgs.push_back(Exc);
1874193326Sed  ESelArgs.push_back(Personality);
1875201361Srdivacky  // If there is a @catch or @finally clause in outside of this one then we
1876201361Srdivacky  // need to make sure that we catch and rethrow it.
1877201361Srdivacky  if (PrevLandingPad) {
1878201361Srdivacky    ESelArgs.push_back(NULLPtr);
1879201361Srdivacky  } else {
1880201361Srdivacky    ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
1881201361Srdivacky  }
1882193326Sed  CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(),
1883193326Sed      "selector");
1884193326Sed  CGF.Builder.CreateCall(llvm_eh_typeid_for,
1885193326Sed      CGF.Builder.CreateIntToPtr(ESelArgs[2], PtrTy));
1886193326Sed  CGF.Builder.CreateStore(Exc, RethrowPtr);
1887193326Sed  CGF.EmitBranchThroughCleanup(FinallyRethrow);
1888193326Sed
1889193326Sed  CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
1890193326Sed
1891193326Sed  CGF.setInvokeDest(PrevLandingPad);
1892193326Sed
1893193326Sed  CGF.EmitBlock(FinallyBlock);
1894193326Sed
1895193326Sed
1896193326Sed  if (isTry) {
1897198092Srdivacky    if (const ObjCAtFinallyStmt* FinallyStmt =
1898193326Sed        cast<ObjCAtTryStmt>(S).getFinallyStmt())
1899193326Sed      CGF.EmitStmt(FinallyStmt->getFinallyBody());
1900193326Sed  } else {
1901193326Sed    // Emit 'objc_sync_exit(expr)' as finally's sole statement for
1902193326Sed    // @synchronized.
1903193326Sed    std::vector<const llvm::Type*> Args(1, IdTy);
1904193326Sed    llvm::FunctionType *FTy =
1905198092Srdivacky      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
1906193326Sed    llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
1907198092Srdivacky    llvm::Value *SyncArg =
1908193326Sed      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
1909193326Sed    SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
1910193326Sed    CGF.Builder.CreateCall(SyncExit, SyncArg);
1911193326Sed  }
1912193326Sed
1913193326Sed  if (Info.SwitchBlock)
1914193326Sed    CGF.EmitBlock(Info.SwitchBlock);
1915193326Sed  if (Info.EndBlock)
1916193326Sed    CGF.EmitBlock(Info.EndBlock);
1917193326Sed
1918193326Sed  // Branch around the rethrow code.
1919193326Sed  CGF.EmitBranch(FinallyEnd);
1920193326Sed
1921193326Sed  CGF.EmitBlock(FinallyRethrow);
1922198092Srdivacky
1923201361Srdivacky  llvm::Value *ExceptionObject = CGF.Builder.CreateLoad(RethrowPtr);
1924201361Srdivacky  llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
1925201361Srdivacky  if (!UnwindBB) {
1926201361Srdivacky    CGF.Builder.CreateCall(RethrowFn, ExceptionObject);
1927201361Srdivacky    // Exception always thrown, next instruction is never reached.
1928201361Srdivacky    CGF.Builder.CreateUnreachable();
1929201361Srdivacky  } else {
1930201361Srdivacky    // If there is a @catch block outside this scope, we invoke instead of
1931201361Srdivacky    // calling because we may return to this function.  This is very slow, but
1932201361Srdivacky    // some people still do it.  It would be nice to add an optimised path for
1933201361Srdivacky    // this.
1934201361Srdivacky    CGF.Builder.CreateInvoke(RethrowFn, UnwindBB, UnwindBB, &ExceptionObject,
1935201361Srdivacky        &ExceptionObject+1);
1936201361Srdivacky  }
1937201361Srdivacky
1938193326Sed  CGF.EmitBlock(FinallyEnd);
1939193326Sed}
1940193326Sed
1941193326Sedvoid CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1942193326Sed                              const ObjCAtThrowStmt &S) {
1943193326Sed  llvm::Value *ExceptionAsObject;
1944193326Sed
1945193326Sed  std::vector<const llvm::Type*> Args(1, IdTy);
1946193326Sed  llvm::FunctionType *FTy =
1947198092Srdivacky    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
1948198092Srdivacky  llvm::Value *ThrowFn =
1949193326Sed    CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
1950198092Srdivacky
1951193326Sed  if (const Expr *ThrowExpr = S.getThrowExpr()) {
1952193326Sed    llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
1953193326Sed    ExceptionAsObject = Exception;
1954193326Sed  } else {
1955198092Srdivacky    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
1956193326Sed           "Unexpected rethrow outside @catch block.");
1957193326Sed    ExceptionAsObject = CGF.ObjCEHValueStack.back();
1958193326Sed  }
1959193326Sed  ExceptionAsObject =
1960193326Sed      CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp");
1961198092Srdivacky
1962193326Sed  // Note: This may have to be an invoke, if we want to support constructs like:
1963193326Sed  // @try {
1964193326Sed  //  @throw(obj);
1965193326Sed  // }
1966193326Sed  // @catch(id) ...
1967193326Sed  //
1968193326Sed  // This is effectively turning @throw into an incredibly-expensive goto, but
1969193326Sed  // it may happen as a result of inlining followed by missed optimizations, or
1970193326Sed  // as a result of stupidity.
1971193326Sed  llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
1972193326Sed  if (!UnwindBB) {
1973193326Sed    CGF.Builder.CreateCall(ThrowFn, ExceptionAsObject);
1974193326Sed    CGF.Builder.CreateUnreachable();
1975193326Sed  } else {
1976193326Sed    CGF.Builder.CreateInvoke(ThrowFn, UnwindBB, UnwindBB, &ExceptionAsObject,
1977193326Sed        &ExceptionAsObject+1);
1978193326Sed  }
1979193326Sed  // Clear the insertion point to indicate we are in unreachable code.
1980193326Sed  CGF.Builder.ClearInsertionPoint();
1981193326Sed}
1982193326Sed
1983193326Sedllvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1984198092Srdivacky                                          llvm::Value *AddrWeakObj) {
1985203955Srdivacky  CGBuilderTy B = CGF.Builder;
1986203955Srdivacky  AddrWeakObj = EnforceType(B, AddrWeakObj, IdTy);
1987203955Srdivacky  return B.CreateCall(WeakReadFn, AddrWeakObj);
1988193326Sed}
1989193326Sed
1990193326Sedvoid CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1991198092Srdivacky                                   llvm::Value *src, llvm::Value *dst) {
1992203955Srdivacky  CGBuilderTy B = CGF.Builder;
1993203955Srdivacky  src = EnforceType(B, src, IdTy);
1994203955Srdivacky  dst = EnforceType(B, dst, PtrToIdTy);
1995203955Srdivacky  B.CreateCall2(WeakAssignFn, src, dst);
1996193326Sed}
1997193326Sed
1998193326Sedvoid CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1999198092Srdivacky                                     llvm::Value *src, llvm::Value *dst) {
2000203955Srdivacky  CGBuilderTy B = CGF.Builder;
2001203955Srdivacky  src = EnforceType(B, src, IdTy);
2002203955Srdivacky  dst = EnforceType(B, dst, PtrToIdTy);
2003203955Srdivacky  B.CreateCall2(GlobalAssignFn, src, dst);
2004193326Sed}
2005193326Sed
2006193326Sedvoid CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
2007198092Srdivacky                                   llvm::Value *src, llvm::Value *dst,
2008198092Srdivacky                                   llvm::Value *ivarOffset) {
2009203955Srdivacky  CGBuilderTy B = CGF.Builder;
2010203955Srdivacky  src = EnforceType(B, src, IdTy);
2011203955Srdivacky  dst = EnforceType(B, dst, PtrToIdTy);
2012203955Srdivacky  B.CreateCall3(IvarAssignFn, src, dst, ivarOffset);
2013193326Sed}
2014193326Sed
2015193326Sedvoid CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
2016198092Srdivacky                                         llvm::Value *src, llvm::Value *dst) {
2017203955Srdivacky  CGBuilderTy B = CGF.Builder;
2018203955Srdivacky  src = EnforceType(B, src, IdTy);
2019203955Srdivacky  dst = EnforceType(B, dst, PtrToIdTy);
2020203955Srdivacky  B.CreateCall2(StrongCastAssignFn, src, dst);
2021193326Sed}
2022193326Sed
2023198092Srdivackyvoid CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
2024198092Srdivacky                                         llvm::Value *DestPtr,
2025198092Srdivacky                                         llvm::Value *SrcPtr,
2026198092Srdivacky                                         QualType Ty) {
2027203955Srdivacky  CGBuilderTy B = CGF.Builder;
2028203955Srdivacky  DestPtr = EnforceType(B, DestPtr, IdTy);
2029203955Srdivacky  SrcPtr = EnforceType(B, SrcPtr, PtrToIdTy);
2030203955Srdivacky
2031203955Srdivacky  std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
2032203955Srdivacky  unsigned long size = TypeInfo.first/8;
2033203955Srdivacky  // FIXME: size_t
2034203955Srdivacky  llvm::Value *N = llvm::ConstantInt::get(LongTy, size);
2035203955Srdivacky
2036203955Srdivacky  B.CreateCall3(MemMoveFn, DestPtr, SrcPtr, N);
2037198092Srdivacky}
2038198092Srdivacky
2039193326Sedllvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
2040193326Sed                              const ObjCInterfaceDecl *ID,
2041193326Sed                              const ObjCIvarDecl *Ivar) {
2042193326Sed  const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
2043193326Sed    + '.' + Ivar->getNameAsString();
2044193326Sed  // Emit the variable and initialize it with what we think the correct value
2045193326Sed  // is.  This allows code compiled with non-fragile ivars to work correctly
2046193326Sed  // when linked against code which isn't (most of the time).
2047198092Srdivacky  llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
2048198092Srdivacky  if (!IvarOffsetPointer) {
2049193326Sed    uint64_t Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
2050193326Sed    llvm::ConstantInt *OffsetGuess =
2051202379Srdivacky      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset, "ivar");
2052198092Srdivacky    // Don't emit the guess in non-PIC code because the linker will not be able
2053198092Srdivacky    // to replace it with the real version for a library.  In non-PIC code you
2054198092Srdivacky    // must compile with the fragile ABI if you want to use ivars from a
2055198092Srdivacky    // GCC-compiled class.
2056198092Srdivacky    if (CGM.getLangOptions().PICLevel) {
2057198092Srdivacky      llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule,
2058198092Srdivacky            llvm::Type::getInt32Ty(VMContext), false,
2059198092Srdivacky            llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess");
2060198092Srdivacky      IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
2061198092Srdivacky            IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage,
2062198092Srdivacky            IvarOffsetGV, Name);
2063198092Srdivacky    } else {
2064198092Srdivacky      IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
2065198092Srdivacky              llvm::Type::getInt32PtrTy(VMContext), false,
2066198092Srdivacky              llvm::GlobalValue::ExternalLinkage, 0, Name);
2067198092Srdivacky    }
2068193326Sed  }
2069198092Srdivacky  return IvarOffsetPointer;
2070193326Sed}
2071193326Sed
2072193326SedLValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
2073193326Sed                                       QualType ObjectTy,
2074193326Sed                                       llvm::Value *BaseValue,
2075193326Sed                                       const ObjCIvarDecl *Ivar,
2076193326Sed                                       unsigned CVRQualifiers) {
2077198092Srdivacky  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
2078193326Sed  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2079193326Sed                                  EmitIvarOffset(CGF, ID, Ivar));
2080193326Sed}
2081198092Srdivacky
2082193326Sedstatic const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
2083193326Sed                                                  const ObjCInterfaceDecl *OID,
2084193326Sed                                                  const ObjCIvarDecl *OIVD) {
2085193326Sed  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
2086193576Sed  Context.ShallowCollectObjCIvars(OID, Ivars);
2087193326Sed  for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
2088193326Sed    if (OIVD == Ivars[k])
2089193326Sed      return OID;
2090193326Sed  }
2091198092Srdivacky
2092193326Sed  // Otherwise check in the super class.
2093193326Sed  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
2094193326Sed    return FindIvarInterface(Context, Super, OIVD);
2095198092Srdivacky
2096193326Sed  return 0;
2097193326Sed}
2098193326Sed
2099193326Sedllvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
2100193326Sed                         const ObjCInterfaceDecl *Interface,
2101193326Sed                         const ObjCIvarDecl *Ivar) {
2102198092Srdivacky  if (CGM.getLangOptions().ObjCNonFragileABI) {
2103193326Sed    Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar);
2104198092Srdivacky    return CGF.Builder.CreateLoad(CGF.Builder.CreateLoad(
2105198092Srdivacky                ObjCIvarOffsetVariable(Interface, Ivar), false, "ivar"));
2106193326Sed  }
2107193326Sed  uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
2108193326Sed  return llvm::ConstantInt::get(LongTy, Offset, "ivar");
2109193326Sed}
2110193326Sed
2111198092SrdivackyCodeGen::CGObjCRuntime *
2112198092SrdivackyCodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM) {
2113193326Sed  return new CGObjCGNU(CGM);
2114193326Sed}
2115