zcov: / lib/CodeGen/CGObjCGNU.cpp


Files: 1 Branches Taken: 58.0% 153 / 264
Generated: 2010-02-10 01:31 Branches Executed: 81.1% 214 / 264
Line Coverage: 77.1% 731 / 948


Programs: 1 Runs 2897


       1                 : //===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This provides Objective-C code generation targetting the GNU runtime.  The
      11                 : // class in this file generates structures used by the GNU Objective-C runtime
      12                 : // library.  These structures are defined in objc/objc.h and objc/objc-api.h in
      13                 : // the GNU runtime distribution.
      14                 : //
      15                 : //===----------------------------------------------------------------------===//
      16                 : 
      17                 : #include "CGObjCRuntime.h"
      18                 : #include "CodeGenModule.h"
      19                 : #include "CodeGenFunction.h"
      20                 : 
      21                 : #include "clang/AST/ASTContext.h"
      22                 : #include "clang/AST/Decl.h"
      23                 : #include "clang/AST/DeclObjC.h"
      24                 : #include "clang/AST/RecordLayout.h"
      25                 : #include "clang/AST/StmtObjC.h"
      26                 : 
      27                 : #include "llvm/Intrinsics.h"
      28                 : #include "llvm/Module.h"
      29                 : #include "llvm/ADT/SmallVector.h"
      30                 : #include "llvm/ADT/StringMap.h"
      31                 : #include "llvm/Support/Compiler.h"
      32                 : #include "llvm/Target/TargetData.h"
      33                 : 
      34                 : #include <map>
      35                 : 
      36                 : 
      37                 : using namespace clang;
      38                 : using namespace CodeGen;
      39                 : using llvm::dyn_cast;
      40                 : 
      41                 : // The version of the runtime that this class targets.  Must match the version
      42                 : // in the runtime.
      43                 : static const int RuntimeVersion = 8;
      44                 : static const int NonFragileRuntimeVersion = 9;
      45                 : static const int ProtocolVersion = 2;
      46                 : static const int NonFragileProtocolVersion = 3;
      47                 : 
      48                 : namespace {
                        6: branch 8 taken
                        0: branch 9 not taken
                        0: branch 19 not taken
                        0: branch 20 not taken
      49                6: class CGObjCGNU : public CodeGen::CGObjCRuntime {
      50                 : private:
      51                 :   CodeGen::CodeGenModule &CGM;
      52                 :   llvm::Module &TheModule;
      53                 :   const llvm::PointerType *SelectorTy;
      54                 :   const llvm::IntegerType *Int8Ty;
      55                 :   const llvm::PointerType *PtrToInt8Ty;
      56                 :   const llvm::FunctionType *IMPTy;
      57                 :   const llvm::PointerType *IdTy;
      58                 :   const llvm::PointerType *PtrToIdTy;
      59                 :   QualType ASTIdTy;
      60                 :   const llvm::IntegerType *IntTy;
      61                 :   const llvm::PointerType *PtrTy;
      62                 :   const llvm::IntegerType *LongTy;
      63                 :   const llvm::PointerType *PtrToIntTy;
      64                 :   llvm::GlobalAlias *ClassPtrAlias;
      65                 :   llvm::GlobalAlias *MetaClassPtrAlias;
      66                 :   std::vector<llvm::Constant*> Classes;
      67                 :   std::vector<llvm::Constant*> Categories;
      68                 :   std::vector<llvm::Constant*> ConstantStrings;
      69                 :   llvm::StringMap<llvm::Constant*> ObjCStrings;
      70                 :   llvm::Function *LoadFunction;
      71                 :   llvm::StringMap<llvm::Constant*> ExistingProtocols;
      72                 :   typedef std::pair<std::string, std::string> TypedSelector;
      73                 :   std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors;
      74                 :   llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors;
      75                 :   // Selectors that we don't emit in GC mode
      76                 :   Selector RetainSel, ReleaseSel, AutoreleaseSel;
      77                 :   // Functions used for GC.
      78                 :   llvm::Constant *IvarAssignFn, *StrongCastAssignFn, *MemMoveFn, *WeakReadFn, 
      79                 :     *WeakAssignFn, *GlobalAssignFn;
      80                 :   // Some zeros used for GEPs in lots of places.
      81                 :   llvm::Constant *Zeros[2];
      82                 :   llvm::Constant *NULLPtr;
      83                 :   llvm::LLVMContext &VMContext;
      84                 : private:
      85                 :   llvm::Constant *GenerateIvarList(
      86                 :       const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
      87                 :       const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
      88                 :       const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets);
      89                 :   llvm::Constant *GenerateMethodList(const std::string &ClassName,
      90                 :       const std::string &CategoryName,
      91                 :       const llvm::SmallVectorImpl<Selector>  &MethodSels,
      92                 :       const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes,
      93                 :       bool isClassMethodList);
      94                 :   llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName);
      95                 :   llvm::Constant *GeneratePropertyList(const ObjCImplementationDecl *OID,
      96                 :         llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
      97                 :         llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes);
      98                 :   llvm::Constant *GenerateProtocolList(
      99                 :       const llvm::SmallVectorImpl<std::string> &Protocols);
     100                 :   // To ensure that all protocols are seen by the runtime, we add a category on
     101                 :   // a class defined in the runtime, declaring no methods, but adopting the
     102                 :   // protocols.
     103                 :   void GenerateProtocolHolderCategory(void);
     104                 :   llvm::Constant *GenerateClassStructure(
     105                 :       llvm::Constant *MetaClass,
     106                 :       llvm::Constant *SuperClass,
     107                 :       unsigned info,
     108                 :       const char *Name,
     109                 :       llvm::Constant *Version,
     110                 :       llvm::Constant *InstanceSize,
     111                 :       llvm::Constant *IVars,
     112                 :       llvm::Constant *Methods,
     113                 :       llvm::Constant *Protocols,
     114                 :       llvm::Constant *IvarOffsets,
     115                 :       llvm::Constant *Properties);
     116                 :   llvm::Constant *GenerateProtocolMethodList(
     117                 :       const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
     118                 :       const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes);
     119                 :   llvm::Constant *MakeConstantString(const std::string &Str, const std::string
     120                 :       &Name="");
     121                 :   llvm::Constant *ExportUniqueString(const std::string &Str, const std::string
     122                 :           prefix);
     123                 :   llvm::Constant *MakeGlobal(const llvm::StructType *Ty,
     124                 :     std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
     125                 :     llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
     126                 :   llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty,
     127                 :     std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
     128                 :     llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
     129                 :   llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
     130                 :       const ObjCIvarDecl *Ivar);
     131                 :   void EmitClassRef(const std::string &className);
     132                0:   llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, const llvm::Type *Ty){
                        0: branch 1 not taken
                        0: branch 2 not taken
     133                0:     if (V->getType() == Ty) return V;
     134                0:     return B.CreateBitCast(V, Ty);
     135                 :   }
     136                 : public:
     137                 :   CGObjCGNU(CodeGen::CodeGenModule &cgm);
     138                 :   virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
     139                 :   virtual CodeGen::RValue
     140                 :   GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
     141                 :                       QualType ResultType,
     142                 :                       Selector Sel,
     143                 :                       llvm::Value *Receiver,
     144                 :                       bool IsClassMessage,
     145                 :                       const CallArgList &CallArgs,
     146                 :                       const ObjCMethodDecl *Method);
     147                 :   virtual CodeGen::RValue
     148                 :   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
     149                 :                            QualType ResultType,
     150                 :                            Selector Sel,
     151                 :                            const ObjCInterfaceDecl *Class,
     152                 :                            bool isCategoryImpl,
     153                 :                            llvm::Value *Receiver,
     154                 :                            bool IsClassMessage,
     155                 :                            const CallArgList &CallArgs,
     156                 :                            const ObjCMethodDecl *Method);
     157                 :   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
     158                 :                                 const ObjCInterfaceDecl *OID);
     159                 :   virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
     160                 :   virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
     161                 :       *Method);
     162                 : 
     163                 :   virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
     164                 :                                          const ObjCContainerDecl *CD);
     165                 :   virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
     166                 :   virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
     167                 :   virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
     168                 :                                            const ObjCProtocolDecl *PD);
     169                 :   virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
     170                 :   virtual llvm::Function *ModuleInitFunction();
     171                 :   virtual llvm::Function *GetPropertyGetFunction();
     172                 :   virtual llvm::Function *GetPropertySetFunction();
     173                 :   virtual llvm::Constant *EnumerationMutationFunction();
     174                 : 
     175                 :   virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
     176                 :                                          const Stmt &S);
     177                 :   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
     178                 :                              const ObjCAtThrowStmt &S);
     179                 :   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
     180                 :                                          llvm::Value *AddrWeakObj);
     181                 :   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
     182                 :                                   llvm::Value *src, llvm::Value *dst);
     183                 :   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
     184                 :                                     llvm::Value *src, llvm::Value *dest);
     185                 :   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
     186                 :                                     llvm::Value *src, llvm::Value *dest,
     187                 :                                     llvm::Value *ivarOffset);
     188                 :   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
     189                 :                                         llvm::Value *src, llvm::Value *dest);
     190                 :   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
     191                 :                                         llvm::Value *DestPtr,
     192                 :                                         llvm::Value *SrcPtr,
     193                 :                                         QualType Ty);
     194                 :   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
     195                 :                                       QualType ObjectTy,
     196                 :                                       llvm::Value *BaseValue,
     197                 :                                       const ObjCIvarDecl *Ivar,
     198                 :                                       unsigned CVRQualifiers);
     199                 :   virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
     200                 :                                       const ObjCInterfaceDecl *Interface,
     201                 :                                       const ObjCIvarDecl *Ivar);
     202                 : };
     203                 : } // end anonymous namespace
     204                 : 
     205                 : 
     206                 : /// Emits a reference to a dummy variable which is emitted with each class.
     207                 : /// This ensures that a linker error will be generated when trying to link
     208                 : /// together modules where a referenced class is not defined.
     209                2: void CGObjCGNU::EmitClassRef(const std::string &className) {
     210                2:   std::string symbolRef = "__objc_class_ref_" + className;
     211                 :   // Don't emit two copies of the same symbol
                        0: branch 2 not taken
                        2: branch 3 taken
     212                2:   if (TheModule.getGlobalVariable(symbolRef))
     213                0:     return;
     214                2:   std::string symbolName = "__objc_class_name_" + className;
     215                2:   llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
                        1: branch 0 taken
                        1: branch 1 taken
     216                2:   if (!ClassSymbol) {
     217                 :     ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
     218                1:         llvm::GlobalValue::ExternalLinkage, 0, symbolName);
     219                 :   }
     220                 :   new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true,
                        2: branch 6 taken
                        0: branch 7 not taken
     221                2:     llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
     222                 : }
     223                 : 
     224                6: static std::string SymbolNameForClass(const std::string &ClassName) {
     225                6:   return "_OBJC_CLASS_" + ClassName;
     226                 : }
     227                 : 
     228                 : static std::string SymbolNameForMethod(const std::string &ClassName, const
     229               15:   std::string &CategoryName, const std::string &MethodName, bool isClassMethod)
     230                 : {
     231               15:   std::string MethodNameColonStripped = MethodName;
     232                 :   std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
     233               15:       ':', '_');
     234                 :   return std::string(isClassMethod ? "_c_" : "_i_") + ClassName + "_" +
                        2: branch 1 taken
                       13: branch 2 taken
     235               15:     CategoryName + "_" + MethodNameColonStripped;
     236                 : }
     237                 : 
     238                7: CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
     239                 :   : CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
     240                7:     MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
     241                 :   IntTy = cast<llvm::IntegerType>(
     242                7:       CGM.getTypes().ConvertType(CGM.getContext().IntTy));
     243                 :   LongTy = cast<llvm::IntegerType>(
     244                7:       CGM.getTypes().ConvertType(CGM.getContext().LongTy));
     245                 : 
     246                7:   Int8Ty = llvm::Type::getInt8Ty(VMContext);
     247                 :   // C string type.  Used in lots of places.
     248                7:   PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
     249                 : 
     250                7:   Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
     251                7:   Zeros[1] = Zeros[0];
     252                7:   NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
     253                 :   // Get the selector Type.
     254                7:   QualType selTy = CGM.getContext().getObjCSelType();
                        0: branch 2 not taken
                        7: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     255                7:   if (QualType() == selTy) {
     256                0:     SelectorTy = PtrToInt8Ty;
     257                 :   } else {
     258                7:     SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
     259                 :   }
     260                 : 
     261                7:   PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
     262                7:   PtrTy = PtrToInt8Ty;
     263                 : 
     264                 :   // Object type
     265                7:   ASTIdTy = CGM.getContext().getObjCIdType();
                        0: branch 2 not taken
                        7: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     266                7:   if (QualType() == ASTIdTy) {
     267                0:     IdTy = PtrToInt8Ty;
     268                 :   } else {
     269                7:     IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
     270                 :   }
     271                7:   PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
     272                 : 
     273                 :   // IMP type
     274                7:   std::vector<const llvm::Type*> IMPArgs;
     275                7:   IMPArgs.push_back(IdTy);
     276                7:   IMPArgs.push_back(SelectorTy);
     277                7:   IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
     278                 : 
                        0: branch 2 not taken
                        7: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     279                7:   if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
     280                 :     // Get selectors needed in GC mode
     281                0:     RetainSel = GetNullarySelector("retain", CGM.getContext());
     282                0:     ReleaseSel = GetNullarySelector("release", CGM.getContext());
     283                0:     AutoreleaseSel = GetNullarySelector("autorelease", CGM.getContext());
     284                 : 
     285                 :     // Get functions needed in GC mode
     286                 : 
     287                 :     // id objc_assign_ivar(id, id, ptrdiff_t);
     288                0:     std::vector<const llvm::Type*> Args(1, IdTy);
     289                0:     Args.push_back(PtrToIdTy);
     290                 :     // FIXME: ptrdiff_t
     291                0:     Args.push_back(LongTy);
     292                0:     llvm::FunctionType *FTy = llvm::FunctionType::get(IdTy, Args, false);
     293                0:     IvarAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
     294                 :     // id objc_assign_strongCast (id, id*)
     295                0:     Args.pop_back();
     296                0:     FTy = llvm::FunctionType::get(IdTy, Args, false);
     297                 :     StrongCastAssignFn = 
     298                0:         CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
     299                 :     // id objc_assign_global(id, id*);
     300                0:     FTy = llvm::FunctionType::get(IdTy, Args, false);
     301                0:     GlobalAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
     302                 :     // id objc_assign_weak(id, id*);
     303                0:     FTy = llvm::FunctionType::get(IdTy, Args, false);
     304                0:     WeakAssignFn = CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
     305                 :     // id objc_read_weak(id*);
     306                0:     Args.clear();
     307                0:     Args.push_back(PtrToIdTy);
     308                0:     FTy = llvm::FunctionType::get(IdTy, Args, false);
     309                0:     WeakReadFn = CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
     310                 :     // void *objc_memmove_collectable(void*, void *, size_t);
     311                0:     Args.clear();
     312                0:     Args.push_back(PtrToInt8Ty);
     313                0:     Args.push_back(PtrToInt8Ty);
     314                 :     // FIXME: size_t
     315                0:     Args.push_back(LongTy);
     316                0:     FTy = llvm::FunctionType::get(IdTy, Args, false);
     317                0:     MemMoveFn = CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
     318                7:   }
     319                7: }
     320                 : 
     321                 : // This has to perform the lookup every time, since posing and related
     322                 : // techniques can modify the name -> class mapping.
     323                 : llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder,
     324                0:                                  const ObjCInterfaceDecl *OID) {
     325                0:   llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString());
     326                 :   // With the incompatible ABI, this will need to be replaced with a direct
     327                 :   // reference to the class symbol.  For the compatible nonfragile ABI we are
     328                 :   // still performing this lookup at run time but emitting the symbol for the
     329                 :   // class externally so that we can make the switch later.
     330                0:   EmitClassRef(OID->getNameAsString());
     331                0:   ClassName = Builder.CreateStructGEP(ClassName, 0);
     332                 : 
     333                0:   std::vector<const llvm::Type*> Params(1, PtrToInt8Ty);
     334                 :   llvm::Constant *ClassLookupFn =
     335                 :     CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy,
     336                 :                                                       Params,
     337                 :                                                       true),
     338                0:                               "objc_lookup_class");
     339                0:   return Builder.CreateCall(ClassLookupFn, ClassName);
     340                 : }
     341                 : 
     342               17: llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
     343               17:   llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()];
                       14: branch 0 taken
                        3: branch 1 taken
     344               17:   if (US == 0)
     345                 :     US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
     346                 :                                llvm::GlobalValue::PrivateLinkage,
     347                 :                                ".objc_untyped_selector_alias"+Sel.getAsString(),
     348               14:                                NULL, &TheModule);
     349                 : 
     350               17:   return Builder.CreateLoad(US);
     351                 : }
     352                 : 
     353                 : llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
     354                0:     *Method) {
     355                 : 
     356                0:   std::string SelName = Method->getSelector().getAsString();
     357                0:   std::string SelTypes;
     358                0:   CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
     359                 :   // Typed selectors
     360                 :   TypedSelector Selector = TypedSelector(SelName,
     361                0:           SelTypes);
     362                 : 
     363                 :   // If it's already cached, return it.
                        0: branch 1 not taken
                        0: branch 2 not taken
     364                0:   if (TypedSelectors[Selector]) {
     365                0:     return Builder.CreateLoad(TypedSelectors[Selector]);
     366                 :   }
     367                 : 
     368                 :   // If it isn't, cache it.
     369                 :   llvm::GlobalAlias *Sel = new llvm::GlobalAlias(
     370                 :           llvm::PointerType::getUnqual(SelectorTy),
     371                 :           llvm::GlobalValue::PrivateLinkage, ".objc_selector_alias" + SelName,
     372                0:           NULL, &TheModule);
     373                0:   TypedSelectors[Selector] = Sel;
     374                 : 
     375                0:   return Builder.CreateLoad(Sel);
     376                 : }
     377                 : 
     378                 : llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
     379               65:                                               const std::string &Name) {
     380               65:   llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
     381               65:   return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
     382                 : }
     383                 : llvm::Constant *CGObjCGNU::ExportUniqueString(const std::string &Str,
     384               14:         const std::string prefix) {
     385               14:   std::string name = prefix + Str;
     386               14:   llvm::Constant *ConstStr = TheModule.getGlobalVariable(name);
                       14: branch 0 taken
                        0: branch 1 not taken
     387               14:   if (!ConstStr) {
     388               14:     llvm::Constant *value = llvm::ConstantArray::get(VMContext, Str, true);
     389                 :     ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true,
     390               14:             llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str);
     391                 :   }
     392               14:   return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
     393                 : }
     394                 : 
     395                 : llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty,
     396                 :     std::vector<llvm::Constant*> &V, llvm::StringRef Name,
     397               57:     llvm::GlobalValue::LinkageTypes linkage) {
     398               57:   llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
     399                 :   return new llvm::GlobalVariable(TheModule, Ty, false,
     400               57:       llvm::GlobalValue::InternalLinkage, C, Name);
     401                 : }
     402                 : 
     403                 : llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty,
     404                 :     std::vector<llvm::Constant*> &V, llvm::StringRef Name,
     405               10:     llvm::GlobalValue::LinkageTypes linkage) {
     406               10:   llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
     407                 :   return new llvm::GlobalVariable(TheModule, Ty, false,
     408               10:                                   llvm::GlobalValue::InternalLinkage, C, Name);
     409                 : }
     410                 : 
     411                 : /// Generate an NSConstantString object.
     412                3: llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
     413                 : 
     414                3:   std::string Str(SL->getStrData(), SL->getByteLength());
     415                 : 
     416                 :   // Look for an existing one
     417                3:   llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
                        0: branch 2 not taken
                        3: branch 3 taken
     418                3:   if (old != ObjCStrings.end())
     419                0:     return old->getValue();
     420                 : 
     421                3:   std::vector<llvm::Constant*> Ivars;
     422                3:   Ivars.push_back(NULLPtr);
     423                3:   Ivars.push_back(MakeConstantString(Str));
     424                3:   Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
     425                 :   llvm::Constant *ObjCStr = MakeGlobal(
     426                 :     llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL),
     427                3:     Ivars, ".objc_str");
     428                3:   ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
     429                3:   ObjCStrings[Str] = ObjCStr;
     430                3:   ConstantStrings.push_back(ObjCStr);
     431                3:   return ObjCStr;
     432                 : }
     433                 : 
     434                 : ///Generates a message send where the super is the receiver.  This is a message
     435                 : ///send to self with special delivery semantics indicating which class's method
     436                 : ///should be called.
     437                 : CodeGen::RValue
     438                 : CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
     439                 :                                     QualType ResultType,
     440                 :                                     Selector Sel,
     441                 :                                     const ObjCInterfaceDecl *Class,
     442                 :                                     bool isCategoryImpl,
     443                 :                                     llvm::Value *Receiver,
     444                 :                                     bool IsClassMessage,
     445                 :                                     const CallArgList &CallArgs,
     446                3:                                     const ObjCMethodDecl *Method) {
                        0: branch 2 not taken
                        3: branch 3 taken
     447                3:   if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     448                0:     if (Sel == RetainSel || Sel == AutoreleaseSel) {
     449                0:       return RValue::get(Receiver);
     450                 :     }
                        0: branch 1 not taken
                        0: branch 2 not taken
     451                0:     if (Sel == ReleaseSel) {
     452                0:       return RValue::get(0);
     453                 :     }
     454                 :   }
     455                3:   llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
     456                 : 
     457                3:   CallArgList ActualArgs;
     458                 : 
     459                 :   ActualArgs.push_back(
     460                 :       std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
     461                3:       ASTIdTy));
     462                 :   ActualArgs.push_back(std::make_pair(RValue::get(cmd),
     463                3:                                       CGF.getContext().getObjCSelType()));
     464                3:   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
     465                 : 
     466                3:   CodeGenTypes &Types = CGM.getTypes();
     467                 :   const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
     468                3:                                                        CC_Default, false);
     469                 :   const llvm::FunctionType *impType =
                        0: branch 0 not taken
                        3: branch 1 taken
     470                3:     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
     471                 : 
     472                3:   llvm::Value *ReceiverClass = 0;
                        0: branch 0 not taken
                        3: branch 1 taken
     473                3:   if (isCategoryImpl) {
     474                0:     llvm::Constant *classLookupFunction = 0;
     475                0:     std::vector<const llvm::Type*> Params;
     476                0:     Params.push_back(PtrTy);
                        0: branch 0 not taken
                        0: branch 1 not taken
     477                0:     if (IsClassMessage)  {
     478                 :       classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
     479                0:             IdTy, Params, true), "objc_get_meta_class");
     480                 :     } else {
     481                 :       classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
     482                0:             IdTy, Params, true), "objc_get_class");
     483                 :     }
     484                 :     ReceiverClass = CGF.Builder.CreateCall(classLookupFunction,
     485                0:         MakeConstantString(Class->getNameAsString()));
     486                 :   } else {
     487                 :     // Set up global aliases for the metaclass or class pointer if they do not
     488                 :     // already exist.  These will are forward-references which will be set to
     489                 :     // pointers to the class and metaclass structure created for the runtime
     490                 :     // load function.  To send a message to super, we look up the value of the
     491                 :     // super_class pointer from either the class or metaclass structure.
                        1: branch 0 taken
                        2: branch 1 taken
     492                3:     if (IsClassMessage)  {
                        1: branch 0 taken
                        0: branch 1 not taken
     493                1:       if (!MetaClassPtrAlias) {
     494                 :         MetaClassPtrAlias = new llvm::GlobalAlias(IdTy,
     495                 :             llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" +
     496                1:             Class->getNameAsString(), NULL, &TheModule);
     497                 :       }
     498                1:       ReceiverClass = MetaClassPtrAlias;
     499                 :     } else {
                        1: branch 0 taken
                        1: branch 1 taken
     500                2:       if (!ClassPtrAlias) {
     501                 :         ClassPtrAlias = new llvm::GlobalAlias(IdTy,
     502                 :             llvm::GlobalValue::InternalLinkage, ".objc_class_ref" +
     503                1:             Class->getNameAsString(), NULL, &TheModule);
     504                 :       }
     505                2:       ReceiverClass = ClassPtrAlias;
     506                 :     }
     507                 :   }
     508                 :   // Cast the pointer to a simplified version of the class structure
     509                 :   ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass,
     510                 :       llvm::PointerType::getUnqual(
     511                3:         llvm::StructType::get(VMContext, IdTy, IdTy, NULL)));
     512                 :   // Get the superclass pointer
     513                3:   ReceiverClass = CGF.Builder.CreateStructGEP(ReceiverClass, 1);
     514                 :   // Load the superclass pointer
     515                3:   ReceiverClass = CGF.Builder.CreateLoad(ReceiverClass);
     516                 :   // Construct the structure used to look up the IMP
     517                 :   llvm::StructType *ObjCSuperTy = llvm::StructType::get(VMContext,
     518                3:       Receiver->getType(), IdTy, NULL);
     519                3:   llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy);
     520                 : 
     521                3:   CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0));
     522                 :   CGF.Builder.CreateStore(ReceiverClass,
     523                3:       CGF.Builder.CreateStructGEP(ObjCSuper, 1));
     524                 : 
     525                 :   // Get the IMP
     526                3:   std::vector<const llvm::Type*> Params;
     527                3:   Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy));
     528                3:   Params.push_back(SelectorTy);
     529                 :   llvm::Constant *lookupFunction =
     530                 :     CGM.CreateRuntimeFunction(llvm::FunctionType::get(
     531                 :           llvm::PointerType::getUnqual(impType), Params, true),
     532                3:         "objc_msg_lookup_super");
     533                 : 
     534                3:   llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
     535                 :   llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs,
     536                3:       lookupArgs+2);
     537                 : 
     538                3:   return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
     539                 : }
     540                 : 
     541                 : /// Generate code for a message send expression.
     542                 : CodeGen::RValue
     543                 : CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
     544                 :                                QualType ResultType,
     545                 :                                Selector Sel,
     546                 :                                llvm::Value *Receiver,
     547                 :                                bool IsClassMessage,
     548                 :                                const CallArgList &CallArgs,
     549               12:                                const ObjCMethodDecl *Method) {
                        0: branch 2 not taken
                       12: branch 3 taken
     550               12:   if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     551                0:     if (Sel == RetainSel || Sel == AutoreleaseSel) {
     552                0:       return RValue::get(Receiver);
     553                 :     }
                        0: branch 1 not taken
                        0: branch 2 not taken
     554                0:     if (Sel == ReleaseSel) {
     555                0:       return RValue::get(0);
     556                 :     }
     557                 :   }
     558               12:   CGBuilderTy &Builder = CGF.Builder;
     559               12:   IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
     560                 :   llvm::Value *cmd;
                        0: branch 0 not taken
                       12: branch 1 taken
     561               12:   if (Method)
     562                0:     cmd = GetSelector(Builder, Method);
     563                 :   else
     564               12:     cmd = GetSelector(Builder, Sel);
     565               12:   CallArgList ActualArgs;
     566                 : 
     567               12:   Receiver = Builder.CreateBitCast(Receiver, IdTy);
     568                 :   ActualArgs.push_back(
     569               12:     std::make_pair(RValue::get(Receiver), ASTIdTy));
     570                 :   ActualArgs.push_back(std::make_pair(RValue::get(cmd),
     571               12:                                       CGF.getContext().getObjCSelType()));
     572               12:   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
     573                 : 
     574               12:   CodeGenTypes &Types = CGM.getTypes();
     575                 :   const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
     576               12:                                                        CC_Default, false);
     577                 :   const llvm::FunctionType *impType =
                        0: branch 0 not taken
                       12: branch 1 taken
     578               12:     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
     579                 : 
     580                 :   llvm::Value *imp;
     581                 :   // For sender-aware dispatch, we pass the sender as the third argument to a
     582                 :   // lookup function.  When sending messages from C code, the sender is nil.
     583                 :   // objc_msg_lookup_sender(id *receiver, SEL selector, id sender);
                        5: branch 2 taken
                        7: branch 3 taken
     584               12:   if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
     585                 : 
     586                5:     std::vector<const llvm::Type*> Params;
     587                5:     llvm::Value *ReceiverPtr = CGF.CreateTempAlloca(Receiver->getType());
     588                5:     Builder.CreateStore(Receiver, ReceiverPtr);
     589                5:     Params.push_back(ReceiverPtr->getType());
     590                5:     Params.push_back(SelectorTy);
     591                 :     llvm::Value *self;
     592                 : 
                        0: branch 1 not taken
                        5: branch 2 taken
     593                5:     if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) {
     594                0:       self = CGF.LoadObjCSelf();
     595                 :     } else {
     596                5:       self = llvm::ConstantPointerNull::get(IdTy);
     597                 :     }
     598                 : 
     599                5:     Params.push_back(self->getType());
     600                 : 
     601                 :     // The lookup function returns a slot, which can be safely cached.
     602                 :     llvm::Type *SlotTy = llvm::StructType::get(VMContext, PtrTy, PtrTy, PtrTy,
     603                5:             IntTy, llvm::PointerType::getUnqual(impType), NULL);
     604                 :     llvm::Constant *lookupFunction =
     605                 :       CGM.CreateRuntimeFunction(llvm::FunctionType::get(
     606                 :           llvm::PointerType::getUnqual(SlotTy), Params, true),
     607                5:         "objc_msg_lookup_sender");
     608                 : 
     609                 :     // The lookup function is guaranteed not to capture the receiver pointer.
                        1: branch 1 taken
                        4: branch 2 taken
     610                5:     if (llvm::Function *LookupFn = dyn_cast<llvm::Function>(lookupFunction)) {
     611                1:       LookupFn->setDoesNotCapture(1);
     612                 :     }
     613                 : 
     614                 :     llvm::Value *slot =
     615                5:         Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
     616                5:     imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
     617                 :     // The lookup function may have changed the receiver, so make sure we use
     618                 :     // the new one.
     619                 :     ActualArgs[0] =
     620                5:         std::make_pair(RValue::get(Builder.CreateLoad(ReceiverPtr)), ASTIdTy);
     621                 :   } else {
     622                7:     std::vector<const llvm::Type*> Params;
     623                7:     Params.push_back(Receiver->getType());
     624                7:     Params.push_back(SelectorTy);
     625                 :     llvm::Constant *lookupFunction =
     626                 :     CGM.CreateRuntimeFunction(llvm::FunctionType::get(
     627                 :         llvm::PointerType::getUnqual(impType), Params, true),
     628                7:       "objc_msg_lookup");
     629                 : 
     630                7:     imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
     631                 :   }
     632                 : 
     633               12:   return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
     634                 : }
     635                 : 
     636                 : /// Generates a MethodList.  Used in construction of a objc_class and
     637                 : /// objc_category structures.
     638                 : llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
     639                 :                                               const std::string &CategoryName,
     640                 :     const llvm::SmallVectorImpl<Selector> &MethodSels,
     641                 :     const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
     642               22:     bool isClassMethodList) {
                       20: branch 1 taken
                        2: branch 2 taken
     643               22:   if (MethodSels.empty())
     644               20:     return NULLPtr;
     645                 :   // Get the method structure type.
     646                 :   llvm::StructType *ObjCMethodTy = llvm::StructType::get(VMContext,
     647                 :     PtrToInt8Ty, // Really a selector, but the runtime creates it us.
     648                 :     PtrToInt8Ty, // Method types
     649                 :     llvm::PointerType::getUnqual(IMPTy), //Method pointer
     650                2:     NULL);
     651                2:   std::vector<llvm::Constant*> Methods;
     652                2:   std::vector<llvm::Constant*> Elements;
                        8: branch 1 taken
                        2: branch 2 taken
     653               10:   for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
     654                8:     Elements.clear();
                        7: branch 0 taken
                        1: branch 1 taken
     655                8:     if (llvm::Constant *Method =
     656                 :       TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
     657                 :                                                 MethodSels[i].getAsString(),
     658                8:                                                 isClassMethodList))) {
     659                7:       llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString());
     660                7:       Elements.push_back(C);
     661                7:       Elements.push_back(MethodTypes[i]);
     662                 :       Method = llvm::ConstantExpr::getBitCast(Method,
     663                7:           llvm::PointerType::getUnqual(IMPTy));
     664                7:       Elements.push_back(Method);
     665                7:       Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
     666                 :     }
     667                 :   }
     668                 : 
     669                 :   // Array of method structures
     670                 :   llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
     671                2:                                                             Methods.size());
     672                 :   llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
     673                2:                                                          Methods);
     674                 : 
     675                 :   // Structure containing list pointer, array and array count
     676                2:   llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields;
     677                2:   llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get(VMContext);
     678                2:   llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy);
     679                 :   llvm::StructType *ObjCMethodListTy = llvm::StructType::get(VMContext,
     680                 :       NextPtrTy,
     681                 :       IntTy,
     682                 :       ObjCMethodArrayTy,
     683                2:       NULL);
     684                 :   // Refine next pointer type to concrete type
     685                 :   llvm::cast<llvm::OpaqueType>(
     686                2:       OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy);
     687                2:   ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get());
     688                 : 
     689                2:   Methods.clear();
     690                 :   Methods.push_back(llvm::ConstantPointerNull::get(
     691                2:         llvm::PointerType::getUnqual(ObjCMethodListTy)));
     692                 :   Methods.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
     693                2:         MethodTypes.size()));
     694                2:   Methods.push_back(MethodArray);
     695                 : 
     696                 :   // Create an instance of the structure
     697                2:   return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list");
     698                 : }
     699                 : 
     700                 : /// Generates an IvarList.  Used in construction of a objc_class.
     701                 : llvm::Constant *CGObjCGNU::GenerateIvarList(
     702                 :     const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
     703                 :     const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
     704                6:     const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets) {
                        5: branch 1 taken
                        1: branch 2 taken
     705                6:   if (IvarNames.size() == 0)
     706                5:     return NULLPtr;
     707                 :   // Get the method structure type.
     708                 :   llvm::StructType *ObjCIvarTy = llvm::StructType::get(VMContext,
     709                 :     PtrToInt8Ty,
     710                 :     PtrToInt8Ty,
     711                 :     IntTy,
     712                1:     NULL);
     713                1:   std::vector<llvm::Constant*> Ivars;
     714                1:   std::vector<llvm::Constant*> Elements;
                        3: branch 1 taken
                        1: branch 2 taken
     715                4:   for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
     716                3:     Elements.clear();
     717                3:     Elements.push_back(IvarNames[i]);
     718                3:     Elements.push_back(IvarTypes[i]);
     719                3:     Elements.push_back(IvarOffsets[i]);
     720                3:     Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements));
     721                 :   }
     722                 : 
     723                 :   // Array of method structures
     724                 :   llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
     725                1:       IvarNames.size());
     726                 : 
     727                 : 
     728                1:   Elements.clear();
     729                1:   Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size()));
     730                1:   Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars));
     731                 :   // Structure containing array and array count
     732                 :   llvm::StructType *ObjCIvarListTy = llvm::StructType::get(VMContext, IntTy,
     733                 :     ObjCIvarArrayTy,
     734                1:     NULL);
     735                 : 
     736                 :   // Create an instance of the structure
     737                1:   return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list");
     738                 : }
     739                 : 
     740                 : /// Generate a class structure
     741                 : llvm::Constant *CGObjCGNU::GenerateClassStructure(
     742                 :     llvm::Constant *MetaClass,
     743                 :     llvm::Constant *SuperClass,
     744                 :     unsigned info,
     745                 :     const char *Name,
     746                 :     llvm::Constant *Version,
     747                 :     llvm::Constant *InstanceSize,
     748                 :     llvm::Constant *IVars,
     749                 :     llvm::Constant *Methods,
     750                 :     llvm::Constant *Protocols,
     751                 :     llvm::Constant *IvarOffsets,
     752                6:     llvm::Constant *Properties) {
     753                 :   // Set up the class structure
     754                 :   // Note:  Several of these are char*s when they should be ids.  This is
     755                 :   // because the runtime performs this translation on load.
     756                 :   //
     757                 :   // Fields marked New ABI are part of the GNUstep runtime.  We emit them
     758                 :   // anyway; the classes will still work with the GNU runtime, they will just
     759                 :   // be ignored.
     760                 :   llvm::StructType *ClassTy = llvm::StructType::get(VMContext,
     761                 :       PtrToInt8Ty,        // class_pointer
     762                 :       PtrToInt8Ty,        // super_class
     763                 :       PtrToInt8Ty,        // name
     764                 :       LongTy,             // version
     765                 :       LongTy,             // info
     766                 :       LongTy,             // instance_size
     767                 :       IVars->getType(),   // ivars
     768                 :       Methods->getType(), // methods
     769                 :       // These are all filled in by the runtime, so we pretend
     770                 :       PtrTy,              // dtable
     771                 :       PtrTy,              // subclass_list
     772                 :       PtrTy,              // sibling_class
     773                 :       PtrTy,              // protocols
     774                 :       PtrTy,              // gc_object_type
     775                 :       // New ABI:
     776                 :       LongTy,                 // abi_version
     777                 :       IvarOffsets->getType(), // ivar_offsets
     778                 :       Properties->getType(),  // properties
     779                6:       NULL);
     780                6:   llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
     781                 :   // Fill in the structure
     782                6:   std::vector<llvm::Constant*> Elements;
     783                6:   Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
     784                6:   Elements.push_back(SuperClass);
     785                6:   Elements.push_back(MakeConstantString(Name, ".class_name"));
     786                6:   Elements.push_back(Zero);
     787                6:   Elements.push_back(llvm::ConstantInt::get(LongTy, info));
     788                6:   Elements.push_back(InstanceSize);
     789                6:   Elements.push_back(IVars);
     790                6:   Elements.push_back(Methods);
     791                6:   Elements.push_back(NULLPtr);
     792                6:   Elements.push_back(NULLPtr);
     793                6:   Elements.push_back(NULLPtr);
     794                6:   Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
     795                6:   Elements.push_back(NULLPtr);
     796                6:   Elements.push_back(Zero);
     797                6:   Elements.push_back(IvarOffsets);
     798                6:   Elements.push_back(Properties);
     799                 :   // Create an instance of the structure
     800                 :   // This is now an externally visible symbol, so that we can speed up class
     801                 :   // messages in the next ABI.
     802                 :   return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name),
     803                6:          llvm::GlobalValue::ExternalLinkage);
     804                 : }
     805                 : 
     806                 : llvm::Constant *CGObjCGNU::GenerateProtocolMethodList(
     807                 :     const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
     808                5:     const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes) {
     809                 :   // Get the method structure type.
     810                 :   llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(VMContext,
     811                 :     PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.
     812                 :     PtrToInt8Ty,
     813                5:     NULL);
     814                5:   std::vector<llvm::Constant*> Methods;
     815                5:   std::vector<llvm::Constant*> Elements;
                        1: branch 1 taken
                        5: branch 2 taken
     816                6:   for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
     817                1:     Elements.clear();
     818                1:     Elements.push_back(MethodNames[i]);
     819                1:     Elements.push_back(MethodTypes[i]);
     820                1:     Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements));
     821                 :   }
     822                 :   llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
     823                5:       MethodNames.size());
     824                 :   llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
     825                5:                                                    Methods);
     826                 :   llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(VMContext,
     827                5:       IntTy, ObjCMethodArrayTy, NULL);
     828                5:   Methods.clear();
     829                5:   Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
     830                5:   Methods.push_back(Array);
     831                5:   return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list");
     832                 : }
     833                 : 
     834                 : // Create the protocol list structure used in classes, categories and so on
     835                 : llvm::Constant *CGObjCGNU::GenerateProtocolList(
     836                6:     const llvm::SmallVectorImpl<std::string> &Protocols) {
     837                 :   llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
     838                6:       Protocols.size());
     839                 :   llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext,
     840                 :       PtrTy, //Should be a recurisve pointer, but it's always NULL here.
     841                 :       LongTy,//FIXME: Should be size_t
     842                 :       ProtocolArrayTy,
     843                6:       NULL);
     844                6:   std::vector<llvm::Constant*> Elements;
                        3: branch 2 taken
                        6: branch 3 taken
     845                9:   for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
     846                 :       iter != endIter ; iter++) {
     847                3:     llvm::Constant *protocol = 0;
     848                 :     llvm::StringMap<llvm::Constant*>::iterator value =
     849                3:       ExistingProtocols.find(*iter);
                        1: branch 2 taken
                        2: branch 3 taken
     850                3:     if (value == ExistingProtocols.end()) {
     851                1:       protocol = GenerateEmptyProtocol(*iter);
     852                 :     } else {
     853                2:       protocol = value->getValue();
     854                 :     }
     855                 :     llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
     856                3:                                                            PtrToInt8Ty);
     857                3:     Elements.push_back(Ptr);
     858                 :   }
     859                 :   llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
     860                6:       Elements);
     861                6:   Elements.clear();
     862                6:   Elements.push_back(NULLPtr);
     863                6:   Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
     864                6:   Elements.push_back(ProtocolArray);
     865                6:   return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list");
     866                 : }
     867                 : 
     868                 : llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder,
     869                0:                                             const ObjCProtocolDecl *PD) {
     870                0:   llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()];
     871                 :   const llvm::Type *T =
     872                0:     CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
     873                0:   return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
     874                 : }
     875                 : 
     876                 : llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
     877                1:   const std::string &ProtocolName) {
     878                1:   llvm::SmallVector<std::string, 0> EmptyStringVector;
     879                1:   llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector;
     880                 : 
     881                1:   llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
     882                 :   llvm::Constant *MethodList =
     883                1:     GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
     884                 :   // Protocols are objects containing lists of the methods implemented and
     885                 :   // protocols adopted.
     886                 :   llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy,
     887                 :       PtrToInt8Ty,
     888                 :       ProtocolList->getType(),
     889                 :       MethodList->getType(),
     890                 :       MethodList->getType(),
     891                 :       MethodList->getType(),
     892                 :       MethodList->getType(),
     893                1:       NULL);
     894                1:   std::vector<llvm::Constant*> Elements;
     895                 :   // The isa pointer must be set to a magic number so the runtime knows it's
     896                 :   // the correct layout.
     897                 :   int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ?
                        0: branch 2 not taken
                        1: branch 3 taken
     898                1:       NonFragileProtocolVersion : ProtocolVersion;
     899                 :   Elements.push_back(llvm::ConstantExpr::getIntToPtr(
     900                1:         llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy));
     901                1:   Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
     902                1:   Elements.push_back(ProtocolList);
     903                1:   Elements.push_back(MethodList);
     904                1:   Elements.push_back(MethodList);
     905                1:   Elements.push_back(MethodList);
     906                1:   Elements.push_back(MethodList);
     907                1:   return MakeGlobal(ProtocolTy, Elements, ".objc_protocol");
     908                 : }
     909                 : 
     910                1: void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
     911                1:   ASTContext &Context = CGM.getContext();
     912                1:   std::string ProtocolName = PD->getNameAsString();
     913                1:   llvm::SmallVector<std::string, 16> Protocols;
                        0: branch 1 not taken
                        1: branch 2 taken
     914                2:   for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
     915                1:        E = PD->protocol_end(); PI != E; ++PI)
     916                0:     Protocols.push_back((*PI)->getNameAsString());
     917                1:   llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
     918                1:   llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
     919                1:   llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodNames;
     920                1:   llvm::SmallVector<llvm::Constant*, 16> OptionalInstanceMethodTypes;
                        1: branch 4 taken
                        1: branch 5 taken
     921                3:   for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
     922                1:        E = PD->instmeth_end(); iter != E; iter++) {
     923                1:     std::string TypeStr;
     924                1:     Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
                        0: branch 2 not taken
                        1: branch 3 taken
     925                1:     if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
     926                 :       InstanceMethodNames.push_back(
     927                0:           MakeConstantString((*iter)->getSelector().getAsString()));
     928                0:       InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
     929                 :     } else {
     930                 :       OptionalInstanceMethodNames.push_back(
     931                1:           MakeConstantString((*iter)->getSelector().getAsString()));
     932                1:       OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
     933                 :     }
     934                 :   }
     935                 :   // Collect information about class methods:
     936                1:   llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
     937                1:   llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
     938                1:   llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodNames;
     939                1:   llvm::SmallVector<llvm::Constant*, 16> OptionalClassMethodTypes;
                        0: branch 3 not taken
                        1: branch 4 taken
     940                1:   for (ObjCProtocolDecl::classmeth_iterator
     941                1:          iter = PD->classmeth_begin(), endIter = PD->classmeth_end();
     942                 :        iter != endIter ; iter++) {
     943                0:     std::string TypeStr;
     944                0:     Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
                        0: branch 2 not taken
                        0: branch 3 not taken
     945                0:     if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
     946                 :       ClassMethodNames.push_back(
     947                0:           MakeConstantString((*iter)->getSelector().getAsString()));
     948                0:       ClassMethodTypes.push_back(MakeConstantString(TypeStr));
     949                 :     } else {
     950                 :       OptionalClassMethodNames.push_back(
     951                0:           MakeConstantString((*iter)->getSelector().getAsString()));
     952                0:       OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
     953                 :     }
     954                 :   }
     955                 : 
     956                1:   llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
     957                 :   llvm::Constant *InstanceMethodList =
     958                1:     GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
     959                 :   llvm::Constant *ClassMethodList =
     960                1:     GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
     961                 :   llvm::Constant *OptionalInstanceMethodList =
     962                 :     GenerateProtocolMethodList(OptionalInstanceMethodNames,
     963                1:             OptionalInstanceMethodTypes);
     964                 :   llvm::Constant *OptionalClassMethodList =
     965                 :     GenerateProtocolMethodList(OptionalClassMethodNames,
     966                1:             OptionalClassMethodTypes);
     967                 : 
     968                 :   // Property metadata: name, attributes, isSynthesized, setter name, setter
     969                 :   // types, getter name, getter types.
     970                 :   // The isSynthesized value is always set to 0 in a protocol.  It exists to
     971                 :   // simplify the runtime library by allowing it to use the same data
     972                 :   // structures for protocol metadata everywhere.
     973                 :   llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext,
     974                 :           PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
     975                1:           PtrToInt8Ty, NULL);
     976                1:   std::vector<llvm::Constant*> Properties;
     977                1:   std::vector<llvm::Constant*> OptionalProperties;
     978                 : 
     979                 :   // Add all of the property methods need adding to the method list and to the
     980                 :   // property metadata list.
                        0: branch 3 not taken
                        1: branch 4 taken
     981                1:   for (ObjCContainerDecl::prop_iterator
     982                1:          iter = PD->prop_begin(), endIter = PD->prop_end();
     983                 :        iter != endIter ; iter++) {
     984                0:     std::vector<llvm::Constant*> Fields;
     985                0:     ObjCPropertyDecl *property = (*iter);
     986                 : 
     987                0:     Fields.push_back(MakeConstantString(property->getNameAsString()));
     988                 :     Fields.push_back(llvm::ConstantInt::get(Int8Ty,
     989                0:                 property->getPropertyAttributes()));
     990                0:     Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
                        0: branch 1 not taken
                        0: branch 2 not taken
     991                0:     if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
     992                0:       std::string TypeStr;
     993                0:       Context.getObjCEncodingForMethodDecl(getter,TypeStr);
     994                0:       llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
     995                0:       InstanceMethodTypes.push_back(TypeEncoding);
     996                0:       Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
     997                0:       Fields.push_back(TypeEncoding);
     998                 :     } else {
     999                0:       Fields.push_back(NULLPtr);
    1000                0:       Fields.push_back(NULLPtr);
    1001                 :     }
                        0: branch 1 not taken
                        0: branch 2 not taken
    1002                0:     if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
    1003                0:       std::string TypeStr;
    1004                0:       Context.getObjCEncodingForMethodDecl(setter,TypeStr);
    1005                0:       llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
    1006                0:       InstanceMethodTypes.push_back(TypeEncoding);
    1007                0:       Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
    1008                0:       Fields.push_back(TypeEncoding);
    1009                 :     } else {
    1010                0:       Fields.push_back(NULLPtr);
    1011                0:       Fields.push_back(NULLPtr);
    1012                 :     }
                        0: branch 1 not taken
                        0: branch 2 not taken
    1013                0:     if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) {
    1014                0:       OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
    1015                 :     } else {
    1016                0:       Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
    1017                 :     }
    1018                 :   }
    1019                 :   llvm::Constant *PropertyArray = llvm::ConstantArray::get(
    1020                1:       llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
    1021                 :   llvm::Constant* PropertyListInitFields[] =
    1022                1:     {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
    1023                 : 
    1024                 :   llvm::Constant *PropertyListInit =
    1025                1:       llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false);
    1026                 :   llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule,
    1027                 :       PropertyListInit->getType(), false, llvm::GlobalValue::InternalLinkage,
    1028                1:       PropertyListInit, ".objc_property_list");
    1029                 : 
    1030                 :   llvm::Constant *OptionalPropertyArray =
    1031                 :       llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
    1032                1:           OptionalProperties.size()) , OptionalProperties);
    1033                 :   llvm::Constant* OptionalPropertyListInitFields[] = {
    1034                 :       llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
    1035                1:       OptionalPropertyArray };
    1036                 : 
    1037                 :   llvm::Constant *OptionalPropertyListInit =
    1038                1:       llvm::ConstantStruct::get(VMContext, OptionalPropertyListInitFields, 3, false);
    1039                 :   llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(TheModule,
    1040                 :           OptionalPropertyListInit->getType(), false,
    1041                 :           llvm::GlobalValue::InternalLinkage, OptionalPropertyListInit,
    1042                1:           ".objc_property_list");
    1043                 : 
    1044                 :   // Protocols are objects containing lists of the methods implemented and
    1045                 :   // protocols adopted.
    1046                 :   llvm::StructType *ProtocolTy = llvm::StructType::get(VMContext, IdTy,
    1047                 :       PtrToInt8Ty,
    1048                 :       ProtocolList->getType(),
    1049                 :       InstanceMethodList->getType(),
    1050                 :       ClassMethodList->getType(),
    1051                 :       OptionalInstanceMethodList->getType(),
    1052                 :       OptionalClassMethodList->getType(),
    1053                 :       PropertyList->getType(),
    1054                 :       OptionalPropertyList->getType(),
    1055                1:       NULL);
    1056                1:   std::vector<llvm::Constant*> Elements;
    1057                 :   // The isa pointer must be set to a magic number so the runtime knows it's
    1058                 :   // the correct layout.
    1059                 :   int Version = CGM.getContext().getLangOptions().ObjCNonFragileABI ?
                        0: branch 2 not taken
                        1: branch 3 taken
    1060                1:       NonFragileProtocolVersion : ProtocolVersion;
    1061                 :   Elements.push_back(llvm::ConstantExpr::getIntToPtr(
    1062                1:         llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Version), IdTy));
    1063                1:   Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
    1064                1:   Elements.push_back(ProtocolList);
    1065                1:   Elements.push_back(InstanceMethodList);
    1066                1:   Elements.push_back(ClassMethodList);
    1067                1:   Elements.push_back(OptionalInstanceMethodList);
    1068                1:   Elements.push_back(OptionalClassMethodList);
    1069                1:   Elements.push_back(PropertyList);
    1070                1:   Elements.push_back(OptionalPropertyList);
    1071                 :   ExistingProtocols[ProtocolName] =
    1072                 :     llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
    1073                1:           ".objc_protocol"), IdTy);
    1074                1: }
    1075                7: void CGObjCGNU::GenerateProtocolHolderCategory(void) {
    1076                 :   // Collect information about instance methods
    1077                7:   llvm::SmallVector<Selector, 1> MethodSels;
    1078                7:   llvm::SmallVector<llvm::Constant*, 1> MethodTypes;
    1079                 : 
    1080                7:   std::vector<llvm::Constant*> Elements;
    1081                7:   const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack";
    1082                7:   const std::string CategoryName = "AnotherHack";
    1083                7:   Elements.push_back(MakeConstantString(CategoryName));
    1084                7:   Elements.push_back(MakeConstantString(ClassName));
    1085                 :   // Instance method list
    1086                 :   Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
    1087                7:           ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy));
    1088                 :   // Class method list
    1089                 :   Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
    1090                7:           ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy));
    1091                 :   // Protocol list
    1092                 :   llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
    1093                7:       ExistingProtocols.size());
    1094                 :   llvm::StructType *ProtocolListTy = llvm::StructType::get(VMContext,
    1095                 :       PtrTy, //Should be a recurisve pointer, but it's always NULL here.
    1096                 :       LongTy,//FIXME: Should be size_t
    1097                 :       ProtocolArrayTy,
    1098                7:       NULL);
    1099                7:   std::vector<llvm::Constant*> ProtocolElements;
                        1: branch 2 taken
                        7: branch 3 taken
    1100                8:   for (llvm::StringMapIterator<llvm::Constant*> iter =
    1101                7:        ExistingProtocols.begin(), endIter = ExistingProtocols.end();
    1102                 :        iter != endIter ; iter++) {
    1103                 :     llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(),
    1104                1:             PtrTy);
    1105                1:     ProtocolElements.push_back(Ptr);
    1106                 :   }
    1107                 :   llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
    1108                7:       ProtocolElements);
    1109                7:   ProtocolElements.clear();
    1110                7:   ProtocolElements.push_back(NULLPtr);
    1111                 :   ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
    1112                7:               ExistingProtocols.size()));
    1113                7:   ProtocolElements.push_back(ProtocolArray);
    1114                 :   Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy,
    1115                7:                   ProtocolElements, ".objc_protocol_list"), PtrTy));
    1116                 :   Categories.push_back(llvm::ConstantExpr::getBitCast(
    1117                 :         MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty,
    1118                7:             PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
    1119                7: }
    1120                 : 
    1121                1: void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
    1122                1:   std::string ClassName = OCD->getClassInterface()->getNameAsString();
    1123                1:   std::string CategoryName = OCD->getNameAsString();
    1124                 :   // Collect information about instance methods
    1125                1:   llvm::SmallVector<Selector, 16> InstanceMethodSels;
    1126                1:   llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
                        0: branch 3 not taken
                        1: branch 4 taken
    1127                1:   for (ObjCCategoryImplDecl::instmeth_iterator
    1128                1:          iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end();
    1129                 :        iter != endIter ; iter++) {
    1130                0:     InstanceMethodSels.push_back((*iter)->getSelector());
    1131                0:     std::string TypeStr;
    1132                0:     CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
    1133                0:     InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
    1134                 :   }
    1135                 : 
    1136                 :   // Collect information about class methods
    1137                1:   llvm::SmallVector<Selector, 16> ClassMethodSels;
    1138                1:   llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
                        0: branch 3 not taken
                        1: branch 4 taken
    1139                1:   for (ObjCCategoryImplDecl::classmeth_iterator
    1140                1:          iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end();
    1141                 :        iter != endIter ; iter++) {
    1142                0:     ClassMethodSels.push_back((*iter)->getSelector());
    1143                0:     std::string TypeStr;
    1144                0:     CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
    1145                0:     ClassMethodTypes.push_back(MakeConstantString(TypeStr));
    1146                 :   }
    1147                 : 
    1148                 :   // Collect the names of referenced protocols
    1149                1:   llvm::SmallVector<std::string, 16> Protocols;
    1150                1:   const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface();
    1151                1:   const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
                        1: branch 1 taken
                        1: branch 2 taken
    1152                3:   for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
    1153                1:        E = Protos.end(); I != E; ++I)
    1154                1:     Protocols.push_back((*I)->getNameAsString());
    1155                 : 
    1156                1:   std::vector<llvm::Constant*> Elements;
    1157                1:   Elements.push_back(MakeConstantString(CategoryName));
    1158                1:   Elements.push_back(MakeConstantString(ClassName));
    1159                 :   // Instance method list
    1160                 :   Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
    1161                 :           ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
    1162                1:           false), PtrTy));
    1163                 :   // Class method list
    1164                 :   Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
    1165                 :           ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true),
    1166                1:         PtrTy));
    1167                 :   // Protocol list
    1168                 :   Elements.push_back(llvm::ConstantExpr::getBitCast(
    1169                1:         GenerateProtocolList(Protocols), PtrTy));
    1170                 :   Categories.push_back(llvm::ConstantExpr::getBitCast(
    1171                 :         MakeGlobal(llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty,
    1172                1:             PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
    1173                1: }
    1174                 : 
    1175                 : llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OID,
    1176                 :         llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
    1177                3:         llvm::SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) {
    1178                3:   ASTContext &Context = CGM.getContext();
    1179                 :   //
    1180                 :   // Property metadata: name, attributes, isSynthesized, setter name, setter
    1181                 :   // types, getter name, getter types.
    1182                 :   llvm::StructType *PropertyMetadataTy = llvm::StructType::get(VMContext,
    1183                 :           PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
    1184                3:           PtrToInt8Ty, NULL);
    1185                3:   std::vector<llvm::Constant*> Properties;
    1186                 : 
    1187                 : 
    1188                 :   // Add all of the property methods need adding to the method list and to the
    1189                 :   // property metadata list.
                        3: branch 3 taken
                        3: branch 4 taken
    1190                6:   for (ObjCImplDecl::propimpl_iterator
    1191                3:          iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
    1192                 :        iter != endIter ; iter++) {
    1193                3:     std::vector<llvm::Constant*> Fields;
    1194                3:     ObjCPropertyDecl *property = (*iter)->getPropertyDecl();
    1195                 : 
    1196                3:     Fields.push_back(MakeConstantString(property->getNameAsString()));
    1197                 :     Fields.push_back(llvm::ConstantInt::get(Int8Ty,
    1198                3:                 property->getPropertyAttributes()));
    1199                 :     Fields.push_back(llvm::ConstantInt::get(Int8Ty,
    1200                 :                 (*iter)->getPropertyImplementation() ==
    1201                3:                 ObjCPropertyImplDecl::Synthesize));
                        3: branch 1 taken
                        0: branch 2 not taken
    1202                3:     if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
    1203                3:       InstanceMethodSels.push_back(getter->getSelector());
    1204                3:       std::string TypeStr;
    1205                3:       Context.getObjCEncodingForMethodDecl(getter,TypeStr);
    1206                3:       llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
    1207                3:       InstanceMethodTypes.push_back(TypeEncoding);
    1208                3:       Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
    1209                3:       Fields.push_back(TypeEncoding);
    1210                 :     } else {
    1211                0:       Fields.push_back(NULLPtr);
    1212                0:       Fields.push_back(NULLPtr);
    1213                 :     }
                        2: branch 1 taken
                        1: branch 2 taken
    1214                3:     if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
    1215                2:       InstanceMethodSels.push_back(setter->getSelector());
    1216                2:       std::string TypeStr;
    1217                2:       Context.getObjCEncodingForMethodDecl(setter,TypeStr);
    1218                2:       llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
    1219                2:       InstanceMethodTypes.push_back(TypeEncoding);
    1220                2:       Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
    1221                2:       Fields.push_back(TypeEncoding);
    1222                 :     } else {
    1223                1:       Fields.push_back(NULLPtr);
    1224                1:       Fields.push_back(NULLPtr);
    1225                 :     }
    1226                3:     Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
    1227                 :   }
    1228                 :   llvm::ArrayType *PropertyArrayTy =
    1229                3:       llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
    1230                 :   llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
    1231                3:           Properties);
    1232                 :   llvm::Constant* PropertyListInitFields[] =
    1233                3:     {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
    1234                 : 
    1235                 :   llvm::Constant *PropertyListInit =
    1236                3:       llvm::ConstantStruct::get(VMContext, PropertyListInitFields, 3, false);
    1237                 :   return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(), false,
    1238                 :           llvm::GlobalValue::InternalLinkage, PropertyListInit,
    1239                3:           ".objc_property_list");
    1240                 : }
    1241                 : 
    1242                3: void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
    1243                3:   ASTContext &Context = CGM.getContext();
    1244                 : 
    1245                 :   // Get the superclass name.
    1246                 :   const ObjCInterfaceDecl * SuperClassDecl =
    1247                3:     OID->getClassInterface()->getSuperClass();
    1248                3:   std::string SuperClassName;
                        2: branch 0 taken
                        1: branch 1 taken
    1249                3:   if (SuperClassDecl) {
    1250                2:     SuperClassName = SuperClassDecl->getNameAsString();
    1251                2:     EmitClassRef(SuperClassName);
    1252                 :   }
    1253                 : 
    1254                 :   // Get the class name
    1255                 :   ObjCInterfaceDecl *ClassDecl =
    1256                3:     const_cast<ObjCInterfaceDecl *>(OID->getClassInterface());
    1257                3:   std::string ClassName = ClassDecl->getNameAsString();
    1258                 :   // Emit the symbol that is used to generate linker errors if this class is
    1259                 :   // referenced in other modules but not declared.
    1260                3:   std::string classSymbolName = "__objc_class_name_" + ClassName;
                        0: branch 0 not taken
                        3: branch 1 taken
    1261                3:   if (llvm::GlobalVariable *symbol =
    1262                3:       TheModule.getGlobalVariable(classSymbolName)) {
    1263                0:     symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
    1264                 :   } else {
    1265                 :     new llvm::GlobalVariable(TheModule, LongTy, false,
    1266                 :     llvm::GlobalValue::ExternalLinkage, llvm::ConstantInt::get(LongTy, 0),
    1267                3:     classSymbolName);
    1268                 :   }
    1269                 : 
    1270                 :   // Get the size of instances.
    1271                3:   int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8;
    1272                 : 
    1273                 :   // Collect information about instance variables.
    1274                3:   llvm::SmallVector<llvm::Constant*, 16> IvarNames;
    1275                3:   llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
    1276                3:   llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
    1277                 : 
    1278                3:   std::vector<llvm::Constant*> IvarOffsetValues;
    1279                 : 
    1280                 :   int superInstanceSize = !SuperClassDecl ? 0 :
                        2: branch 0 taken
                        1: branch 1 taken
    1281                3:     Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8;
    1282                 :   // For non-fragile ivars, set the instance size to 0 - {the size of just this
    1283                 :   // class}.  The runtime will then set this to the correct value on load.
                        0: branch 2 not taken
                        3: branch 3 taken
    1284                3:   if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
    1285                0:     instanceSize = 0 - (instanceSize - superInstanceSize);
    1286                 :   }
                        3: branch 2 taken
                        3: branch 3 taken
    1287                9:   for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
    1288                3:       endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
    1289                 :       // Store the name
    1290                3:       IvarNames.push_back(MakeConstantString((*iter)->getNameAsString()));
    1291                 :       // Get the type encoding for this ivar
    1292                3:       std::string TypeStr;
    1293                3:       Context.getObjCEncodingForType((*iter)->getType(), TypeStr);
    1294                3:       IvarTypes.push_back(MakeConstantString(TypeStr));
    1295                 :       // Get the offset
    1296                3:       uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter);
    1297                3:       uint64_t Offset = BaseOffset;
                        0: branch 2 not taken
                        3: branch 3 taken
    1298                3:       if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
    1299                0:         Offset = BaseOffset - superInstanceSize;
    1300                 :       }
    1301                 :       IvarOffsets.push_back(
    1302                3:           llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset));
    1303                 :       IvarOffsetValues.push_back(new llvm::GlobalVariable(TheModule, IntTy,
    1304                 :           false, llvm::GlobalValue::ExternalLinkage,
    1305                 :           llvm::ConstantInt::get(IntTy, BaseOffset),
    1306                 :           "__objc_ivar_offset_value_" + ClassName +"." +
    1307                3:           (*iter)->getNameAsString()));
    1308                 :   }
    1309                 :   llvm::Constant *IvarOffsetArrayInit =
    1310                 :       llvm::ConstantArray::get(llvm::ArrayType::get(PtrToIntTy,
    1311                3:                   IvarOffsetValues.size()), IvarOffsetValues);
    1312                 :   llvm::GlobalVariable *IvarOffsetArray = new llvm::GlobalVariable(TheModule,
    1313                 :           IvarOffsetArrayInit->getType(), false,
    1314                 :           llvm::GlobalValue::InternalLinkage, IvarOffsetArrayInit,
    1315                3:           ".ivar.offsets");
    1316                 : 
    1317                 :   // Collect information about instance methods
    1318                3:   llvm::SmallVector<Selector, 16> InstanceMethodSels;
    1319                3:   llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
                        2: branch 3 taken
                        3: branch 4 taken
    1320                5:   for (ObjCImplementationDecl::instmeth_iterator
    1321                3:          iter = OID->instmeth_begin(), endIter = OID->instmeth_end();
    1322                 :        iter != endIter ; iter++) {
    1323                2:     InstanceMethodSels.push_back((*iter)->getSelector());
    1324                2:     std::string TypeStr;
    1325                2:     Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
    1326                2:     InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
    1327                 :   }
    1328                 : 
    1329                 :   llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
    1330                3:           InstanceMethodTypes);
    1331                 : 
    1332                 : 
    1333                 :   // Collect information about class methods
    1334                3:   llvm::SmallVector<Selector, 16> ClassMethodSels;
    1335                3:   llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
                        1: branch 3 taken
                        3: branch 4 taken
    1336                4:   for (ObjCImplementationDecl::classmeth_iterator
    1337                3:          iter = OID->classmeth_begin(), endIter = OID->classmeth_end();
    1338                 :        iter != endIter ; iter++) {
    1339                1:     ClassMethodSels.push_back((*iter)->getSelector());
    1340                1:     std::string TypeStr;
    1341                1:     Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
    1342                1:     ClassMethodTypes.push_back(MakeConstantString(TypeStr));
    1343                 :   }
    1344                 :   // Collect the names of referenced protocols
    1345                3:   llvm::SmallVector<std::string, 16> Protocols;
    1346                3:   const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
                        2: branch 1 taken
                        3: branch 2 taken
    1347                8:   for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
    1348                3:        E = Protos.end(); I != E; ++I)
    1349                2:     Protocols.push_back((*I)->getNameAsString());
    1350                 : 
    1351                 : 
    1352                 : 
    1353                 :   // Get the superclass pointer.
    1354                 :   llvm::Constant *SuperClass;
                        2: branch 1 taken
                        1: branch 2 taken
    1355                3:   if (!SuperClassName.empty()) {
    1356                2:     SuperClass = MakeConstantString(SuperClassName, ".super_class_name");
    1357                 :   } else {
    1358                1:     SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
    1359                 :   }
    1360                 :   // Empty vector used to construct empty method lists
    1361                3:   llvm::SmallVector<llvm::Constant*, 1>  empty;
    1362                 :   // Generate the method and instance variable lists
    1363                 :   llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
    1364                3:       InstanceMethodSels, InstanceMethodTypes, false);
    1365                 :   llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
    1366                3:       ClassMethodSels, ClassMethodTypes, true);
    1367                 :   llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
    1368                3:       IvarOffsets);
    1369                 :   // Irrespective of whether we are compiling for a fragile or non-fragile ABI,
    1370                 :   // we emit a symbol containing the offset for each ivar in the class.  This
    1371                 :   // allows code compiled for the non-Fragile ABI to inherit from code compiled
    1372                 :   // for the legacy ABI, without causing problems.  The converse is also
    1373                 :   // possible, but causes all ivar accesses to be fragile.
    1374                3:   int i = 0;
    1375                 :   // Offset pointer for getting at the correct field in the ivar list when
    1376                 :   // setting up the alias.  These are: The base address for the global, the
    1377                 :   // ivar array (second field), the ivar in this list (set for each ivar), and
    1378                 :   // the offset (third field in ivar structure)
    1379                3:   const llvm::Type *IndexTy = llvm::Type::getInt32Ty(VMContext);
    1380                 :   llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
    1381                 :       llvm::ConstantInt::get(IndexTy, 1), 0,
    1382                3:       llvm::ConstantInt::get(IndexTy, 2) };
    1383                 : 
                        3: branch 2 taken
                        3: branch 3 taken
    1384                9:   for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
    1385                3:       endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
    1386                 :       const std::string Name = "__objc_ivar_offset_" + ClassName + '.'
    1387                3:           +(*iter)->getNameAsString();
    1388                3:       offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i++);
    1389                 :       // Get the correct ivar field
    1390                 :       llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
    1391                3:               IvarList, offsetPointerIndexes, 4);
    1392                 :       // Get the existing alias, if one exists.
    1393                3:       llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
                        0: branch 0 not taken
                        3: branch 1 taken
    1394                3:       if (offset) {
    1395                0:           offset->setInitializer(offsetValue);
    1396                 :           // If this is the real definition, change its linkage type so that
    1397                 :           // different modules will use this one, rather than their private
    1398                 :           // copy.
    1399                0:           offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
    1400                 :       } else {
    1401                 :           // Add a new alias if there isn't one already.
    1402                 :           offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(),
    1403                3:                   false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
    1404                 :       }
    1405                 :   }
    1406                 :   //Generate metaclass for class methods
    1407                 :   llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
    1408                 :       NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList(
    1409                3:         empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr, NULLPtr);
    1410                 : 
    1411                 :   // Generate the class structure
    1412                 :   llvm::Constant *ClassStruct =
    1413                 :     GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L,
    1414                 :                            ClassName.c_str(), 0,
    1415                 :       llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
    1416                 :       MethodList, GenerateProtocolList(Protocols), IvarOffsetArray,
    1417                3:       Properties);
    1418                 : 
    1419                 :   // Resolve the class aliases, if they exist.
                        1: branch 0 taken
                        2: branch 1 taken
    1420                3:   if (ClassPtrAlias) {
    1421                 :     ClassPtrAlias->setAliasee(
    1422                1:         llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
    1423                1:     ClassPtrAlias = 0;
    1424                 :   }
                        1: branch 0 taken
                        2: branch 1 taken
    1425                3:   if (MetaClassPtrAlias) {
    1426                 :     MetaClassPtrAlias->setAliasee(
    1427                1:         llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
    1428                1:     MetaClassPtrAlias = 0;
    1429                 :   }
    1430                 : 
    1431                 :   // Add class structure to list to be added to the symtab later
    1432                3:   ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
    1433                3:   Classes.push_back(ClassStruct);
    1434                3: }
    1435                 : 
    1436                 : 
    1437                7: llvm::Function *CGObjCGNU::ModuleInitFunction() {
    1438                 :   // Only emit an ObjC load function if no Objective-C stuff has been called
                        5: branch 1 taken
                        2: branch 2 taken
                        5: branch 4 taken
                        0: branch 5 not taken
                        2: branch 7 taken
                        3: branch 8 taken
                        2: branch 10 taken
                        0: branch 11 not taken
                        2: branch 13 taken
                        0: branch 14 not taken
                        0: branch 16 not taken
                        2: branch 17 taken
                        0: branch 18 not taken
                        7: branch 19 taken
    1439                7:   if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
    1440                 :       ExistingProtocols.empty() && TypedSelectors.empty() &&
    1441                 :       UntypedSelectors.empty())
    1442                0:     return NULL;
    1443                 : 
    1444                 :   // Add all referenced protocols to a category.
    1445                7:   GenerateProtocolHolderCategory();
    1446                 : 
    1447                 :   const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
    1448                7:           SelectorTy->getElementType());
    1449                7:   const llvm::Type *SelStructPtrTy = SelectorTy;
    1450                7:   bool isSelOpaque = false;
                        7: branch 0 taken
                        0: branch 1 not taken
    1451                7:   if (SelStructTy == 0) {
    1452                 :     SelStructTy = llvm::StructType::get(VMContext, PtrToInt8Ty,
    1453                7:                                         PtrToInt8Ty, NULL);
    1454                7:     SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
    1455                7:     isSelOpaque = true;
    1456                 :   }
    1457                 : 
    1458                 :   // Name the ObjC types to make the IR a bit easier to read
    1459                7:   TheModule.addTypeName(".objc_selector", SelStructPtrTy);
    1460                7:   TheModule.addTypeName(".objc_id", IdTy);
    1461                7:   TheModule.addTypeName(".objc_imp", IMPTy);
    1462                 : 
    1463                7:   std::vector<llvm::Constant*> Elements;
    1464                7:   llvm::Constant *Statics = NULLPtr;
    1465                 :   // Generate statics list:
                        3: branch 1 taken
                        4: branch 2 taken
    1466                7:   if (ConstantStrings.size()) {
    1467                 :     llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
    1468                3:         ConstantStrings.size() + 1);
    1469                3:     ConstantStrings.push_back(NULLPtr);
    1470                 : 
    1471                3:     llvm::StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass;
                        2: branch 1 taken
                        1: branch 2 taken
    1472                3:     if (StringClass.empty()) StringClass = "NXConstantString";
    1473                 :     Elements.push_back(MakeConstantString(StringClass,
    1474                3:                 ".objc_static_class_name"));
    1475                 :     Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
    1476                3:        ConstantStrings));
    1477                 :     llvm::StructType *StaticsListTy =
    1478                3:       llvm::StructType::get(VMContext, PtrToInt8Ty, StaticsArrayTy, NULL);
    1479                 :     llvm::Type *StaticsListPtrTy =
    1480                3:       llvm::PointerType::getUnqual(StaticsListTy);
    1481                3:     Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics");
    1482                 :     llvm::ArrayType *StaticsListArrayTy =
    1483                3:       llvm::ArrayType::get(StaticsListPtrTy, 2);
    1484                3:     Elements.clear();
    1485                3:     Elements.push_back(Statics);
    1486                3:     Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
    1487                3:     Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr");
    1488                3:     Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
    1489                 :   }
    1490                 :   // Array of classes, categories, and constant objects
    1491                 :   llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
    1492                7:       Classes.size() + Categories.size()  + 2);
    1493                 :   llvm::StructType *SymTabTy = llvm::StructType::get(VMContext,
    1494                 :                                                      LongTy, SelStructPtrTy,
    1495                 :                                                      llvm::Type::getInt16Ty(VMContext),
    1496                 :                                                      llvm::Type::getInt16Ty(VMContext),
    1497                7:                                                      ClassListTy, NULL);
    1498                 : 
    1499                7:   Elements.clear();
    1500                 :   // Pointer to an array of selectors used in this module.
    1501                7:   std::vector<llvm::Constant*> Selectors;
                        0: branch 2 not taken
                        7: branch 3 taken
    1502                7:   for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
    1503                7:      iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end();
    1504                 :      iter != iterEnd ; ++iter) {
    1505                0:     Elements.push_back(ExportUniqueString(iter->first.first, ".objc_sel_name"));
    1506                 :     Elements.push_back(MakeConstantString(iter->first.second,
    1507                0:                                           ".objc_sel_types"));
    1508                0:     Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
    1509                0:     Elements.clear();
    1510                 :   }
                       14: branch 2 taken
                        7: branch 3 taken
    1511               21:   for (llvm::StringMap<llvm::GlobalAlias*>::iterator
    1512                7:       iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
    1513                 :       iter != iterEnd; ++iter) {
    1514                 :     Elements.push_back(
    1515               14:         ExportUniqueString(iter->getKeyData(), ".objc_sel_name"));
    1516               14:     Elements.push_back(NULLPtr);
    1517               14:     Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
    1518               14:     Elements.clear();
    1519                 :   }
    1520                7:   Elements.push_back(NULLPtr);
    1521                7:   Elements.push_back(NULLPtr);
    1522                7:   Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
    1523                7:   Elements.clear();
    1524                 :   // Number of static selectors
    1525                7:   Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() ));
    1526                 :   llvm::Constant *SelectorList = MakeGlobal(
    1527                 :           llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors,
    1528                7:           ".objc_selector_list");
    1529                 :   Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
    1530                7:     SelStructPtrTy));
    1531                 : 
    1532                 :   // Now that all of the static selectors exist, create pointers to them.
    1533                7:   int index = 0;
                        0: branch 2 not taken
                        7: branch 3 taken
    1534                7:   for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
    1535                7:      iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end();
    1536                 :      iter != iterEnd; ++iter) {
    1537                 :     llvm::Constant *Idxs[] = {Zeros[0],
    1538                0:       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]};
    1539                 :     llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy,
    1540                 :         true, llvm::GlobalValue::InternalLinkage,
    1541                 :         llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
    1542                0:         ".objc_sel_ptr");
    1543                 :     // If selectors are defined as an opaque type, cast the pointer to this
    1544                 :     // type.
                        0: branch 0 not taken
                        0: branch 1 not taken
    1545                0:     if (isSelOpaque) {
    1546                 :       SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
    1547                0:         llvm::PointerType::getUnqual(SelectorTy));
    1548                 :     }
    1549                0:     (*iter).second->setAliasee(SelPtr);
    1550                 :   }
                       14: branch 2 taken
                        7: branch 3 taken
    1551               21:   for (llvm::StringMap<llvm::GlobalAlias*>::iterator
    1552                7:       iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
    1553                 :       iter != iterEnd; iter++) {
    1554                 :     llvm::Constant *Idxs[] = {Zeros[0],
    1555               14:       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), index++), Zeros[0]};
    1556                 :     llvm::Constant *SelPtr = new llvm::GlobalVariable
    1557                 :       (TheModule, SelStructPtrTy,
    1558                 :        true, llvm::GlobalValue::InternalLinkage,
    1559                 :        llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
    1560               14:        ".objc_sel_ptr");
    1561                 :     // If selectors are defined as an opaque type, cast the pointer to this
    1562                 :     // type.
                       14: branch 0 taken
                        0: branch 1 not taken
    1563               14:     if (isSelOpaque) {
    1564                 :       SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
    1565               14:         llvm::PointerType::getUnqual(SelectorTy));
    1566                 :     }
    1567               14:     (*iter).second->setAliasee(SelPtr);
    1568                 :   }
    1569                 :   // Number of classes defined.
    1570                 :   Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
    1571                7:         Classes.size()));
    1572                 :   // Number of categories defined
    1573                 :   Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
    1574                7:         Categories.size()));
    1575                 :   // Create an array of classes, then categories, then static object instances
    1576                7:   Classes.insert(Classes.end(), Categories.begin(), Categories.end());
    1577                 :   //  NULL-terminated list of static object instances (mainly constant strings)
    1578                7:   Classes.push_back(Statics);
    1579                7:   Classes.push_back(NULLPtr);
    1580                7:   llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
    1581                7:   Elements.push_back(ClassList);
    1582                 :   // Construct the symbol table
    1583                7:   llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements);
    1584                 : 
    1585                 :   // The symbol table is contained in a module which has some version-checking
    1586                 :   // constants
    1587                 :   llvm::StructType * ModuleTy = llvm::StructType::get(VMContext, LongTy, LongTy,
    1588                7:       PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL);
    1589                7:   Elements.clear();
    1590                 :   // Runtime version used for compatibility checking.
                        1: branch 2 taken
                        6: branch 3 taken
    1591                7:   if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
    1592                 :     Elements.push_back(llvm::ConstantInt::get(LongTy,
    1593                1:         NonFragileRuntimeVersion));
    1594                 :   } else {
    1595                6:     Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
    1596                 :   }
    1597                 :   // sizeof(ModuleTy)
    1598                7:   llvm::TargetData td(&TheModule);
    1599                 :   Elements.push_back(llvm::ConstantInt::get(LongTy,
    1600                7:                      td.getTypeSizeInBits(ModuleTy)/8));
    1601                 :   //FIXME: Should be the path to the file where this module was declared
    1602                7:   Elements.push_back(NULLPtr);
    1603                7:   Elements.push_back(SymTab);
    1604                7:   llvm::Value *Module = MakeGlobal(ModuleTy, Elements);
    1605                 : 
    1606                 :   // Create the load function calling the runtime entry point with the module
    1607                 :   // structure
    1608                 :   llvm::Function * LoadFunction = llvm::Function::Create(
    1609                 :       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
    1610                 :       llvm::GlobalValue::InternalLinkage, ".objc_load_function",
    1611                7:       &TheModule);
    1612                 :   llvm::BasicBlock *EntryBB =
    1613                7:       llvm::BasicBlock::Create(VMContext, "entry", LoadFunction);
    1614                7:   CGBuilderTy Builder(VMContext);
    1615                7:   Builder.SetInsertPoint(EntryBB);
    1616                 : 
    1617                 :   std::vector<const llvm::Type*> Params(1,
    1618                7:       llvm::PointerType::getUnqual(ModuleTy));
    1619                 :   llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
    1620                7:         llvm::Type::getVoidTy(VMContext), Params, true), "__objc_exec_class");
    1621                7:   Builder.CreateCall(Register, Module);
    1622                7:   Builder.CreateRetVoid();
    1623                 : 
    1624                7:   return LoadFunction;
    1625                 : }
    1626                 : 
    1627                 : llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
    1628                7:                                           const ObjCContainerDecl *CD) {
    1629                 :   const ObjCCategoryImplDecl *OCD =
    1630                7:     dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext());
                        0: branch 0 not taken
                        7: branch 1 taken
                        7: branch 5 taken
                        0: branch 6 not taken
    1631                7:   std::string CategoryName = OCD ? OCD->getNameAsString() : "";
    1632                7:   std::string ClassName = OMD->getClassInterface()->getNameAsString();
    1633                7:   std::string MethodName = OMD->getSelector().getAsString();
    1634                7:   bool isClassMethod = !OMD->isInstanceMethod();
    1635                 : 
    1636                7:   CodeGenTypes &Types = CGM.getTypes();
    1637                 :   const llvm::FunctionType *MethodTy =
    1638                7:     Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
    1639                 :   std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
    1640                7:       MethodName, isClassMethod);
    1641                 : 
    1642                 :   llvm::Function *Method
    1643                 :     = llvm::Function::Create(MethodTy,
    1644                 :                              llvm::GlobalValue::InternalLinkage,
    1645                 :                              FunctionName,
    1646                7:                              &TheModule);
    1647                7:   return Method;
    1648                 : }
    1649                 : 
    1650                0: llvm::Function *CGObjCGNU::GetPropertyGetFunction() {
    1651                0:   std::vector<const llvm::Type*> Params;
    1652                 :   const llvm::Type *BoolTy =
    1653                0:     CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
    1654                0:   Params.push_back(IdTy);
    1655                0:   Params.push_back(SelectorTy);
    1656                 :   // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64
    1657                0:   Params.push_back(LongTy);
    1658                0:   Params.push_back(BoolTy);
    1659                 :   // void objc_getProperty (id, SEL, ptrdiff_t, bool)
    1660                 :   const llvm::FunctionType *FTy =
    1661                0:     llvm::FunctionType::get(IdTy, Params, false);
    1662                 :   return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy,
    1663                0:                                                         "objc_getProperty"));
    1664                 : }
    1665                 : 
    1666                0: llvm::Function *CGObjCGNU::GetPropertySetFunction() {
    1667                0:   std::vector<const llvm::Type*> Params;
    1668                 :   const llvm::Type *BoolTy =
    1669                0:     CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
    1670                0:   Params.push_back(IdTy);
    1671                0:   Params.push_back(SelectorTy);
    1672                 :   // FIXME: Using LongTy for ptrdiff_t is probably broken on Win64
    1673                0:   Params.push_back(LongTy);
    1674                0:   Params.push_back(IdTy);
    1675                0:   Params.push_back(BoolTy);
    1676                0:   Params.push_back(BoolTy);
    1677                 :   // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
    1678                 :   const llvm::FunctionType *FTy =
    1679                0:     llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
    1680                 :   return cast<llvm::Function>(CGM.CreateRuntimeFunction(FTy,
    1681                0:                                                         "objc_setProperty"));
    1682                 : }
    1683                 : 
    1684                1: llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
    1685                1:   CodeGen::CodeGenTypes &Types = CGM.getTypes();
    1686                1:   ASTContext &Ctx = CGM.getContext();
    1687                 :   // void objc_enumerationMutation (id)
    1688                1:   llvm::SmallVector<QualType,16> Params;
    1689                1:   Params.push_back(ASTIdTy);
    1690                 :   const llvm::FunctionType *FTy =
    1691                 :     Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
    1692                1:                                                 CC_Default, false), false);
    1693                1:   return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
    1694                 : }
    1695                 : 
    1696                 : void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
    1697                2:                                           const Stmt &S) {
    1698                 :   // Pointer to the personality function
    1699                 :   llvm::Constant *Personality =
    1700                 :     CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
    1701                 :           true),
    1702                2:         "__gnu_objc_personality_v0");
    1703                2:   Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy);
    1704                2:   std::vector<const llvm::Type*> Params;
    1705                2:   Params.push_back(PtrTy);
    1706                 :   llvm::Value *RethrowFn =
    1707                 :     CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
    1708                2:           Params, false), "_Unwind_Resume");
    1709                 : 
    1710                2:   bool isTry = isa<ObjCAtTryStmt>(S);
    1711                2:   llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
    1712                2:   llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
    1713                2:   llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
    1714                2:   llvm::BasicBlock *CatchInCatch = CGF.createBasicBlock("catch.rethrow");
    1715                2:   llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
    1716                2:   llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
    1717                2:   llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
    1718                 : 
    1719                 :   // @synchronized()
                        1: branch 0 taken
                        1: branch 1 taken
    1720                2:   if (!isTry) {
    1721                1:     std::vector<const llvm::Type*> Args(1, IdTy);
    1722                 :     llvm::FunctionType *FTy =
    1723                1:       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
    1724                1:     llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
    1725                 :     llvm::Value *SyncArg =
    1726                1:       CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
    1727                1:     SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
    1728                1:     CGF.Builder.CreateCall(SyncEnter, SyncArg);
    1729                 :   }
    1730                 : 
    1731                 : 
    1732                 :   // Push an EH context entry, used for handling rethrows and jumps
    1733                 :   // through finally.
    1734                2:   CGF.PushCleanupBlock(FinallyBlock);
    1735                 : 
    1736                 :   // Emit the statements in the @try {} block
    1737                2:   CGF.setInvokeDest(TryHandler);
    1738                 : 
    1739                2:   CGF.EmitBlock(TryBlock);
    1740                 :   CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
                        1: branch 0 taken
                        1: branch 1 taken
    1741                2:                      : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
    1742                 : 
    1743                 :   // Jump to @finally if there is no exception
    1744                2:   CGF.EmitBranchThroughCleanup(FinallyEnd);
    1745                 : 
    1746                 :   // Emit the handlers
    1747                2:   CGF.EmitBlock(TryHandler);
    1748                 : 
    1749                 :   // Get the correct versions of the exception handling intrinsics
    1750                 :   llvm::Value *llvm_eh_exception =
    1751                2:     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
    1752                 :   llvm::Value *llvm_eh_selector =
    1753                2:     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
    1754                 :   llvm::Value *llvm_eh_typeid_for =
    1755                2:     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
    1756                 : 
    1757                 :   // Exception object
    1758                2:   llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
    1759                2:   llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow");
    1760                 : 
    1761                2:   llvm::SmallVector<llvm::Value*, 8> ESelArgs;
    1762                2:   llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers;
    1763                 : 
    1764                2:   ESelArgs.push_back(Exc);
    1765                2:   ESelArgs.push_back(Personality);
    1766                 : 
    1767                2:   bool HasCatchAll = false;
    1768                 :   // Only @try blocks are allowed @catch blocks, but both can have @finally
                        1: branch 0 taken
                        1: branch 1 taken
    1769                2:   if (isTry) {
                        1: branch 0 taken
                        0: branch 1 not taken
    1770                1:     if (const ObjCAtCatchStmt* CatchStmt =
    1771                1:       cast<ObjCAtTryStmt>(S).getCatchStmts())  {
    1772                1:       CGF.setInvokeDest(CatchInCatch);
    1773                 : 
                        2: branch 1 taken
                        1: branch 2 taken
    1774                3:       for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
    1775                2:         const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
    1776                 :         Handlers.push_back(std::make_pair(CatchDecl,
    1777                2:                                           CatchStmt->getCatchBody()));
    1778                 : 
    1779                 :         // @catch() and @catch(id) both catch any ObjC exception
                        2: branch 0 taken
                        0: branch 1 not taken
                        2: branch 5 taken
                        0: branch 6 not taken
                        0: branch 10 not taken
                        2: branch 11 taken
                        0: branch 12 not taken
                        2: branch 13 taken
    1780                2:         if (!CatchDecl || CatchDecl->getType()->isObjCIdType()
    1781                 :             || CatchDecl->getType()->isObjCQualifiedIdType()) {
    1782                 :           // Use i8* null here to signal this is a catch all, not a cleanup.
    1783                0:           ESelArgs.push_back(NULLPtr);
    1784                0:           HasCatchAll = true;
    1785                 :           // No further catches after this one will ever by reached
    1786                0:           break;
    1787                 :         }
    1788                 : 
    1789                 :         // All other types should be Objective-C interface pointer types.
    1790                 :         const ObjCObjectPointerType *OPT =
    1791                2:           CatchDecl->getType()->getAs<ObjCObjectPointerType>();
                        0: branch 0 not taken
                        2: branch 1 taken
    1792                2:         assert(OPT && "Invalid @catch type.");
    1793                 :         const ObjCInterfaceType *IT =
    1794                2:           OPT->getPointeeType()->getAs<ObjCInterfaceType>();
                        0: branch 0 not taken
                        2: branch 1 taken
    1795                2:         assert(IT && "Invalid @catch type.");
    1796                 :         llvm::Value *EHType =
    1797                2:           MakeConstantString(IT->getDecl()->getNameAsString());
    1798                2:         ESelArgs.push_back(EHType);
    1799                 :       }
    1800                 :     }
    1801                 :   }
    1802                 : 
    1803                 :   // We use a cleanup unless there was already a catch all.
                        2: branch 0 taken
                        0: branch 1 not taken
    1804                2:   if (!HasCatchAll) {
    1805                2:     ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
    1806                2:     Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0));
    1807                 :   }
    1808                 : 
    1809                 :   // Find which handler was matched.
    1810                 :   llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector,
    1811                2:       ESelArgs.begin(), ESelArgs.end(), "selector");
    1812                 : 
                        4: branch 1 taken
                        2: branch 2 taken
    1813                6:   for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
    1814                4:     const ParmVarDecl *CatchParam = Handlers[i].first;
    1815                4:     const Stmt *CatchBody = Handlers[i].second;
    1816                 : 
    1817                4:     llvm::BasicBlock *Next = 0;
    1818                 : 
    1819                 :     // The last handler always matches.
                        2: branch 0 taken
                        2: branch 1 taken
    1820                4:     if (i + 1 != e) {
                        0: branch 0 not taken
                        2: branch 1 taken
    1821                2:       assert(CatchParam && "Only last handler can be a catch all.");
    1822                 : 
    1823                 :       // Test whether this block matches the type for the selector and branch
    1824                 :       // to Match if it does, or to the next BB if it doesn't.
    1825                2:       llvm::BasicBlock *Match = CGF.createBasicBlock("match");
    1826                2:       Next = CGF.createBasicBlock("catch.next");
    1827                 :       llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for,
    1828                2:           CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy));
    1829                 :       CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match,
    1830                2:           Next);
    1831                 : 
    1832                2:       CGF.EmitBlock(Match);
    1833                 :     }
    1834                 : 
                        2: branch 0 taken
                        2: branch 1 taken
    1835                4:     if (CatchBody) {
    1836                 :       llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc,
    1837                2:           CGF.ConvertType(CatchParam->getType()));
    1838                 : 
    1839                 :       // Bind the catch parameter if it exists.
                        2: branch 0 taken
                        0: branch 1 not taken
    1840                2:       if (CatchParam) {
    1841                 :         // CatchParam is a ParmVarDecl because of the grammar
    1842                 :         // construction used to handle this, but for codegen purposes
    1843                 :         // we treat this as a local decl.
    1844                2:         CGF.EmitLocalBlockVarDecl(*CatchParam);
    1845                2:         CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam));
    1846                 :       }
    1847                 : 
    1848                2:       CGF.ObjCEHValueStack.push_back(ExcObject);
    1849                2:       CGF.EmitStmt(CatchBody);
    1850                2:       CGF.ObjCEHValueStack.pop_back();
    1851                 : 
    1852                2:       CGF.EmitBranchThroughCleanup(FinallyEnd);
    1853                 : 
                        2: branch 0 taken
                        0: branch 1 not taken
    1854                2:       if (Next)
    1855                2:         CGF.EmitBlock(Next);
    1856                 :     } else {
                        0: branch 0 not taken
                        2: branch 1 taken
    1857                2:       assert(!Next && "catchup should be last handler.");
    1858                 : 
    1859                2:       CGF.Builder.CreateStore(Exc, RethrowPtr);
    1860                2:       CGF.EmitBranchThroughCleanup(FinallyRethrow);
    1861                 :     }
    1862                 :   }
    1863                 :   // The @finally block is a secondary landing pad for any exceptions thrown in
    1864                 :   // @catch() blocks
    1865                2:   CGF.EmitBlock(CatchInCatch);
    1866                2:   Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
    1867                2:   ESelArgs.clear();
    1868                2:   ESelArgs.push_back(Exc);
    1869                2:   ESelArgs.push_back(Personality);
    1870                 :   // If there is a @catch or @finally clause in outside of this one then we
    1871                 :   // need to make sure that we catch and rethrow it.  
                        0: branch 0 not taken
                        2: branch 1 taken
    1872                2:   if (PrevLandingPad) {
    1873                0:     ESelArgs.push_back(NULLPtr);
    1874                 :   } else {
    1875                2:     ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
    1876                 :   }
    1877                 :   CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(),
    1878                2:       "selector");
    1879                 :   CGF.Builder.CreateCall(llvm_eh_typeid_for,
    1880                2:       CGF.Builder.CreateIntToPtr(ESelArgs[2], PtrTy));
    1881                2:   CGF.Builder.CreateStore(Exc, RethrowPtr);
    1882                2:   CGF.EmitBranchThroughCleanup(FinallyRethrow);
    1883                 : 
    1884                2:   CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
    1885                 : 
    1886                2:   CGF.setInvokeDest(PrevLandingPad);
    1887                 : 
    1888                2:   CGF.EmitBlock(FinallyBlock);
    1889                 : 
    1890                 : 
                        1: branch 0 taken
                        1: branch 1 taken
    1891                2:   if (isTry) {
                        1: branch 0 taken
                        0: branch 1 not taken
    1892                1:     if (const ObjCAtFinallyStmt* FinallyStmt =
    1893                1:         cast<ObjCAtTryStmt>(S).getFinallyStmt())
    1894                1:       CGF.EmitStmt(FinallyStmt->getFinallyBody());
    1895                 :   } else {
    1896                 :     // Emit 'objc_sync_exit(expr)' as finally's sole statement for
    1897                 :     // @synchronized.
    1898                1:     std::vector<const llvm::Type*> Args(1, IdTy);
    1899                 :     llvm::FunctionType *FTy =
    1900                1:       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
    1901                1:     llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
    1902                 :     llvm::Value *SyncArg =
    1903                1:       CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
    1904                1:     SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
    1905                1:     CGF.Builder.CreateCall(SyncExit, SyncArg);
    1906                 :   }
    1907                 : 
                        2: branch 0 taken
                        0: branch 1 not taken
    1908                2:   if (Info.SwitchBlock)
    1909                2:     CGF.EmitBlock(Info.SwitchBlock);
                        2: branch 0 taken
                        0: branch 1 not taken
    1910                2:   if (Info.EndBlock)
    1911                2:     CGF.EmitBlock(Info.EndBlock);
    1912                 : 
    1913                 :   // Branch around the rethrow code.
    1914                2:   CGF.EmitBranch(FinallyEnd);
    1915                 : 
    1916                2:   CGF.EmitBlock(FinallyRethrow);
    1917                 : 
    1918                2:   llvm::Value *ExceptionObject = CGF.Builder.CreateLoad(RethrowPtr);
    1919                2:   llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
                        2: branch 0 taken
                        0: branch 1 not taken
    1920                2:   if (!UnwindBB) {
    1921                2:     CGF.Builder.CreateCall(RethrowFn, ExceptionObject);
    1922                 :     // Exception always thrown, next instruction is never reached.
    1923                2:     CGF.Builder.CreateUnreachable();
    1924                 :   } else {
    1925                 :     // If there is a @catch block outside this scope, we invoke instead of
    1926                 :     // calling because we may return to this function.  This is very slow, but
    1927                 :     // some people still do it.  It would be nice to add an optimised path for
    1928                 :     // this.
    1929                 :     CGF.Builder.CreateInvoke(RethrowFn, UnwindBB, UnwindBB, &ExceptionObject,
    1930                0:         &ExceptionObject+1);
    1931                 :   }
    1932                 : 
    1933                2:   CGF.EmitBlock(FinallyEnd);
    1934                2: }
    1935                 : 
    1936                 : void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
    1937                2:                               const ObjCAtThrowStmt &S) {
    1938                 :   llvm::Value *ExceptionAsObject;
    1939                 : 
    1940                2:   std::vector<const llvm::Type*> Args(1, IdTy);
    1941                 :   llvm::FunctionType *FTy =
    1942                2:     llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
    1943                 :   llvm::Value *ThrowFn =
    1944                2:     CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
    1945                 : 
                        1: branch 1 taken
                        1: branch 2 taken
    1946                2:   if (const Expr *ThrowExpr = S.getThrowExpr()) {
    1947                1:     llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
    1948                1:     ExceptionAsObject = Exception;
    1949                 :   } else {
    1950                 :     assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
                        1: branch 1 taken
                        0: branch 2 not taken
                        1: branch 4 taken
                        0: branch 5 not taken
    1951                1:            "Unexpected rethrow outside @catch block.");
    1952                1:     ExceptionAsObject = CGF.ObjCEHValueStack.back();
    1953                 :   }
    1954                 :   ExceptionAsObject =
    1955                2:       CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp");
    1956                 : 
    1957                 :   // Note: This may have to be an invoke, if we want to support constructs like:
    1958                 :   // @try {
    1959                 :   //  @throw(obj);
    1960                 :   // }
    1961                 :   // @catch(id) ...
    1962                 :   //
    1963                 :   // This is effectively turning @throw into an incredibly-expensive goto, but
    1964                 :   // it may happen as a result of inlining followed by missed optimizations, or
    1965                 :   // as a result of stupidity.
    1966                2:   llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
                        0: branch 0 not taken
                        2: branch 1 taken
    1967                2:   if (!UnwindBB) {
    1968                0:     CGF.Builder.CreateCall(ThrowFn, ExceptionAsObject);
    1969                0:     CGF.Builder.CreateUnreachable();
    1970                 :   } else {
    1971                 :     CGF.Builder.CreateInvoke(ThrowFn, UnwindBB, UnwindBB, &ExceptionAsObject,
    1972                2:         &ExceptionAsObject+1);
    1973                 :   }
    1974                 :   // Clear the insertion point to indicate we are in unreachable code.
    1975                2:   CGF.Builder.ClearInsertionPoint();
    1976                2: }
    1977                 : 
    1978                 : llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
    1979                0:                                           llvm::Value *AddrWeakObj) {
    1980                0:   CGBuilderTy B = CGF.Builder;
    1981                0:   AddrWeakObj = EnforceType(B, AddrWeakObj, IdTy);
    1982                0:   return B.CreateCall(WeakReadFn, AddrWeakObj);
    1983                 : }
    1984                 : 
    1985                 : void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
    1986                0:                                    llvm::Value *src, llvm::Value *dst) {
    1987                0:   CGBuilderTy B = CGF.Builder;
    1988                0:   src = EnforceType(B, src, IdTy);
    1989                0:   dst = EnforceType(B, dst, PtrToIdTy);
    1990                0:   B.CreateCall2(WeakAssignFn, src, dst);
    1991                0: }
    1992                 : 
    1993                 : void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
    1994                0:                                      llvm::Value *src, llvm::Value *dst) {
    1995                0:   CGBuilderTy B = CGF.Builder;
    1996                0:   src = EnforceType(B, src, IdTy);
    1997                0:   dst = EnforceType(B, dst, PtrToIdTy);
    1998                0:   B.CreateCall2(GlobalAssignFn, src, dst);
    1999                0: }
    2000                 : 
    2001                 : void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
    2002                 :                                    llvm::Value *src, llvm::Value *dst,
    2003                0:                                    llvm::Value *ivarOffset) {
    2004                0:   CGBuilderTy B = CGF.Builder;
    2005                0:   src = EnforceType(B, src, IdTy);
    2006                0:   dst = EnforceType(B, dst, PtrToIdTy);
    2007                0:   B.CreateCall3(IvarAssignFn, src, dst, ivarOffset);
    2008                0: }
    2009                 : 
    2010                 : void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
    2011                0:                                          llvm::Value *src, llvm::Value *dst) {
    2012                0:   CGBuilderTy B = CGF.Builder;
    2013                0:   src = EnforceType(B, src, IdTy);
    2014                0:   dst = EnforceType(B, dst, PtrToIdTy);
    2015                0:   B.CreateCall2(StrongCastAssignFn, src, dst);
    2016                0: }
    2017                 : 
    2018                 : void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
    2019                 :                                          llvm::Value *DestPtr,
    2020                 :                                          llvm::Value *SrcPtr,
    2021                0:                                          QualType Ty) {
    2022                0:   CGBuilderTy B = CGF.Builder;
    2023                0:   DestPtr = EnforceType(B, DestPtr, IdTy);
    2024                0:   SrcPtr = EnforceType(B, SrcPtr, PtrToIdTy);
    2025                 : 
    2026                0:   std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
    2027                0:   unsigned long size = TypeInfo.first/8;
    2028                 :   // FIXME: size_t
    2029                0:   llvm::Value *N = llvm::ConstantInt::get(LongTy, size);
    2030                 : 
    2031                0:   B.CreateCall3(MemMoveFn, DestPtr, SrcPtr, N);
    2032                0: }
    2033                 : 
    2034                 : llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
    2035                 :                               const ObjCInterfaceDecl *ID,
    2036                0:                               const ObjCIvarDecl *Ivar) {
    2037                 :   const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
    2038                0:     + '.' + Ivar->getNameAsString();
    2039                 :   // Emit the variable and initialize it with what we think the correct value
    2040                 :   // is.  This allows code compiled with non-fragile ivars to work correctly
    2041                 :   // when linked against code which isn't (most of the time).
    2042                0:   llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
                        0: branch 0 not taken
                        0: branch 1 not taken
    2043                0:   if (!IvarOffsetPointer) {
    2044                0:     uint64_t Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
    2045                 :     llvm::ConstantInt *OffsetGuess =
    2046                0:       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset, "ivar");
    2047                 :     // Don't emit the guess in non-PIC code because the linker will not be able
    2048                 :     // to replace it with the real version for a library.  In non-PIC code you
    2049                 :     // must compile with the fragile ABI if you want to use ivars from a
    2050                 :     // GCC-compiled class.
                        0: branch 1 not taken
                        0: branch 2 not taken
    2051                0:     if (CGM.getLangOptions().PICLevel) {
    2052                 :       llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule,
    2053                 :             llvm::Type::getInt32Ty(VMContext), false,
    2054                0:             llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess");
    2055                 :       IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
    2056                 :             IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage,
    2057                0:             IvarOffsetGV, Name);
    2058                 :     } else {
    2059                 :       IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
    2060                 :               llvm::Type::getInt32PtrTy(VMContext), false,
    2061                0:               llvm::GlobalValue::ExternalLinkage, 0, Name);
    2062                 :     }
    2063                 :   }
    2064                0:   return IvarOffsetPointer;
    2065                 : }
    2066                 : 
    2067                 : LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
    2068                 :                                        QualType ObjectTy,
    2069                 :                                        llvm::Value *BaseValue,
    2070                 :                                        const ObjCIvarDecl *Ivar,
    2071                4:                                        unsigned CVRQualifiers) {
    2072                4:   const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
    2073                 :   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
    2074                4:                                   EmitIvarOffset(CGF, ID, Ivar));
    2075                 : }
    2076                 : 
    2077                 : static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
    2078                 :                                                   const ObjCInterfaceDecl *OID,
    2079                0:                                                   const ObjCIvarDecl *OIVD) {
    2080                0:   llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
    2081                0:   Context.ShallowCollectObjCIvars(OID, Ivars);
                        0: branch 1 not taken
                        0: branch 2 not taken
    2082                0:   for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
                        0: branch 1 not taken
                        0: branch 2 not taken
    2083                0:     if (OIVD == Ivars[k])
    2084                0:       return OID;
    2085                 :   }
    2086                 : 
    2087                 :   // Otherwise check in the super class.
                        0: branch 1 not taken
                        0: branch 2 not taken
    2088                0:   if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
    2089                0:     return FindIvarInterface(Context, Super, OIVD);
    2090                 : 
    2091                0:   return 0;
    2092                 : }
    2093                 : 
    2094                 : llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
    2095                 :                          const ObjCInterfaceDecl *Interface,
    2096                4:                          const ObjCIvarDecl *Ivar) {
                        0: branch 1 not taken
                        4: branch 2 taken
    2097                4:   if (CGM.getLangOptions().ObjCNonFragileABI) {
    2098                0:     Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar);
    2099                 :     return CGF.Builder.CreateLoad(CGF.Builder.CreateLoad(
    2100                0:                 ObjCIvarOffsetVariable(Interface, Ivar), false, "ivar"));
    2101                 :   }
    2102                4:   uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
    2103                4:   return llvm::ConstantInt::get(LongTy, Offset, "ivar");
    2104                 : }
    2105                 : 
    2106                 : CodeGen::CGObjCRuntime *
    2107                7: CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM) {
    2108                7:   return new CGObjCGNU(CGM);
    2109                 : }

Generated: 2010-02-10 01:31 by zcov