zcov: / lib/CodeGen/CGObjCMac.cpp


Files: 1 Branches Taken: 72.8% 587 / 806
Generated: 2010-02-10 01:31 Branches Executed: 88.8% 716 / 806
Line Coverage: 91.2% 1931 / 2117


Programs: 1 Runs 2897


       1                 : //===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
       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 Apple runtime.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "CGObjCRuntime.h"
      15                 : 
      16                 : #include "CodeGenModule.h"
      17                 : #include "CodeGenFunction.h"
      18                 : #include "clang/AST/ASTContext.h"
      19                 : #include "clang/AST/Decl.h"
      20                 : #include "clang/AST/DeclObjC.h"
      21                 : #include "clang/AST/RecordLayout.h"
      22                 : #include "clang/AST/StmtObjC.h"
      23                 : #include "clang/Basic/LangOptions.h"
      24                 : #include "clang/CodeGen/CodeGenOptions.h"
      25                 : 
      26                 : #include "llvm/Intrinsics.h"
      27                 : #include "llvm/LLVMContext.h"
      28                 : #include "llvm/Module.h"
      29                 : #include "llvm/ADT/DenseSet.h"
      30                 : #include "llvm/ADT/SetVector.h"
      31                 : #include "llvm/ADT/SmallString.h"
      32                 : #include "llvm/ADT/SmallPtrSet.h"
      33                 : #include "llvm/Support/raw_ostream.h"
      34                 : #include "llvm/Target/TargetData.h"
      35                 : #include <cstdio>
      36                 : 
      37                 : using namespace clang;
      38                 : using namespace CodeGen;
      39                 : 
      40                 : // Common CGObjCRuntime functions, these don't belong here, but they
      41                 : // don't belong in CGObjCRuntime either so we will live with it for
      42                 : // now.
      43                 : 
      44                 : /// FindIvarInterface - Find the interface containing the ivar.
      45                 : ///
      46                 : /// FIXME: We shouldn't need to do this, the containing context should
      47                 : /// be fixed.
      48                 : static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
      49                 :                                                   const ObjCInterfaceDecl *OID,
      50                 :                                                   const ObjCIvarDecl *OIVD,
      51              843:                                                   unsigned &Index) {
      52                 :   // FIXME: The index here is closely tied to how
      53                 :   // ASTContext::getObjCLayout is implemented. This should be fixed to
      54                 :   // get the information from the layout directly.
      55              843:   Index = 0;
      56              843:   llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
      57              843:   Context.ShallowCollectObjCIvars(OID, Ivars);
                     2906: branch 1 taken
                       85: branch 2 taken
      58             2991:   for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
                      758: branch 1 taken
                     2148: branch 2 taken
      59             2906:     if (OIVD == Ivars[k])
      60              758:       return OID;
      61             2148:     ++Index;
      62                 :   }
      63                 : 
      64                 :   // Otherwise check in the super class.
                       85: branch 1 taken
                        0: branch 2 not taken
      65               85:   if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
      66               85:     return FindIvarInterface(Context, Super, OIVD, Index);
      67                 : 
      68                0:   return 0;
      69                 : }
      70                 : 
      71                 : static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
      72                 :                                      const ObjCInterfaceDecl *OID,
      73                 :                                      const ObjCImplementationDecl *ID,
      74              642:                                      const ObjCIvarDecl *Ivar) {
      75                 :   unsigned Index;
      76                 :   const ObjCInterfaceDecl *Container =
      77              642:     FindIvarInterface(CGM.getContext(), OID, Ivar, Index);
                        0: branch 0 not taken
                      642: branch 1 taken
      78              642:   assert(Container && "Unable to find ivar container");
      79                 : 
      80                 :   // If we know have an implementation (and the ivar is in it) then
      81                 :   // look up in the implementation layout.
      82                 :   const ASTRecordLayout *RL;
                      176: branch 0 taken
                      466: branch 1 taken
                      154: branch 3 taken
                       22: branch 4 taken
                      154: branch 5 taken
                      488: branch 6 taken
      83              642:   if (ID && ID->getClassInterface() == Container)
      84              154:     RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
      85                 :   else
      86              488:     RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
      87              642:   return RL->getFieldOffset(Index);
      88                 : }
      89                 : 
      90                 : uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
      91                 :                                               const ObjCInterfaceDecl *OID,
      92              410:                                               const ObjCIvarDecl *Ivar) {
      93              410:   return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8;
      94                 : }
      95                 : 
      96                 : uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
      97                 :                                               const ObjCImplementationDecl *OID,
      98              176:                                               const ObjCIvarDecl *Ivar) {
      99              176:   return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8;
     100                 : }
     101                 : 
     102                 : LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
     103                 :                                                const ObjCInterfaceDecl *OID,
     104                 :                                                llvm::Value *BaseValue,
     105                 :                                                const ObjCIvarDecl *Ivar,
     106                 :                                                unsigned CVRQualifiers,
     107              293:                                                llvm::Value *Offset) {
     108                 :   // Compute (type*) ( (char *) BaseValue + Offset)
     109              293:   const llvm::Type *I8Ptr = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
     110              293:   QualType IvarTy = Ivar->getType();
     111              293:   const llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
     112              293:   llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr);
     113              293:   V = CGF.Builder.CreateGEP(V, Offset, "add.ptr");
     114              293:   V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
     115                 : 
     116              293:   Qualifiers Quals = CGF.MakeQualifiers(IvarTy);
     117              293:   Quals.addCVRQualifiers(CVRQualifiers);
     118                 : 
                       56: branch 1 taken
                      237: branch 2 taken
     119              293:   if (Ivar->isBitField()) {
     120                 :     // We need to compute the bit offset for the bit-field, the offset
     121                 :     // is to the byte. Note, there is a subtle invariant here: we can
     122                 :     // only call this routine on non-sythesized ivars but we may be
     123                 :     // called for synthesized ivars. However, a synthesized ivar can
     124                 :     // never be a bit-field so this is safe.
     125               56:     uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8;
     126                 : 
     127                 :     uint64_t BitFieldSize =
     128               56:       Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
     129                 :     return LValue::MakeBitfield(V, BitOffset, BitFieldSize,
     130                 :                                 IvarTy->isSignedIntegerType(),
     131               56:                                 Quals.getCVRQualifiers());
     132                 :   }
     133                 : 
     134                 :   
     135              237:   LValue LV = LValue::MakeAddr(V, Quals);
     136              237:   return LV;
     137                 : }
     138                 : 
     139                 : ///
     140                 : 
     141                 : namespace {
     142                 : 
     143                 : typedef std::vector<llvm::Constant*> ConstantVector;
     144                 : 
     145                 : // FIXME: We should find a nicer way to make the labels for metadata, string
     146                 : // concatenation is lame.
     147                 : 
     148                 : class ObjCCommonTypesHelper {
     149                 : protected:
     150                 :   llvm::LLVMContext &VMContext;
     151                 : 
     152                 : private:
     153              167:   llvm::Constant *getMessageSendFn() const {
     154                 :     // id objc_msgSend (id, SEL, ...)
     155              167:     std::vector<const llvm::Type*> Params;
     156              167:     Params.push_back(ObjectPtrTy);
     157              167:     Params.push_back(SelectorPtrTy);
     158                 :     return
     159                 :       CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     160                 :                                                         Params, true),
     161              167:                                 "objc_msgSend");
     162                 :   }
     163                 : 
     164                6:   llvm::Constant *getMessageSendStretFn() const {
     165                 :     // id objc_msgSend_stret (id, SEL, ...)
     166                6:     std::vector<const llvm::Type*> Params;
     167                6:     Params.push_back(ObjectPtrTy);
     168                6:     Params.push_back(SelectorPtrTy);
     169                 :     return
     170                 :       CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
     171                 :                                                         Params, true),
     172                6:                                 "objc_msgSend_stret");
     173                 : 
     174                 :   }
     175                 : 
     176                9:   llvm::Constant *getMessageSendFpretFn() const {
     177                 :     // FIXME: This should be long double on x86_64?
     178                 :     // [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
     179                9:     std::vector<const llvm::Type*> Params;
     180                9:     Params.push_back(ObjectPtrTy);
     181                9:     Params.push_back(SelectorPtrTy);
     182                 :     return
     183                 :       CGM.CreateRuntimeFunction(llvm::FunctionType::get(
     184                 :                                              llvm::Type::getDoubleTy(VMContext),
     185                 :                                                         Params,
     186                 :                                                         true),
     187                9:                                 "objc_msgSend_fpret");
     188                 : 
     189                 :   }
     190                 : 
     191               29:   llvm::Constant *getMessageSendSuperFn() const {
     192                 :     // id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
     193               29:     const char *SuperName = "objc_msgSendSuper";
     194               29:     std::vector<const llvm::Type*> Params;
     195               29:     Params.push_back(SuperPtrTy);
     196               29:     Params.push_back(SelectorPtrTy);
     197                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     198                 :                                                              Params, true),
     199               29:                                      SuperName);
     200                 :   }
     201                 : 
     202                2:   llvm::Constant *getMessageSendSuperFn2() const {
     203                 :     // id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
     204                2:     const char *SuperName = "objc_msgSendSuper2";
     205                2:     std::vector<const llvm::Type*> Params;
     206                2:     Params.push_back(SuperPtrTy);
     207                2:     Params.push_back(SelectorPtrTy);
     208                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     209                 :                                                              Params, true),
     210                2:                                      SuperName);
     211                 :   }
     212                 : 
     213                4:   llvm::Constant *getMessageSendSuperStretFn() const {
     214                 :     // void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super,
     215                 :     //                              SEL op, ...)
     216                4:     std::vector<const llvm::Type*> Params;
     217                4:     Params.push_back(Int8PtrTy);
     218                4:     Params.push_back(SuperPtrTy);
     219                4:     Params.push_back(SelectorPtrTy);
     220                 :     return CGM.CreateRuntimeFunction(
     221                 :       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
     222                 :                               Params, true),
     223                4:       "objc_msgSendSuper_stret");
     224                 :   }
     225                 : 
     226                0:   llvm::Constant *getMessageSendSuperStretFn2() const {
     227                 :     // void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
     228                 :     //                               SEL op, ...)
     229                0:     std::vector<const llvm::Type*> Params;
     230                0:     Params.push_back(Int8PtrTy);
     231                0:     Params.push_back(SuperPtrTy);
     232                0:     Params.push_back(SelectorPtrTy);
     233                 :     return CGM.CreateRuntimeFunction(
     234                 :       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
     235                 :                               Params, true),
     236                0:       "objc_msgSendSuper2_stret");
     237                 :   }
     238                 : 
     239                4:   llvm::Constant *getMessageSendSuperFpretFn() const {
     240                 :     // There is no objc_msgSendSuper_fpret? How can that work?
     241                4:     return getMessageSendSuperFn();
     242                 :   }
     243                 : 
     244                0:   llvm::Constant *getMessageSendSuperFpretFn2() const {
     245                 :     // There is no objc_msgSendSuper_fpret? How can that work?
     246                0:     return getMessageSendSuperFn2();
     247                 :   }
     248                 : 
     249                 : protected:
     250                 :   CodeGen::CodeGenModule &CGM;
     251                 : 
     252                 : public:
     253                 :   const llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
     254                 :   const llvm::Type *Int8PtrTy;
     255                 : 
     256                 :   /// ObjectPtrTy - LLVM type for object handles (typeof(id))
     257                 :   const llvm::Type *ObjectPtrTy;
     258                 : 
     259                 :   /// PtrObjectPtrTy - LLVM type for id *
     260                 :   const llvm::Type *PtrObjectPtrTy;
     261                 : 
     262                 :   /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
     263                 :   const llvm::Type *SelectorPtrTy;
     264                 :   /// ProtocolPtrTy - LLVM type for external protocol handles
     265                 :   /// (typeof(Protocol))
     266                 :   const llvm::Type *ExternalProtocolPtrTy;
     267                 : 
     268                 :   // SuperCTy - clang type for struct objc_super.
     269                 :   QualType SuperCTy;
     270                 :   // SuperPtrCTy - clang type for struct objc_super *.
     271                 :   QualType SuperPtrCTy;
     272                 : 
     273                 :   /// SuperTy - LLVM type for struct objc_super.
     274                 :   const llvm::StructType *SuperTy;
     275                 :   /// SuperPtrTy - LLVM type for struct objc_super *.
     276                 :   const llvm::Type *SuperPtrTy;
     277                 : 
     278                 :   /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
     279                 :   /// in GCC parlance).
     280                 :   const llvm::StructType *PropertyTy;
     281                 : 
     282                 :   /// PropertyListTy - LLVM type for struct objc_property_list
     283                 :   /// (_prop_list_t in GCC parlance).
     284                 :   const llvm::StructType *PropertyListTy;
     285                 :   /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
     286                 :   const llvm::Type *PropertyListPtrTy;
     287                 : 
     288                 :   // MethodTy - LLVM type for struct objc_method.
     289                 :   const llvm::StructType *MethodTy;
     290                 : 
     291                 :   /// CacheTy - LLVM type for struct objc_cache.
     292                 :   const llvm::Type *CacheTy;
     293                 :   /// CachePtrTy - LLVM type for struct objc_cache *.
     294                 :   const llvm::Type *CachePtrTy;
     295                 : 
     296                8:   llvm::Constant *getGetPropertyFn() {
     297                8:     CodeGen::CodeGenTypes &Types = CGM.getTypes();
     298                8:     ASTContext &Ctx = CGM.getContext();
     299                 :     // id objc_getProperty (id, SEL, ptrdiff_t, bool)
     300                8:     llvm::SmallVector<QualType,16> Params;
     301                8:     QualType IdType = Ctx.getObjCIdType();
     302                8:     QualType SelType = Ctx.getObjCSelType();
     303                8:     Params.push_back(IdType);
     304                8:     Params.push_back(SelType);
     305                8:     Params.push_back(Ctx.LongTy);
     306                8:     Params.push_back(Ctx.BoolTy);
     307                 :     const llvm::FunctionType *FTy =
     308                 :       Types.GetFunctionType(Types.getFunctionInfo(IdType, Params,
     309                8:                                                   CC_Default, false), false);
     310                8:     return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
     311                 :   }
     312                 : 
     313               10:   llvm::Constant *getSetPropertyFn() {
     314               10:     CodeGen::CodeGenTypes &Types = CGM.getTypes();
     315               10:     ASTContext &Ctx = CGM.getContext();
     316                 :     // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
     317               10:     llvm::SmallVector<QualType,16> Params;
     318               10:     QualType IdType = Ctx.getObjCIdType();
     319               10:     QualType SelType = Ctx.getObjCSelType();
     320               10:     Params.push_back(IdType);
     321               10:     Params.push_back(SelType);
     322               10:     Params.push_back(Ctx.LongTy);
     323               10:     Params.push_back(IdType);
     324               10:     Params.push_back(Ctx.BoolTy);
     325               10:     Params.push_back(Ctx.BoolTy);
     326                 :     const llvm::FunctionType *FTy =
     327                 :       Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
     328               10:                                                   CC_Default, false), false);
     329               10:     return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
     330                 :   }
     331                 : 
     332                4:   llvm::Constant *getEnumerationMutationFn() {
     333                4:     CodeGen::CodeGenTypes &Types = CGM.getTypes();
     334                4:     ASTContext &Ctx = CGM.getContext();
     335                 :     // void objc_enumerationMutation (id)
     336                4:     llvm::SmallVector<QualType,16> Params;
     337                4:     Params.push_back(Ctx.getObjCIdType());
     338                 :     const llvm::FunctionType *FTy =
     339                 :       Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
     340                4:                                                   CC_Default, false), false);
     341                4:     return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
     342                 :   }
     343                 : 
     344                 :   /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
     345               15:   llvm::Constant *getGcReadWeakFn() {
     346                 :     // id objc_read_weak (id *)
     347               15:     std::vector<const llvm::Type*> Args;
     348               15:     Args.push_back(ObjectPtrTy->getPointerTo());
     349                 :     llvm::FunctionType *FTy =
     350               15:       llvm::FunctionType::get(ObjectPtrTy, Args, false);
     351               15:     return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
     352                 :   }
     353                 : 
     354                 :   /// GcAssignWeakFn -- LLVM objc_assign_weak function.
     355               11:   llvm::Constant *getGcAssignWeakFn() {
     356                 :     // id objc_assign_weak (id, id *)
     357               11:     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     358               11:     Args.push_back(ObjectPtrTy->getPointerTo());
     359                 :     llvm::FunctionType *FTy =
     360               11:       llvm::FunctionType::get(ObjectPtrTy, Args, false);
     361               11:     return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
     362                 :   }
     363                 : 
     364                 :   /// GcAssignGlobalFn -- LLVM objc_assign_global function.
     365               53:   llvm::Constant *getGcAssignGlobalFn() {
     366                 :     // id objc_assign_global(id, id *)
     367               53:     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     368               53:     Args.push_back(ObjectPtrTy->getPointerTo());
     369                 :     llvm::FunctionType *FTy =
     370               53:       llvm::FunctionType::get(ObjectPtrTy, Args, false);
     371               53:     return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
     372                 :   }
     373                 : 
     374                 :   /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
     375               36:   llvm::Constant *getGcAssignIvarFn() {
     376                 :     // id objc_assign_ivar(id, id *, ptrdiff_t)
     377               36:     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     378               36:     Args.push_back(ObjectPtrTy->getPointerTo());
     379               36:     Args.push_back(LongTy);
     380                 :     llvm::FunctionType *FTy =
     381               36:       llvm::FunctionType::get(ObjectPtrTy, Args, false);
     382               36:     return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
     383                 :   }
     384                 : 
     385                 :   /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
     386                5:   llvm::Constant *GcMemmoveCollectableFn() {
     387                 :     // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
     388                5:     std::vector<const llvm::Type*> Args(1, Int8PtrTy);
     389                5:     Args.push_back(Int8PtrTy);
     390                5:     Args.push_back(LongTy);
     391                5:     llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
     392                5:     return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
     393                 :   }
     394                 : 
     395                 :   /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
     396               22:   llvm::Constant *getGcAssignStrongCastFn() {
     397                 :     // id objc_assign_global(id, id *)
     398               22:     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     399               22:     Args.push_back(ObjectPtrTy->getPointerTo());
     400                 :     llvm::FunctionType *FTy =
     401               22:       llvm::FunctionType::get(ObjectPtrTy, Args, false);
     402               22:     return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
     403                 :   }
     404                 : 
     405                 :   /// ExceptionThrowFn - LLVM objc_exception_throw function.
     406               21:   llvm::Constant *getExceptionThrowFn() {
     407                 :     // void objc_exception_throw(id)
     408               21:     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     409                 :     llvm::FunctionType *FTy =
     410               21:       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
     411               21:     return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
     412                 :   }
     413                 : 
     414                 :   /// SyncEnterFn - LLVM object_sync_enter function.
     415                7:   llvm::Constant *getSyncEnterFn() {
     416                 :     // void objc_sync_enter (id)
     417                7:     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     418                 :     llvm::FunctionType *FTy =
     419                7:       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
     420                7:     return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
     421                 :   }
     422                 : 
     423                 :   /// SyncExitFn - LLVM object_sync_exit function.
     424                7:   llvm::Constant *getSyncExitFn() {
     425                 :     // void objc_sync_exit (id)
     426                7:     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     427                 :     llvm::FunctionType *FTy =
     428                7:       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
     429                7:     return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
     430                 :   }
     431                 : 
     432              177:   llvm::Constant *getSendFn(bool IsSuper) const {
                       25: branch 0 taken
                      152: branch 1 taken
     433              177:     return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
     434                 :   }
     435                 : 
     436               17:   llvm::Constant *getSendFn2(bool IsSuper) const {
                        2: branch 0 taken
                       15: branch 1 taken
     437               17:     return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
     438                 :   }
     439                 : 
     440               10:   llvm::Constant *getSendStretFn(bool IsSuper) const {
                        4: branch 0 taken
                        6: branch 1 taken
     441               10:     return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
     442                 :   }
     443                 : 
     444                0:   llvm::Constant *getSendStretFn2(bool IsSuper) const {
                        0: branch 0 not taken
                        0: branch 1 not taken
     445                0:     return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
     446                 :   }
     447                 : 
     448               12:   llvm::Constant *getSendFpretFn(bool IsSuper) const {
                        4: branch 0 taken
                        8: branch 1 taken
     449               12:     return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
     450                 :   }
     451                 : 
     452                1:   llvm::Constant *getSendFpretFn2(bool IsSuper) const {
                        0: branch 0 not taken
                        1: branch 1 taken
     453                1:     return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
     454                 :   }
     455                 : 
     456                 :   ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
     457              129:   ~ObjCCommonTypesHelper(){}
     458                 : };
     459                 : 
     460                 : /// ObjCTypesHelper - Helper class that encapsulates lazy
     461                 : /// construction of varies types used during ObjC generation.
     462                 : class ObjCTypesHelper : public ObjCCommonTypesHelper {
     463                 : public:
     464                 :   /// SymtabTy - LLVM type for struct objc_symtab.
     465                 :   const llvm::StructType *SymtabTy;
     466                 :   /// SymtabPtrTy - LLVM type for struct objc_symtab *.
     467                 :   const llvm::Type *SymtabPtrTy;
     468                 :   /// ModuleTy - LLVM type for struct objc_module.
     469                 :   const llvm::StructType *ModuleTy;
     470                 : 
     471                 :   /// ProtocolTy - LLVM type for struct objc_protocol.
     472                 :   const llvm::StructType *ProtocolTy;
     473                 :   /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
     474                 :   const llvm::Type *ProtocolPtrTy;
     475                 :   /// ProtocolExtensionTy - LLVM type for struct
     476                 :   /// objc_protocol_extension.
     477                 :   const llvm::StructType *ProtocolExtensionTy;
     478                 :   /// ProtocolExtensionTy - LLVM type for struct
     479                 :   /// objc_protocol_extension *.
     480                 :   const llvm::Type *ProtocolExtensionPtrTy;
     481                 :   /// MethodDescriptionTy - LLVM type for struct
     482                 :   /// objc_method_description.
     483                 :   const llvm::StructType *MethodDescriptionTy;
     484                 :   /// MethodDescriptionListTy - LLVM type for struct
     485                 :   /// objc_method_description_list.
     486                 :   const llvm::StructType *MethodDescriptionListTy;
     487                 :   /// MethodDescriptionListPtrTy - LLVM type for struct
     488                 :   /// objc_method_description_list *.
     489                 :   const llvm::Type *MethodDescriptionListPtrTy;
     490                 :   /// ProtocolListTy - LLVM type for struct objc_property_list.
     491                 :   const llvm::Type *ProtocolListTy;
     492                 :   /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
     493                 :   const llvm::Type *ProtocolListPtrTy;
     494                 :   /// CategoryTy - LLVM type for struct objc_category.
     495                 :   const llvm::StructType *CategoryTy;
     496                 :   /// ClassTy - LLVM type for struct objc_class.
     497                 :   const llvm::StructType *ClassTy;
     498                 :   /// ClassPtrTy - LLVM type for struct objc_class *.
     499                 :   const llvm::Type *ClassPtrTy;
     500                 :   /// ClassExtensionTy - LLVM type for struct objc_class_ext.
     501                 :   const llvm::StructType *ClassExtensionTy;
     502                 :   /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
     503                 :   const llvm::Type *ClassExtensionPtrTy;
     504                 :   // IvarTy - LLVM type for struct objc_ivar.
     505                 :   const llvm::StructType *IvarTy;
     506                 :   /// IvarListTy - LLVM type for struct objc_ivar_list.
     507                 :   const llvm::Type *IvarListTy;
     508                 :   /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
     509                 :   const llvm::Type *IvarListPtrTy;
     510                 :   /// MethodListTy - LLVM type for struct objc_method_list.
     511                 :   const llvm::Type *MethodListTy;
     512                 :   /// MethodListPtrTy - LLVM type for struct objc_method_list *.
     513                 :   const llvm::Type *MethodListPtrTy;
     514                 : 
     515                 :   /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
     516                 :   const llvm::Type *ExceptionDataTy;
     517                 : 
     518                 :   /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
     519               22:   llvm::Constant *getExceptionTryEnterFn() {
     520               22:     std::vector<const llvm::Type*> Params;
     521               22:     Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
     522                 :     return CGM.CreateRuntimeFunction(
     523                 :       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
     524                 :                               Params, false),
     525               22:       "objc_exception_try_enter");
     526                 :   }
     527                 : 
     528                 :   /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
     529               15:   llvm::Constant *getExceptionTryExitFn() {
     530               15:     std::vector<const llvm::Type*> Params;
     531               15:     Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
     532                 :     return CGM.CreateRuntimeFunction(
     533                 :       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
     534                 :                               Params, false),
     535               15:       "objc_exception_try_exit");
     536                 :   }
     537                 : 
     538                 :   /// ExceptionExtractFn - LLVM objc_exception_extract function.
     539               22:   llvm::Constant *getExceptionExtractFn() {
     540               22:     std::vector<const llvm::Type*> Params;
     541               22:     Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
     542                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     543                 :                                                              Params, false),
     544               22:                                      "objc_exception_extract");
     545                 : 
     546                 :   }
     547                 : 
     548                 :   /// ExceptionMatchFn - LLVM objc_exception_match function.
     549                4:   llvm::Constant *getExceptionMatchFn() {
     550                4:     std::vector<const llvm::Type*> Params;
     551                4:     Params.push_back(ClassPtrTy);
     552                4:     Params.push_back(ObjectPtrTy);
     553                 :     return CGM.CreateRuntimeFunction(
     554                 :       llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
     555                 :                               Params, false),
     556                4:       "objc_exception_match");
     557                 : 
     558                 :   }
     559                 : 
     560                 :   /// SetJmpFn - LLVM _setjmp function.
     561               22:   llvm::Constant *getSetJmpFn() {
     562               22:     std::vector<const llvm::Type*> Params;
     563               22:     Params.push_back(llvm::Type::getInt32PtrTy(VMContext));
     564                 :     return
     565                 :       CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
     566                 :                                                         Params, false),
     567               22:                                 "_setjmp");
     568                 : 
     569                 :   }
     570                 : 
     571                 : public:
     572                 :   ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
     573              110:   ~ObjCTypesHelper() {}
     574                 : };
     575                 : 
     576                 : /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
     577                 : /// modern abi
     578                 : class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
     579                 : public:
     580                 : 
     581                 :   // MethodListnfABITy - LLVM for struct _method_list_t
     582                 :   const llvm::StructType *MethodListnfABITy;
     583                 : 
     584                 :   // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
     585                 :   const llvm::Type *MethodListnfABIPtrTy;
     586                 : 
     587                 :   // ProtocolnfABITy = LLVM for struct _protocol_t
     588                 :   const llvm::StructType *ProtocolnfABITy;
     589                 : 
     590                 :   // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
     591                 :   const llvm::Type *ProtocolnfABIPtrTy;
     592                 : 
     593                 :   // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
     594                 :   const llvm::StructType *ProtocolListnfABITy;
     595                 : 
     596                 :   // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
     597                 :   const llvm::Type *ProtocolListnfABIPtrTy;
     598                 : 
     599                 :   // ClassnfABITy - LLVM for struct _class_t
     600                 :   const llvm::StructType *ClassnfABITy;
     601                 : 
     602                 :   // ClassnfABIPtrTy - LLVM for struct _class_t*
     603                 :   const llvm::Type *ClassnfABIPtrTy;
     604                 : 
     605                 :   // IvarnfABITy - LLVM for struct _ivar_t
     606                 :   const llvm::StructType *IvarnfABITy;
     607                 : 
     608                 :   // IvarListnfABITy - LLVM for struct _ivar_list_t
     609                 :   const llvm::StructType *IvarListnfABITy;
     610                 : 
     611                 :   // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
     612                 :   const llvm::Type *IvarListnfABIPtrTy;
     613                 : 
     614                 :   // ClassRonfABITy - LLVM for struct _class_ro_t
     615                 :   const llvm::StructType *ClassRonfABITy;
     616                 : 
     617                 :   // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
     618                 :   const llvm::Type *ImpnfABITy;
     619                 : 
     620                 :   // CategorynfABITy - LLVM for struct _category_t
     621                 :   const llvm::StructType *CategorynfABITy;
     622                 : 
     623                 :   // New types for nonfragile abi messaging.
     624                 : 
     625                 :   // MessageRefTy - LLVM for:
     626                 :   // struct _message_ref_t {
     627                 :   //   IMP messenger;
     628                 :   //   SEL name;
     629                 :   // };
     630                 :   const llvm::StructType *MessageRefTy;
     631                 :   // MessageRefCTy - clang type for struct _message_ref_t
     632                 :   QualType MessageRefCTy;
     633                 : 
     634                 :   // MessageRefPtrTy - LLVM for struct _message_ref_t*
     635                 :   const llvm::Type *MessageRefPtrTy;
     636                 :   // MessageRefCPtrTy - clang type for struct _message_ref_t*
     637                 :   QualType MessageRefCPtrTy;
     638                 : 
     639                 :   // MessengerTy - Type of the messenger (shown as IMP above)
     640                 :   const llvm::FunctionType *MessengerTy;
     641                 : 
     642                 :   // SuperMessageRefTy - LLVM for:
     643                 :   // struct _super_message_ref_t {
     644                 :   //   SUPER_IMP messenger;
     645                 :   //   SEL name;
     646                 :   // };
     647                 :   const llvm::StructType *SuperMessageRefTy;
     648                 : 
     649                 :   // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
     650                 :   const llvm::Type *SuperMessageRefPtrTy;
     651                 : 
     652                2:   llvm::Constant *getMessageSendFixupFn() {
     653                 :     // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
     654                2:     std::vector<const llvm::Type*> Params;
     655                2:     Params.push_back(ObjectPtrTy);
     656                2:     Params.push_back(MessageRefPtrTy);
     657                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     658                 :                                                              Params, true),
     659                2:                                      "objc_msgSend_fixup");
     660                 :   }
     661                 : 
     662                0:   llvm::Constant *getMessageSendFpretFixupFn() {
     663                 :     // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
     664                0:     std::vector<const llvm::Type*> Params;
     665                0:     Params.push_back(ObjectPtrTy);
     666                0:     Params.push_back(MessageRefPtrTy);
     667                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     668                 :                                                              Params, true),
     669                0:                                      "objc_msgSend_fpret_fixup");
     670                 :   }
     671                 : 
     672                0:   llvm::Constant *getMessageSendStretFixupFn() {
     673                 :     // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
     674                0:     std::vector<const llvm::Type*> Params;
     675                0:     Params.push_back(ObjectPtrTy);
     676                0:     Params.push_back(MessageRefPtrTy);
     677                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     678                 :                                                              Params, true),
     679                0:                                      "objc_msgSend_stret_fixup");
     680                 :   }
     681                 : 
     682                 :   llvm::Constant *getMessageSendIdFixupFn() {
     683                 :     // id objc_msgSendId_fixup(id, struct message_ref_t*, ...)
     684                 :     std::vector<const llvm::Type*> Params;
     685                 :     Params.push_back(ObjectPtrTy);
     686                 :     Params.push_back(MessageRefPtrTy);
     687                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     688                 :                                                              Params, true),
     689                 :                                      "objc_msgSendId_fixup");
     690                 :   }
     691                 : 
     692                 :   llvm::Constant *getMessageSendIdStretFixupFn() {
     693                 :     // id objc_msgSendId_stret_fixup(id, struct message_ref_t*, ...)
     694                 :     std::vector<const llvm::Type*> Params;
     695                 :     Params.push_back(ObjectPtrTy);
     696                 :     Params.push_back(MessageRefPtrTy);
     697                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     698                 :                                                              Params, true),
     699                 :                                      "objc_msgSendId_stret_fixup");
     700                 :   }
     701                0:   llvm::Constant *getMessageSendSuper2FixupFn() {
     702                 :     // id objc_msgSendSuper2_fixup (struct objc_super *,
     703                 :     //                              struct _super_message_ref_t*, ...)
     704                0:     std::vector<const llvm::Type*> Params;
     705                0:     Params.push_back(SuperPtrTy);
     706                0:     Params.push_back(SuperMessageRefPtrTy);
     707                 :     return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     708                 :                                                               Params, true),
     709                0:                                       "objc_msgSendSuper2_fixup");
     710                 :   }
     711                 : 
     712                0:   llvm::Constant *getMessageSendSuper2StretFixupFn() {
     713                 :     // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
     714                 :     //                                   struct _super_message_ref_t*, ...)
     715                0:     std::vector<const llvm::Type*> Params;
     716                0:     Params.push_back(SuperPtrTy);
     717                0:     Params.push_back(SuperMessageRefPtrTy);
     718                 :     return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
     719                 :                                                               Params, true),
     720                0:                                       "objc_msgSendSuper2_stret_fixup");
     721                 :   }
     722                 : 
     723                 : 
     724                 : 
     725                 :   /// EHPersonalityPtr - LLVM value for an i8* to the Objective-C
     726                 :   /// exception personality function.
     727               14:   llvm::Value *getEHPersonalityPtr() {
     728                 :     llvm::Constant *Personality =
     729                 :       CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext),
     730                 :                                                         true),
     731               14:                                 "__objc_personality_v0");
     732               14:     return llvm::ConstantExpr::getBitCast(Personality, Int8PtrTy);
     733                 :   }
     734                 : 
     735                2:   llvm::Constant *getUnwindResumeOrRethrowFn() {
     736                2:     std::vector<const llvm::Type*> Params;
     737                2:     Params.push_back(Int8PtrTy);
     738                 :     return CGM.CreateRuntimeFunction(
     739                 :       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
     740                 :                               Params, false),
     741                2:       "_Unwind_Resume_or_Rethrow");
     742                 :   }
     743                 : 
     744                6:   llvm::Constant *getObjCEndCatchFn() {
     745                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
     746                 :                                                              false),
     747                6:                                      "objc_end_catch");
     748                 : 
     749                 :   }
     750                 : 
     751                6:   llvm::Constant *getObjCBeginCatchFn() {
     752                6:     std::vector<const llvm::Type*> Params;
     753                6:     Params.push_back(Int8PtrTy);
     754                 :     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
     755                 :                                                              Params, false),
     756                6:                                      "objc_begin_catch");
     757                 :   }
     758                 : 
     759                 :   const llvm::StructType *EHTypeTy;
     760                 :   const llvm::Type *EHTypePtrTy;
     761                 : 
     762                 :   ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
     763               19:   ~ObjCNonFragileABITypesHelper(){}
     764                 : };
     765                 : 
                        0: branch 18 not taken
                      129: branch 19 taken
                        0: branch 39 not taken
                        0: branch 40 not taken
                        0: branch 60 not taken
                        0: branch 61 not taken
     766              129: class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
     767                 : public:
     768                 :   // FIXME - accessibility
     769              152:   class GC_IVAR {
     770                 :   public:
     771                 :     unsigned ivar_bytepos;
     772                 :     unsigned ivar_size;
     773              152:     GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
     774              152:       : ivar_bytepos(bytepos), ivar_size(size) {}
     775                 : 
     776                 :     // Allow sorting based on byte pos.
     777                0:     bool operator<(const GC_IVAR &b) const {
     778                0:       return ivar_bytepos < b.ivar_bytepos;
     779                 :     }
     780                 :   };
     781                 : 
     782               32:   class SKIP_SCAN {
     783                 :   public:
     784                 :     unsigned skip;
     785                 :     unsigned scan;
     786               29:     SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
     787               29:       : skip(_skip), scan(_scan) {}
     788                 :   };
     789                 : 
     790                 : protected:
     791                 :   CodeGen::CodeGenModule &CGM;
     792                 :   llvm::LLVMContext &VMContext;
     793                 :   // FIXME! May not be needing this after all.
     794                 :   unsigned ObjCABI;
     795                 : 
     796                 :   // gc ivar layout bitmap calculation helper caches.
     797                 :   llvm::SmallVector<GC_IVAR, 16> SkipIvars;
     798                 :   llvm::SmallVector<GC_IVAR, 16> IvarsInfo;
     799                 : 
     800                 :   /// LazySymbols - Symbols to generate a lazy reference for. See
     801                 :   /// DefinedSymbols and FinishModule().
     802                 :   llvm::SetVector<IdentifierInfo*> LazySymbols;
     803                 : 
     804                 :   /// DefinedSymbols - External symbols which are defined by this
     805                 :   /// module. The symbols in this list and LazySymbols are used to add
     806                 :   /// special linker symbols which ensure that Objective-C modules are
     807                 :   /// linked properly.
     808                 :   llvm::SetVector<IdentifierInfo*> DefinedSymbols;
     809                 : 
     810                 :   /// ClassNames - uniqued class names.
     811                 :   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
     812                 : 
     813                 :   /// MethodVarNames - uniqued method variable names.
     814                 :   llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
     815                 : 
     816                 :   /// MethodVarTypes - uniqued method type signatures. We have to use
     817                 :   /// a StringMap here because have no other unique reference.
     818                 :   llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
     819                 : 
     820                 :   /// MethodDefinitions - map of methods which have been defined in
     821                 :   /// this translation unit.
     822                 :   llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
     823                 : 
     824                 :   /// PropertyNames - uniqued method variable names.
     825                 :   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
     826                 : 
     827                 :   /// ClassReferences - uniqued class references.
     828                 :   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
     829                 : 
     830                 :   /// SelectorReferences - uniqued selector references.
     831                 :   llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
     832                 : 
     833                 :   /// Protocols - Protocols for which an objc_protocol structure has
     834                 :   /// been emitted. Forward declarations are handled by creating an
     835                 :   /// empty structure whose initializer is filled in when/if defined.
     836                 :   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
     837                 : 
     838                 :   /// DefinedProtocols - Protocols which have actually been
     839                 :   /// defined. We should not need this, see FIXME in GenerateProtocol.
     840                 :   llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
     841                 : 
     842                 :   /// DefinedClasses - List of defined classes.
     843                 :   std::vector<llvm::GlobalValue*> DefinedClasses;
     844                 : 
     845                 :   /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
     846                 :   std::vector<llvm::GlobalValue*> DefinedNonLazyClasses;
     847                 : 
     848                 :   /// DefinedCategories - List of defined categories.
     849                 :   std::vector<llvm::GlobalValue*> DefinedCategories;
     850                 : 
     851                 :   /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
     852                 :   std::vector<llvm::GlobalValue*> DefinedNonLazyCategories;
     853                 : 
     854                 :   /// GetNameForMethod - Return a name for the given method.
     855                 :   /// \param[out] NameOut - The return value.
     856                 :   void GetNameForMethod(const ObjCMethodDecl *OMD,
     857                 :                         const ObjCContainerDecl *CD,
     858                 :                         llvm::SmallVectorImpl<char> &NameOut);
     859                 : 
     860                 :   /// GetMethodVarName - Return a unique constant for the given
     861                 :   /// selector's name. The return value has type char *.
     862                 :   llvm::Constant *GetMethodVarName(Selector Sel);
     863                 :   llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
     864                 :   llvm::Constant *GetMethodVarName(const std::string &Name);
     865                 : 
     866                 :   /// GetMethodVarType - Return a unique constant for the given
     867                 :   /// selector's name. The return value has type char *.
     868                 : 
     869                 :   // FIXME: This is a horrible name.
     870                 :   llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
     871                 :   llvm::Constant *GetMethodVarType(const FieldDecl *D);
     872                 : 
     873                 :   /// GetPropertyName - Return a unique constant for the given
     874                 :   /// name. The return value has type char *.
     875                 :   llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
     876                 : 
     877                 :   // FIXME: This can be dropped once string functions are unified.
     878                 :   llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
     879                 :                                         const Decl *Container);
     880                 : 
     881                 :   /// GetClassName - Return a unique constant for the given selector's
     882                 :   /// name. The return value has type char *.
     883                 :   llvm::Constant *GetClassName(IdentifierInfo *Ident);
     884                 : 
     885                 :   /// BuildIvarLayout - Builds ivar layout bitmap for the class
     886                 :   /// implementation for the __strong or __weak case.
     887                 :   ///
     888                 :   llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
     889                 :                                   bool ForStrongLayout);
     890                 : 
     891                 :   void BuildAggrIvarRecordLayout(const RecordType *RT,
     892                 :                                  unsigned int BytePos, bool ForStrongLayout,
     893                 :                                  bool &HasUnion);
     894                 :   void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
     895                 :                            const llvm::StructLayout *Layout,
     896                 :                            const RecordDecl *RD,
     897                 :                            const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
     898                 :                            unsigned int BytePos, bool ForStrongLayout,
     899                 :                            bool &HasUnion);
     900                 : 
     901                 :   /// GetIvarLayoutName - Returns a unique constant for the given
     902                 :   /// ivar layout bitmap.
     903                 :   llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
     904                 :                                     const ObjCCommonTypesHelper &ObjCTypes);
     905                 : 
     906                 :   /// EmitPropertyList - Emit the given property list. The return
     907                 :   /// value has type PropertyListPtrTy.
     908                 :   llvm::Constant *EmitPropertyList(llvm::Twine Name,
     909                 :                                    const Decl *Container,
     910                 :                                    const ObjCContainerDecl *OCD,
     911                 :                                    const ObjCCommonTypesHelper &ObjCTypes);
     912                 : 
     913                 :   /// PushProtocolProperties - Push protocol's property on the input stack.
     914                 :   void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
     915                 :                               std::vector<llvm::Constant*> &Properties,
     916                 :                                    const Decl *Container,
     917                 :                                    const ObjCProtocolDecl *PROTO,
     918                 :                                    const ObjCCommonTypesHelper &ObjCTypes);
     919                 : 
     920                 :   /// GetProtocolRef - Return a reference to the internal protocol
     921                 :   /// description, creating an empty one if it has not been
     922                 :   /// defined. The return value has type ProtocolPtrTy.
     923                 :   llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
     924                 : 
     925                 :   /// CreateMetadataVar - Create a global variable with internal
     926                 :   /// linkage for use by the Objective-C runtime.
     927                 :   ///
     928                 :   /// This is a convenience wrapper which not only creates the
     929                 :   /// variable, but also sets the section and alignment and adds the
     930                 :   /// global to the "llvm.used" list.
     931                 :   ///
     932                 :   /// \param Name - The variable name.
     933                 :   /// \param Init - The variable initializer; this is also used to
     934                 :   /// define the type of the variable.
     935                 :   /// \param Section - The section the variable should go into, or 0.
     936                 :   /// \param Align - The alignment for the variable, or 0.
     937                 :   /// \param AddToUsed - Whether the variable should be added to
     938                 :   /// "llvm.used".
     939                 :   llvm::GlobalVariable *CreateMetadataVar(llvm::Twine Name,
     940                 :                                           llvm::Constant *Init,
     941                 :                                           const char *Section,
     942                 :                                           unsigned Align,
     943                 :                                           bool AddToUsed);
     944                 : 
     945                 :   CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
     946                 :                                         QualType ResultType,
     947                 :                                         llvm::Value *Sel,
     948                 :                                         llvm::Value *Arg0,
     949                 :                                         QualType Arg0Ty,
     950                 :                                         bool IsSuper,
     951                 :                                         const CallArgList &CallArgs,
     952                 :                                         const ObjCMethodDecl *OMD,
     953                 :                                         const ObjCCommonTypesHelper &ObjCTypes);
     954                 : 
     955                 : public:
     956              130:   CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
     957              130:     CGM(cgm), VMContext(cgm.getLLVMContext()) { }
     958                 : 
     959                 :   virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
     960                 : 
     961                 :   virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
     962                 :                                          const ObjCContainerDecl *CD=0);
     963                 : 
     964                 :   virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
     965                 : 
     966                 :   /// GetOrEmitProtocol - Get the protocol object for the given
     967                 :   /// declaration, emitting it if necessary. The return value has type
     968                 :   /// ProtocolPtrTy.
     969                 :   virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
     970                 : 
     971                 :   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
     972                 :   /// object for the given declaration, emitting it if needed. These
     973                 :   /// forward references will be filled in with empty bodies if no
     974                 :   /// definition is seen. The return value has type ProtocolPtrTy.
     975                 :   virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
     976                 : };
     977                 : 
                      110: branch 2 taken
                        0: branch 3 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
     978              110: class CGObjCMac : public CGObjCCommonMac {
     979                 : private:
     980                 :   ObjCTypesHelper ObjCTypes;
     981                 :   /// EmitImageInfo - Emit the image info marker used to encode some module
     982                 :   /// level information.
     983                 :   void EmitImageInfo();
     984                 : 
     985                 :   /// EmitModuleInfo - Another marker encoding module level
     986                 :   /// information.
     987                 :   void EmitModuleInfo();
     988                 : 
     989                 :   /// EmitModuleSymols - Emit module symbols, the list of defined
     990                 :   /// classes and categories. The result has type SymtabPtrTy.
     991                 :   llvm::Constant *EmitModuleSymbols();
     992                 : 
     993                 :   /// FinishModule - Write out global data structures at the end of
     994                 :   /// processing a translation unit.
     995                 :   void FinishModule();
     996                 : 
     997                 :   /// EmitClassExtension - Generate the class extension structure used
     998                 :   /// to store the weak ivar layout and properties. The return value
     999                 :   /// has type ClassExtensionPtrTy.
    1000                 :   llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
    1001                 : 
    1002                 :   /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
    1003                 :   /// for the given class.
    1004                 :   llvm::Value *EmitClassRef(CGBuilderTy &Builder,
    1005                 :                             const ObjCInterfaceDecl *ID);
    1006                 :   
    1007                 :   /// EmitSuperClassRef - Emits reference to class's main metadata class.
    1008                 :   llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
    1009                 : 
    1010                 :   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
    1011                 :                                   QualType ResultType,
    1012                 :                                   Selector Sel,
    1013                 :                                   llvm::Value *Arg0,
    1014                 :                                   QualType Arg0Ty,
    1015                 :                                   bool IsSuper,
    1016                 :                                   const CallArgList &CallArgs);
    1017                 : 
    1018                 :   /// EmitIvarList - Emit the ivar list for the given
    1019                 :   /// implementation. If ForClass is true the list of class ivars
    1020                 :   /// (i.e. metaclass ivars) is emitted, otherwise the list of
    1021                 :   /// interface ivars will be emitted. The return value has type
    1022                 :   /// IvarListPtrTy.
    1023                 :   llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
    1024                 :                                bool ForClass);
    1025                 : 
    1026                 :   /// EmitMetaClass - Emit a forward reference to the class structure
    1027                 :   /// for the metaclass of the given interface. The return value has
    1028                 :   /// type ClassPtrTy.
    1029                 :   llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
    1030                 : 
    1031                 :   /// EmitMetaClass - Emit a class structure for the metaclass of the
    1032                 :   /// given implementation. The return value has type ClassPtrTy.
    1033                 :   llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
    1034                 :                                 llvm::Constant *Protocols,
    1035                 :                                 const ConstantVector &Methods);
    1036                 : 
    1037                 :   llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
    1038                 : 
    1039                 :   llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
    1040                 : 
    1041                 :   /// EmitMethodList - Emit the method list for the given
    1042                 :   /// implementation. The return value has type MethodListPtrTy.
    1043                 :   llvm::Constant *EmitMethodList(llvm::Twine Name,
    1044                 :                                  const char *Section,
    1045                 :                                  const ConstantVector &Methods);
    1046                 : 
    1047                 :   /// EmitMethodDescList - Emit a method description list for a list of
    1048                 :   /// method declarations.
    1049                 :   ///  - TypeName: The name for the type containing the methods.
    1050                 :   ///  - IsProtocol: True iff these methods are for a protocol.
    1051                 :   ///  - ClassMethds: True iff these are class methods.
    1052                 :   ///  - Required: When true, only "required" methods are
    1053                 :   ///    listed. Similarly, when false only "optional" methods are
    1054                 :   ///    listed. For classes this should always be true.
    1055                 :   ///  - begin, end: The method list to output.
    1056                 :   ///
    1057                 :   /// The return value has type MethodDescriptionListPtrTy.
    1058                 :   llvm::Constant *EmitMethodDescList(llvm::Twine Name,
    1059                 :                                      const char *Section,
    1060                 :                                      const ConstantVector &Methods);
    1061                 : 
    1062                 :   /// GetOrEmitProtocol - Get the protocol object for the given
    1063                 :   /// declaration, emitting it if necessary. The return value has type
    1064                 :   /// ProtocolPtrTy.
    1065                 :   virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
    1066                 : 
    1067                 :   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
    1068                 :   /// object for the given declaration, emitting it if needed. These
    1069                 :   /// forward references will be filled in with empty bodies if no
    1070                 :   /// definition is seen. The return value has type ProtocolPtrTy.
    1071                 :   virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
    1072                 : 
    1073                 :   /// EmitProtocolExtension - Generate the protocol extension
    1074                 :   /// structure used to store optional instance and class methods, and
    1075                 :   /// protocol properties. The return value has type
    1076                 :   /// ProtocolExtensionPtrTy.
    1077                 :   llvm::Constant *
    1078                 :   EmitProtocolExtension(const ObjCProtocolDecl *PD,
    1079                 :                         const ConstantVector &OptInstanceMethods,
    1080                 :                         const ConstantVector &OptClassMethods);
    1081                 : 
    1082                 :   /// EmitProtocolList - Generate the list of referenced
    1083                 :   /// protocols. The return value has type ProtocolListPtrTy.
    1084                 :   llvm::Constant *EmitProtocolList(llvm::Twine Name,
    1085                 :                                    ObjCProtocolDecl::protocol_iterator begin,
    1086                 :                                    ObjCProtocolDecl::protocol_iterator end);
    1087                 : 
    1088                 :   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
    1089                 :   /// for the given selector.
    1090                 :   llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
    1091                 : 
    1092                 : public:
    1093                 :   CGObjCMac(CodeGen::CodeGenModule &cgm);
    1094                 : 
    1095                 :   virtual llvm::Function *ModuleInitFunction();
    1096                 : 
    1097                 :   virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
    1098                 :                                               QualType ResultType,
    1099                 :                                               Selector Sel,
    1100                 :                                               llvm::Value *Receiver,
    1101                 :                                               bool IsClassMessage,
    1102                 :                                               const CallArgList &CallArgs,
    1103                 :                                               const ObjCMethodDecl *Method);
    1104                 : 
    1105                 :   virtual CodeGen::RValue
    1106                 :   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
    1107                 :                            QualType ResultType,
    1108                 :                            Selector Sel,
    1109                 :                            const ObjCInterfaceDecl *Class,
    1110                 :                            bool isCategoryImpl,
    1111                 :                            llvm::Value *Receiver,
    1112                 :                            bool IsClassMessage,
    1113                 :                            const CallArgList &CallArgs,
    1114                 :                            const ObjCMethodDecl *Method);
    1115                 : 
    1116                 :   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
    1117                 :                                 const ObjCInterfaceDecl *ID);
    1118                 : 
    1119                 :   virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
    1120                 : 
    1121                 :   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
    1122                 :   /// untyped one.
    1123                 :   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
    1124                 :                                    const ObjCMethodDecl *Method);
    1125                 : 
    1126                 :   virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
    1127                 : 
    1128                 :   virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
    1129                 : 
    1130                 :   virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
    1131                 :                                            const ObjCProtocolDecl *PD);
    1132                 : 
    1133                 :   virtual llvm::Constant *GetPropertyGetFunction();
    1134                 :   virtual llvm::Constant *GetPropertySetFunction();
    1135                 :   virtual llvm::Constant *EnumerationMutationFunction();
    1136                 : 
    1137                 :   virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
    1138                 :                                          const Stmt &S);
    1139                 :   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
    1140                 :                              const ObjCAtThrowStmt &S);
    1141                 :   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
    1142                 :                                          llvm::Value *AddrWeakObj);
    1143                 :   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
    1144                 :                                   llvm::Value *src, llvm::Value *dst);
    1145                 :   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
    1146                 :                                     llvm::Value *src, llvm::Value *dest);
    1147                 :   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
    1148                 :                                   llvm::Value *src, llvm::Value *dest,
    1149                 :                                   llvm::Value *ivarOffset);
    1150                 :   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
    1151                 :                                         llvm::Value *src, llvm::Value *dest);
    1152                 :   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
    1153                 :                                         llvm::Value *dest, llvm::Value *src,
    1154                 :                                         QualType Ty);
    1155                 : 
    1156                 :   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
    1157                 :                                       QualType ObjectTy,
    1158                 :                                       llvm::Value *BaseValue,
    1159                 :                                       const ObjCIvarDecl *Ivar,
    1160                 :                                       unsigned CVRQualifiers);
    1161                 :   virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
    1162                 :                                       const ObjCInterfaceDecl *Interface,
    1163                 :                                       const ObjCIvarDecl *Ivar);
    1164                 : };
    1165                 : 
                       19: branch 7 taken
                        0: branch 8 not taken
                        0: branch 17 not taken
                        0: branch 18 not taken
    1166               19: class CGObjCNonFragileABIMac : public CGObjCCommonMac {
    1167                 : private:
    1168                 :   ObjCNonFragileABITypesHelper ObjCTypes;
    1169                 :   llvm::GlobalVariable* ObjCEmptyCacheVar;
    1170                 :   llvm::GlobalVariable* ObjCEmptyVtableVar;
    1171                 : 
    1172                 :   /// SuperClassReferences - uniqued super class references.
    1173                 :   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
    1174                 : 
    1175                 :   /// MetaClassReferences - uniqued meta class references.
    1176                 :   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
    1177                 : 
    1178                 :   /// EHTypeReferences - uniqued class ehtype references.
    1179                 :   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
    1180                 : 
    1181                 :   /// NonLegacyDispatchMethods - List of methods for which we do *not* generate
    1182                 :   /// legacy messaging dispatch.
    1183                 :   llvm::DenseSet<Selector> NonLegacyDispatchMethods;
    1184                 : 
    1185                 :   /// DefinedMetaClasses - List of defined meta-classes.
    1186                 :   std::vector<llvm::GlobalValue*> DefinedMetaClasses;
    1187                 :   
    1188                 :   /// LegacyDispatchedSelector - Returns true if SEL is not in the list of
    1189                 :   /// NonLegacyDispatchMethods; false otherwise.
    1190                 :   bool LegacyDispatchedSelector(Selector Sel);
    1191                 : 
    1192                 :   /// FinishNonFragileABIModule - Write out global data structures at the end of
    1193                 :   /// processing a translation unit.
    1194                 :   void FinishNonFragileABIModule();
    1195                 : 
    1196                 :   /// AddModuleClassList - Add the given list of class pointers to the
    1197                 :   /// module with the provided symbol and section names.
    1198                 :   void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container,
    1199                 :                           const char *SymbolName,
    1200                 :                           const char *SectionName);
    1201                 : 
    1202                 :   llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
    1203                 :                                               unsigned InstanceStart,
    1204                 :                                               unsigned InstanceSize,
    1205                 :                                               const ObjCImplementationDecl *ID);
    1206                 :   llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
    1207                 :                                             llvm::Constant *IsAGV,
    1208                 :                                             llvm::Constant *SuperClassGV,
    1209                 :                                             llvm::Constant *ClassRoGV,
    1210                 :                                             bool HiddenVisibility);
    1211                 : 
    1212                 :   llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
    1213                 : 
    1214                 :   llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
    1215                 : 
    1216                 :   /// EmitMethodList - Emit the method list for the given
    1217                 :   /// implementation. The return value has type MethodListnfABITy.
    1218                 :   llvm::Constant *EmitMethodList(llvm::Twine Name,
    1219                 :                                  const char *Section,
    1220                 :                                  const ConstantVector &Methods);
    1221                 :   /// EmitIvarList - Emit the ivar list for the given
    1222                 :   /// implementation. If ForClass is true the list of class ivars
    1223                 :   /// (i.e. metaclass ivars) is emitted, otherwise the list of
    1224                 :   /// interface ivars will be emitted. The return value has type
    1225                 :   /// IvarListnfABIPtrTy.
    1226                 :   llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
    1227                 : 
    1228                 :   llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
    1229                 :                                     const ObjCIvarDecl *Ivar,
    1230                 :                                     unsigned long int offset);
    1231                 : 
    1232                 :   /// GetOrEmitProtocol - Get the protocol object for the given
    1233                 :   /// declaration, emitting it if necessary. The return value has type
    1234                 :   /// ProtocolPtrTy.
    1235                 :   virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
    1236                 : 
    1237                 :   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
    1238                 :   /// object for the given declaration, emitting it if needed. These
    1239                 :   /// forward references will be filled in with empty bodies if no
    1240                 :   /// definition is seen. The return value has type ProtocolPtrTy.
    1241                 :   virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
    1242                 : 
    1243                 :   /// EmitProtocolList - Generate the list of referenced
    1244                 :   /// protocols. The return value has type ProtocolListPtrTy.
    1245                 :   llvm::Constant *EmitProtocolList(llvm::Twine Name,
    1246                 :                                    ObjCProtocolDecl::protocol_iterator begin,
    1247                 :                                    ObjCProtocolDecl::protocol_iterator end);
    1248                 : 
    1249                 :   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
    1250                 :                                   QualType ResultType,
    1251                 :                                   Selector Sel,
    1252                 :                                   llvm::Value *Receiver,
    1253                 :                                   QualType Arg0Ty,
    1254                 :                                   bool IsSuper,
    1255                 :                                   const CallArgList &CallArgs);
    1256                 : 
    1257                 :   /// GetClassGlobal - Return the global variable for the Objective-C
    1258                 :   /// class of the given name.
    1259                 :   llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
    1260                 : 
    1261                 :   /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
    1262                 :   /// for the given class reference.
    1263                 :   llvm::Value *EmitClassRef(CGBuilderTy &Builder,
    1264                 :                             const ObjCInterfaceDecl *ID);
    1265                 : 
    1266                 :   /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
    1267                 :   /// for the given super class reference.
    1268                 :   llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
    1269                 :                                  const ObjCInterfaceDecl *ID);
    1270                 : 
    1271                 :   /// EmitMetaClassRef - Return a Value * of the address of _class_t
    1272                 :   /// meta-data
    1273                 :   llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
    1274                 :                                 const ObjCInterfaceDecl *ID);
    1275                 : 
    1276                 :   /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
    1277                 :   /// the given ivar.
    1278                 :   ///
    1279                 :   llvm::GlobalVariable * ObjCIvarOffsetVariable(
    1280                 :     const ObjCInterfaceDecl *ID,
    1281                 :     const ObjCIvarDecl *Ivar);
    1282                 : 
    1283                 :   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
    1284                 :   /// for the given selector.
    1285                 :   llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
    1286                 : 
    1287                 :   /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
    1288                 :   /// interface. The return value has type EHTypePtrTy.
    1289                 :   llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
    1290                 :                                   bool ForDefinition);
    1291                 : 
    1292               43:   const char *getMetaclassSymbolPrefix() const {
    1293               43:     return "OBJC_METACLASS_$_";
    1294                 :   }
    1295                 : 
    1296               63:   const char *getClassSymbolPrefix() const {
    1297               63:     return "OBJC_CLASS_$_";
    1298                 :   }
    1299                 : 
    1300                 :   void GetClassSizeInfo(const ObjCImplementationDecl *OID,
    1301                 :                         uint32_t &InstanceStart,
    1302                 :                         uint32_t &InstanceSize);
    1303                 : 
    1304                 :   // Shamelessly stolen from Analysis/CFRefCount.cpp
    1305              100:   Selector GetNullarySelector(const char* name) const {
    1306              100:     IdentifierInfo* II = &CGM.getContext().Idents.get(name);
    1307              100:     return CGM.getContext().Selectors.getSelector(0, &II);
    1308                 :   }
    1309                 : 
    1310               40:   Selector GetUnarySelector(const char* name) const {
    1311               40:     IdentifierInfo* II = &CGM.getContext().Idents.get(name);
    1312               40:     return CGM.getContext().Selectors.getSelector(1, &II);
    1313                 :   }
    1314                 : 
    1315                 :   /// ImplementationIsNonLazy - Check whether the given category or
    1316                 :   /// class implementation is "non-lazy".
    1317                 :   bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
    1318                 : 
    1319                 : public:
    1320                 :   CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
    1321                 :   // FIXME. All stubs for now!
    1322                 :   virtual llvm::Function *ModuleInitFunction();
    1323                 : 
    1324                 :   virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
    1325                 :                                               QualType ResultType,
    1326                 :                                               Selector Sel,
    1327                 :                                               llvm::Value *Receiver,
    1328                 :                                               bool IsClassMessage,
    1329                 :                                               const CallArgList &CallArgs,
    1330                 :                                               const ObjCMethodDecl *Method);
    1331                 : 
    1332                 :   virtual CodeGen::RValue
    1333                 :   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
    1334                 :                            QualType ResultType,
    1335                 :                            Selector Sel,
    1336                 :                            const ObjCInterfaceDecl *Class,
    1337                 :                            bool isCategoryImpl,
    1338                 :                            llvm::Value *Receiver,
    1339                 :                            bool IsClassMessage,
    1340                 :                            const CallArgList &CallArgs,
    1341                 :                            const ObjCMethodDecl *Method);
    1342                 : 
    1343                 :   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
    1344                 :                                 const ObjCInterfaceDecl *ID);
    1345                 : 
    1346                0:   virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel)
    1347                0:     { return EmitSelector(Builder, Sel); }
    1348                 : 
    1349                 :   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
    1350                 :   /// untyped one.
    1351                 :   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
    1352                0:                                    const ObjCMethodDecl *Method)
    1353                0:     { return EmitSelector(Builder, Method->getSelector()); }
    1354                 : 
    1355                 :   virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
    1356                 : 
    1357                 :   virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
    1358                 :   virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
    1359                 :                                            const ObjCProtocolDecl *PD);
    1360                 : 
    1361                2:   virtual llvm::Constant *GetPropertyGetFunction() {
    1362                2:     return ObjCTypes.getGetPropertyFn();
    1363                 :   }
    1364                2:   virtual llvm::Constant *GetPropertySetFunction() {
    1365                2:     return ObjCTypes.getSetPropertyFn();
    1366                 :   }
    1367                0:   virtual llvm::Constant *EnumerationMutationFunction() {
    1368                0:     return ObjCTypes.getEnumerationMutationFn();
    1369                 :   }
    1370                 : 
    1371                 :   virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
    1372                 :                                          const Stmt &S);
    1373                 :   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
    1374                 :                              const ObjCAtThrowStmt &S);
    1375                 :   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
    1376                 :                                          llvm::Value *AddrWeakObj);
    1377                 :   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
    1378                 :                                   llvm::Value *src, llvm::Value *dst);
    1379                 :   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
    1380                 :                                     llvm::Value *src, llvm::Value *dest);
    1381                 :   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
    1382                 :                                   llvm::Value *src, llvm::Value *dest,
    1383                 :                                   llvm::Value *ivarOffset);
    1384                 :   virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
    1385                 :                                         llvm::Value *src, llvm::Value *dest);
    1386                 :   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
    1387                 :                                         llvm::Value *dest, llvm::Value *src,
    1388                 :                                         QualType Ty);
    1389                 :   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
    1390                 :                                       QualType ObjectTy,
    1391                 :                                       llvm::Value *BaseValue,
    1392                 :                                       const ObjCIvarDecl *Ivar,
    1393                 :                                       unsigned CVRQualifiers);
    1394                 :   virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
    1395                 :                                       const ObjCInterfaceDecl *Interface,
    1396                 :                                       const ObjCIvarDecl *Ivar);
    1397                 : };
    1398                 : 
    1399                 : } // end anonymous namespace
    1400                 : 
    1401                 : /* *** Helper Functions *** */
    1402                 : 
    1403                 : /// getConstantGEP() - Help routine to construct simple GEPs.
    1404                 : static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
    1405                 :                                       llvm::Constant *C,
    1406                 :                                       unsigned idx0,
    1407             2139:                                       unsigned idx1) {
    1408                 :   llvm::Value *Idxs[] = {
    1409                 :     llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
    1410                 :     llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
    1411             2139:   };
    1412             2139:   return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
    1413                 : }
    1414                 : 
    1415                 : /// hasObjCExceptionAttribute - Return true if this class or any super
    1416                 : /// class has the __objc_exception__ attribute.
    1417                 : static bool hasObjCExceptionAttribute(ASTContext &Context,
    1418               73:                                       const ObjCInterfaceDecl *OID) {
                        6: branch 1 taken
                       67: branch 2 taken
    1419               73:   if (OID->hasAttr<ObjCExceptionAttr>())
    1420                6:     return true;
                       25: branch 1 taken
                       42: branch 2 taken
    1421               67:   if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
    1422               25:     return hasObjCExceptionAttribute(Context, Super);
    1423               42:   return false;
    1424                 : }
    1425                 : 
    1426                 : /* *** CGObjCMac Public Interface *** */
    1427                 : 
    1428              110: CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
    1429              110:                                                     ObjCTypes(cgm) {
    1430              110:   ObjCABI = 1;
    1431              110:   EmitImageInfo();
    1432              110: }
    1433                 : 
    1434                 : /// GetClass - Return a reference to the class for the given interface
    1435                 : /// decl.
    1436                 : llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
    1437               36:                                  const ObjCInterfaceDecl *ID) {
    1438               36:   return EmitClassRef(Builder, ID);
    1439                 : }
    1440                 : 
    1441                 : /// GetSelector - Return the pointer to the unique'd string for this selector.
    1442                1: llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) {
    1443                1:   return EmitSelector(Builder, Sel);
    1444                 : }
    1445                 : llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
    1446                0:                                     *Method) {
    1447                0:   return EmitSelector(Builder, Method->getSelector());
    1448                 : }
    1449                 : 
    1450                 : /// Generate a constant CFString object.
    1451                 : /*
    1452                 :   struct __builtin_CFString {
    1453                 :   const int *isa; // point to __CFConstantStringClassReference
    1454                 :   int flags;
    1455                 :   const char *str;
    1456                 :   long length;
    1457                 :   };
    1458                 : */
    1459                 : 
    1460                 : llvm::Constant *CGObjCCommonMac::GenerateConstantString(
    1461               68:   const StringLiteral *SL) {
    1462               68:   return CGM.GetAddrOfConstantCFString(SL);
    1463                 : }
    1464                 : 
    1465                 : /// Generates a message send where the super is the receiver.  This is
    1466                 : /// a message send to self with special delivery semantics indicating
    1467                 : /// which class's method should be called.
    1468                 : CodeGen::RValue
    1469                 : CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
    1470                 :                                     QualType ResultType,
    1471                 :                                     Selector Sel,
    1472                 :                                     const ObjCInterfaceDecl *Class,
    1473                 :                                     bool isCategoryImpl,
    1474                 :                                     llvm::Value *Receiver,
    1475                 :                                     bool IsClassMessage,
    1476                 :                                     const CodeGen::CallArgList &CallArgs,
    1477               33:                                     const ObjCMethodDecl *Method) {
    1478                 :   // Create and init a super structure; this is a (receiver, class)
    1479                 :   // pair we will pass to objc_msgSendSuper.
    1480                 :   llvm::Value *ObjCSuper =
    1481               33:     CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
    1482                 :   llvm::Value *ReceiverAsObject =
    1483               33:     CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
    1484                 :   CGF.Builder.CreateStore(ReceiverAsObject,
    1485               33:                           CGF.Builder.CreateStructGEP(ObjCSuper, 0));
    1486                 : 
    1487                 :   // If this is a class message the metaclass is passed as the target.
    1488                 :   llvm::Value *Target;
                       12: branch 0 taken
                       21: branch 1 taken
    1489               33:   if (IsClassMessage) {
                        2: branch 0 taken
                       10: branch 1 taken
    1490               12:     if (isCategoryImpl) {
    1491                 :       // Message sent to 'super' in a class method defined in a category
    1492                 :       // implementation requires an odd treatment.
    1493                 :       // If we are in a class method, we must retrieve the
    1494                 :       // _metaclass_ for the current class, pointed at by
    1495                 :       // the class's "isa" pointer.  The following assumes that
    1496                 :       // isa" is the first ivar in a class (which it must be).
    1497                2:       Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
    1498                2:       Target = CGF.Builder.CreateStructGEP(Target, 0);
    1499                2:       Target = CGF.Builder.CreateLoad(Target);
    1500                 :     } else {
    1501               10:       llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
    1502               10:       llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
    1503               10:       llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
    1504               10:       Target = Super;
    1505                 :     }
    1506                 :   } 
                        0: branch 0 not taken
                       21: branch 1 taken
    1507               21:   else if (isCategoryImpl)
    1508                0:     Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
    1509                 :   else {
    1510               21:     llvm::Value *ClassPtr = EmitSuperClassRef(Class);
    1511               21:     ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
    1512               21:     Target = CGF.Builder.CreateLoad(ClassPtr);
    1513                 :   }
    1514                 :   // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
    1515                 :   // ObjCTypes types.
    1516                 :   const llvm::Type *ClassTy =
    1517               33:     CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
    1518               33:   Target = CGF.Builder.CreateBitCast(Target, ClassTy);
    1519                 :   CGF.Builder.CreateStore(Target,
    1520               33:                           CGF.Builder.CreateStructGEP(ObjCSuper, 1));
    1521                 :   return EmitLegacyMessageSend(CGF, ResultType,
    1522                 :                                EmitSelector(CGF.Builder, Sel),
    1523                 :                                ObjCSuper, ObjCTypes.SuperPtrCTy,
    1524               33:                                true, CallArgs, Method, ObjCTypes);
    1525                 : }
    1526                 : 
    1527                 : /// Generate code for a message send expression.
    1528                 : CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
    1529                 :                                                QualType ResultType,
    1530                 :                                                Selector Sel,
    1531                 :                                                llvm::Value *Receiver,
    1532                 :                                                bool IsClassMessage,
    1533                 :                                                const CallArgList &CallArgs,
    1534              166:                                                const ObjCMethodDecl *Method) {
    1535                 :   return EmitLegacyMessageSend(CGF, ResultType,
    1536                 :                                EmitSelector(CGF.Builder, Sel),
    1537                 :                                Receiver, CGF.getContext().getObjCIdType(),
    1538              166:                                false, CallArgs, Method, ObjCTypes);
    1539                 : }
    1540                 : 
    1541                 : CodeGen::RValue
    1542                 : CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
    1543                 :                                        QualType ResultType,
    1544                 :                                        llvm::Value *Sel,
    1545                 :                                        llvm::Value *Arg0,
    1546                 :                                        QualType Arg0Ty,
    1547                 :                                        bool IsSuper,
    1548                 :                                        const CallArgList &CallArgs,
    1549                 :                                        const ObjCMethodDecl *Method,
    1550              217:                                        const ObjCCommonTypesHelper &ObjCTypes) {
    1551              217:   CallArgList ActualArgs;
                      182: branch 0 taken
                       35: branch 1 taken
    1552              217:   if (!IsSuper)
    1553              182:     Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp");
    1554              217:   ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
    1555                 :   ActualArgs.push_back(std::make_pair(RValue::get(Sel),
    1556              217:                                       CGF.getContext().getObjCSelType()));
    1557              217:   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
    1558                 : 
    1559              217:   CodeGenTypes &Types = CGM.getTypes();
    1560                 :   const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
    1561              217:                                                        CC_Default, false);
    1562                 :   const llvm::FunctionType *FTy =
                      109: branch 0 taken
                      108: branch 1 taken
    1563              217:     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
    1564                 : 
    1565              217:   llvm::Constant *Fn = NULL;
                       10: branch 1 taken
                      207: branch 2 taken
    1566              217:   if (CGM.ReturnTypeUsesSret(FnInfo)) {
    1567                 :     Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
                        0: branch 0 not taken
                       10: branch 1 taken
    1568               10:       : ObjCTypes.getSendStretFn(IsSuper);
                       15: branch 2 taken
                      192: branch 3 taken
    1569              207:   } else if (ResultType->isFloatingType()) {
                        3: branch 0 taken
                       12: branch 1 taken
    1570               15:     if (ObjCABI == 2) {
                        3: branch 2 taken
                        0: branch 3 not taken
    1571                3:       if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
    1572                3:         BuiltinType::Kind k = BT->getKind();
    1573                 :         Fn = (k == BuiltinType::LongDouble) ? ObjCTypes.getSendFpretFn2(IsSuper)
                        1: branch 0 taken
                        2: branch 1 taken
    1574                3:           : ObjCTypes.getSendFn2(IsSuper);
    1575                 :       } else {
    1576                0:         Fn = ObjCTypes.getSendFn2(IsSuper);
    1577                 :       }
    1578                 :     } else
    1579                 :       // FIXME. This currently matches gcc's API for x86-32. May need to change
    1580                 :       // for others if we have their API.
    1581               12:       Fn = ObjCTypes.getSendFpretFn(IsSuper);
    1582                 :   } else {
    1583                 :     Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
                       15: branch 0 taken
                      177: branch 1 taken
    1584              192:       : ObjCTypes.getSendFn(IsSuper);
    1585                 :   }
                        0: branch 0 not taken
                      217: branch 1 taken
    1586              217:   assert(Fn && "EmitLegacyMessageSend - unknown API");
    1587                 :   Fn = llvm::ConstantExpr::getBitCast(Fn,
    1588              217:                                       llvm::PointerType::getUnqual(FTy));
    1589              217:   return CGF.EmitCall(FnInfo, Fn, ReturnValueSlot(), ActualArgs);
    1590                 : }
    1591                 : 
    1592                 : llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
    1593               11:                                             const ObjCProtocolDecl *PD) {
    1594                 :   // FIXME: I don't understand why gcc generates this, or where it is
    1595                 :   // resolved. Investigate. Its also wasteful to look this up over and over.
    1596               11:   LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
    1597                 : 
    1598                 :   return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
    1599               11:                                         ObjCTypes.ExternalProtocolPtrTy);
    1600                 : }
    1601                 : 
    1602               31: void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
    1603                 :   // FIXME: We shouldn't need this, the protocol decl should contain enough
    1604                 :   // information to tell us whether this was a declaration or a definition.
    1605               31:   DefinedProtocols.insert(PD->getIdentifier());
    1606                 : 
    1607                 :   // If we have generated a forward reference to this protocol, emit
    1608                 :   // it now. Otherwise do nothing, the protocol objects are lazily
    1609                 :   // emitted.
                        1: branch 2 taken
                       30: branch 3 taken
    1610               31:   if (Protocols.count(PD->getIdentifier()))
    1611                1:     GetOrEmitProtocol(PD);
    1612               31: }
    1613                 : 
    1614               32: llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
                       27: branch 2 taken
                        5: branch 3 taken
    1615               32:   if (DefinedProtocols.count(PD->getIdentifier()))
    1616               27:     return GetOrEmitProtocol(PD);
    1617                5:   return GetOrEmitProtocolRef(PD);
    1618                 : }
    1619                 : 
    1620                 : /*
    1621                 : // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
    1622                 : struct _objc_protocol {
    1623                 : struct _objc_protocol_extension *isa;
    1624                 : char *protocol_name;
    1625                 : struct _objc_protocol_list *protocol_list;
    1626                 : struct _objc__method_prototype_list *instance_methods;
    1627                 : struct _objc__method_prototype_list *class_methods
    1628                 : };
    1629                 : 
    1630                 : See EmitProtocolExtension().
    1631                 : */
    1632               19: llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
    1633               19:   llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
    1634                 : 
    1635                 :   // Early exit if a defining object has already been generated.
                        5: branch 0 taken
                       14: branch 1 taken
                        4: branch 3 taken
                        1: branch 4 taken
                        4: branch 5 taken
                       15: branch 6 taken
    1636               19:   if (Entry && Entry->hasInitializer())
    1637                4:     return Entry;
    1638                 : 
    1639                 :   // FIXME: I don't understand why gcc generates this, or where it is
    1640                 :   // resolved. Investigate. Its also wasteful to look this up over and over.
    1641               15:   LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
    1642                 : 
    1643                 :   // Construct method lists.
    1644               15:   std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
    1645               15:   std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
                       20: branch 2 taken
                       15: branch 3 taken
    1646               35:   for (ObjCProtocolDecl::instmeth_iterator
    1647               15:          i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
    1648               20:     ObjCMethodDecl *MD = *i;
    1649               20:     llvm::Constant *C = GetMethodDescriptionConstant(MD);
                        1: branch 1 taken
                       19: branch 2 taken
    1650               20:     if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
    1651                1:       OptInstanceMethods.push_back(C);
    1652                 :     } else {
    1653               19:       InstanceMethods.push_back(C);
    1654                 :     }
    1655                 :   }
    1656                 : 
                        4: branch 2 taken
                       15: branch 3 taken
    1657               19:   for (ObjCProtocolDecl::classmeth_iterator
    1658               15:          i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
    1659                4:     ObjCMethodDecl *MD = *i;
    1660                4:     llvm::Constant *C = GetMethodDescriptionConstant(MD);
                        1: branch 1 taken
                        3: branch 2 taken
    1661                4:     if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
    1662                1:       OptClassMethods.push_back(C);
    1663                 :     } else {
    1664                3:       ClassMethods.push_back(C);
    1665                 :     }
    1666                 :   }
    1667                 : 
    1668               15:   std::vector<llvm::Constant*> Values(5);
    1669               15:   Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
    1670               15:   Values[1] = GetClassName(PD->getIdentifier());
    1671                 :   Values[2] =
    1672                 :     EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
    1673                 :                      PD->protocol_begin(),
    1674               15:                      PD->protocol_end());
    1675                 :   Values[3] =
    1676                 :     EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
    1677                 :                        "__OBJC,__cat_inst_meth,regular,no_dead_strip",
    1678               15:                        InstanceMethods);
    1679                 :   Values[4] =
    1680                 :     EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
    1681                 :                        "__OBJC,__cat_cls_meth,regular,no_dead_strip",
    1682               15:                        ClassMethods);
    1683                 :   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
    1684               15:                                                    Values);
    1685                 : 
                        1: branch 0 taken
                       14: branch 1 taken
    1686               15:   if (Entry) {
    1687                 :     // Already created, fix the linkage and update the initializer.
    1688                1:     Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
    1689                1:     Entry->setInitializer(Init);
    1690                 :   } else {
    1691                 :     Entry =
    1692                 :       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
    1693                 :                                llvm::GlobalValue::InternalLinkage,
    1694                 :                                Init,
    1695               14:                                "\01L_OBJC_PROTOCOL_" + PD->getName());
    1696               14:     Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
    1697               14:     Entry->setAlignment(4);
    1698                 :     // FIXME: Is this necessary? Why only for protocol?
    1699               14:     Entry->setAlignment(4);
    1700                 :   }
    1701               15:   CGM.AddUsedGlobal(Entry);
    1702                 : 
    1703               15:   return Entry;
    1704                 : }
    1705                 : 
    1706                5: llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
    1707                5:   llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
    1708                 : 
                        5: branch 0 taken
                        0: branch 1 not taken
    1709                5:   if (!Entry) {
    1710                 :     // We use the initializer as a marker of whether this is a forward
    1711                 :     // reference or not. At module finalization we add the empty
    1712                 :     // contents for protocols which were referenced but never defined.
    1713                 :     Entry =
    1714                 :       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
    1715                 :                                llvm::GlobalValue::ExternalLinkage,
    1716                 :                                0,
    1717                5:                                "\01L_OBJC_PROTOCOL_" + PD->getName());
    1718                5:     Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
    1719                5:     Entry->setAlignment(4);
    1720                 :     // FIXME: Is this necessary? Why only for protocol?
    1721                5:     Entry->setAlignment(4);
    1722                 :   }
    1723                 : 
    1724                5:   return Entry;
    1725                 : }
    1726                 : 
    1727                 : /*
    1728                 :   struct _objc_protocol_extension {
    1729                 :   uint32_t size;
    1730                 :   struct objc_method_description_list *optional_instance_methods;
    1731                 :   struct objc_method_description_list *optional_class_methods;
    1732                 :   struct objc_property_list *instance_properties;
    1733                 :   };
    1734                 : */
    1735                 : llvm::Constant *
    1736                 : CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
    1737                 :                                  const ConstantVector &OptInstanceMethods,
    1738               15:                                  const ConstantVector &OptClassMethods) {
    1739                 :   uint64_t Size =
    1740               15:     CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
    1741               15:   std::vector<llvm::Constant*> Values(4);
    1742               15:   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
    1743                 :   Values[1] =
    1744                 :     EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
    1745                 :                        + PD->getName(),
    1746                 :                        "__OBJC,__cat_inst_meth,regular,no_dead_strip",
    1747               15:                        OptInstanceMethods);
    1748                 :   Values[2] =
    1749                 :     EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
    1750                 :                        "__OBJC,__cat_cls_meth,regular,no_dead_strip",
    1751               15:                        OptClassMethods);
    1752                 :   Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(),
    1753               15:                                0, PD, ObjCTypes);
    1754                 : 
    1755                 :   // Return null if no extension bits are used.
                       14: branch 2 taken
                        1: branch 3 taken
                       14: branch 6 taken
                        0: branch 7 not taken
                       13: branch 10 taken
                        1: branch 11 taken
                       13: branch 12 taken
                        2: branch 13 taken
    1756               15:   if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
    1757                 :       Values[3]->isNullValue())
    1758               13:     return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
    1759                 : 
    1760                 :   llvm::Constant *Init =
    1761                2:     llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
    1762                 : 
    1763                 :   // No special section, but goes in llvm.used
    1764                 :   return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
    1765                 :                            Init,
    1766                2:                            0, 0, true);
    1767                 : }
    1768                 : 
    1769                 : /*
    1770                 :   struct objc_protocol_list {
    1771                 :   struct objc_protocol_list *next;
    1772                 :   long count;
    1773                 :   Protocol *list[];
    1774                 :   };
    1775                 : */
    1776                 : llvm::Constant *
    1777                 : CGObjCMac::EmitProtocolList(llvm::Twine Name,
    1778                 :                             ObjCProtocolDecl::protocol_iterator begin,
    1779              140:                             ObjCProtocolDecl::protocol_iterator end) {
    1780              140:   std::vector<llvm::Constant*> ProtocolRefs;
    1781                 : 
                       12: branch 0 taken
                      140: branch 1 taken
    1782              152:   for (; begin != end; ++begin)
    1783               12:     ProtocolRefs.push_back(GetProtocolRef(*begin));
    1784                 : 
    1785                 :   // Just return null for empty protocol lists
                      130: branch 1 taken
                       10: branch 2 taken
    1786              140:   if (ProtocolRefs.empty())
    1787              130:     return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
    1788                 : 
    1789                 :   // This list is null terminated.
    1790               10:   ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
    1791                 : 
    1792               10:   std::vector<llvm::Constant*> Values(3);
    1793                 :   // This field is only used by the runtime.
    1794               10:   Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
    1795                 :   Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
    1796               10:                                      ProtocolRefs.size() - 1);
    1797                 :   Values[2] =
    1798                 :     llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
    1799                 :                                                   ProtocolRefs.size()),
    1800               10:                              ProtocolRefs);
    1801                 : 
    1802               10:   llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
    1803                 :   llvm::GlobalVariable *GV =
    1804                 :     CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
    1805               10:                       4, false);
    1806               10:   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
    1807                 : }
    1808                 : 
    1809                 : void CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
    1810                 :                                    std::vector<llvm::Constant*> &Properties,
    1811                 :                                    const Decl *Container,
    1812                 :                                    const ObjCProtocolDecl *PROTO,
    1813               19:                                    const ObjCCommonTypesHelper &ObjCTypes) {
    1814               19:   std::vector<llvm::Constant*> Prop(2);
                        2: branch 1 taken
                       19: branch 2 taken
    1815               40:   for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
    1816               19:          E = PROTO->protocol_end(); P != E; ++P) 
    1817                2:     PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
                       10: branch 3 taken
                       19: branch 4 taken
    1818               48:   for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
    1819               19:        E = PROTO->prop_end(); I != E; ++I) {
    1820               10:     const ObjCPropertyDecl *PD = *I;
                        1: branch 2 taken
                        9: branch 3 taken
    1821               10:     if (!PropertySet.insert(PD->getIdentifier()))
    1822                1:       continue;
    1823                9:     Prop[0] = GetPropertyName(PD->getIdentifier());
    1824                9:     Prop[1] = GetPropertyTypeString(PD, Container);
    1825                9:     Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
    1826               19:   }
    1827               19: }
    1828                 : 
    1829                 : /*
    1830                 :   struct _objc_property {
    1831                 :   const char * const name;
    1832                 :   const char * const attributes;
    1833                 :   };
    1834                 : 
    1835                 :   struct _objc_property_list {
    1836                 :   uint32_t entsize; // sizeof (struct _objc_property)
    1837                 :   uint32_t prop_count;
    1838                 :   struct _objc_property[prop_count];
    1839                 :   };
    1840                 : */
    1841                 : llvm::Constant *CGObjCCommonMac::EmitPropertyList(llvm::Twine Name,
    1842                 :                                        const Decl *Container,
    1843                 :                                        const ObjCContainerDecl *OCD,
    1844              200:                                        const ObjCCommonTypesHelper &ObjCTypes) {
    1845              200:   std::vector<llvm::Constant*> Properties, Prop(2);
    1846              200:   llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
                       85: branch 3 taken
                      200: branch 4 taken
    1847              485:   for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
    1848              200:          E = OCD->prop_end(); I != E; ++I) {
    1849               85:     const ObjCPropertyDecl *PD = *I;
    1850               85:     PropertySet.insert(PD->getIdentifier());
    1851               85:     Prop[0] = GetPropertyName(PD->getIdentifier());
    1852               85:     Prop[1] = GetPropertyTypeString(PD, Container);
    1853                 :     Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
    1854               85:                                                    Prop));
    1855                 :   }
                      155: branch 1 taken
                       45: branch 2 taken
    1856              200:   if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
                       17: branch 1 taken
                      155: branch 2 taken
    1857              327:     for (ObjCInterfaceDecl::protocol_iterator P = OID->protocol_begin(),
    1858              155:          E = OID->protocol_end(); P != E; ++P)
    1859               17:       PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
    1860                 : 
    1861                 :   // Return null for empty list.
                      155: branch 1 taken
                       45: branch 2 taken
    1862              200:   if (Properties.empty())
    1863              155:     return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
    1864                 : 
    1865                 :   unsigned PropertySize =
    1866               45:     CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy);
    1867               45:   std::vector<llvm::Constant*> Values(3);
    1868               45:   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
    1869               45:   Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
    1870                 :   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
    1871               45:                                              Properties.size());
    1872               45:   Values[2] = llvm::ConstantArray::get(AT, Properties);
    1873               45:   llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
    1874                 : 
    1875                 :   llvm::GlobalVariable *GV =
    1876                 :     CreateMetadataVar(Name, Init,
    1877                 :                       (ObjCABI == 2) ? "__DATA, __objc_const" :
    1878                 :                       "__OBJC,__property,regular,no_dead_strip",
    1879                 :                       (ObjCABI == 2) ? 8 : 4,
                       21: branch 0 taken
                       24: branch 1 taken
                       21: branch 2 taken
                       24: branch 3 taken
    1880               45:                       true);
    1881               45:   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
    1882                 : }
    1883                 : 
    1884                 : /*
    1885                 :   struct objc_method_description_list {
    1886                 :   int count;
    1887                 :   struct objc_method_description list[];
    1888                 :   };
    1889                 : */
    1890                 : llvm::Constant *
    1891               24: CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
    1892               24:   std::vector<llvm::Constant*> Desc(2);
    1893                 :   Desc[0] =
    1894                 :     llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
    1895               24:                                    ObjCTypes.SelectorPtrTy);
    1896               24:   Desc[1] = GetMethodVarType(MD);
    1897                 :   return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
    1898               24:                                    Desc);
    1899                 : }
    1900                 : 
    1901                 : llvm::Constant *CGObjCMac::EmitMethodDescList(llvm::Twine Name,
    1902                 :                                               const char *Section,
    1903               60:                                               const ConstantVector &Methods) {
    1904                 :   // Return null for empty list.
                       46: branch 1 taken
                       14: branch 2 taken
    1905               60:   if (Methods.empty())
    1906               46:     return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
    1907                 : 
    1908               14:   std::vector<llvm::Constant*> Values(2);
    1909               14:   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
    1910                 :   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
    1911               14:                                              Methods.size());
    1912               14:   Values[1] = llvm::ConstantArray::get(AT, Methods);
    1913               14:   llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
    1914                 : 
    1915               14:   llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
    1916                 :   return llvm::ConstantExpr::getBitCast(GV,
    1917               14:                                         ObjCTypes.MethodDescriptionListPtrTy);
    1918                 : }
    1919                 : 
    1920                 : /*
    1921                 :   struct _objc_category {
    1922                 :   char *category_name;
    1923                 :   char *class_name;
    1924                 :   struct _objc_method_list *instance_methods;
    1925                 :   struct _objc_method_list *class_methods;
    1926                 :   struct _objc_protocol_list *protocols;
    1927                 :   uint32_t size; // <rdar://4585769>
    1928                 :   struct _objc_property_list *instance_properties;
    1929                 :   };
    1930                 : */
    1931               12: void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
    1932               12:   unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy);
    1933                 : 
    1934                 :   // FIXME: This is poor design, the OCD should have a pointer to the category
    1935                 :   // decl. Additionally, note that Category can be null for the @implementation
    1936                 :   // w/o an @interface case. Sema should just create one for us as it does for
    1937                 :   // @implementation so everyone else can live life under a clear blue sky.
    1938               12:   const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
    1939                 :   const ObjCCategoryDecl *Category =
    1940               12:     Interface->FindCategoryDeclaration(OCD->getIdentifier());
    1941                 : 
    1942               12:   llvm::SmallString<256> ExtName;
    1943                 :   llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
    1944               12:                                      << OCD->getName();
    1945                 : 
    1946               12:   std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
                        4: branch 2 taken
                       12: branch 3 taken
    1947               16:   for (ObjCCategoryImplDecl::instmeth_iterator
    1948               12:          i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
    1949                 :     // Instance methods should always be defined.
    1950                4:     InstanceMethods.push_back(GetMethodConstant(*i));
    1951                 :   }
                        4: branch 2 taken
                       12: branch 3 taken
    1952               16:   for (ObjCCategoryImplDecl::classmeth_iterator
    1953               12:          i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
    1954                 :     // Class methods should always be defined.
    1955                4:     ClassMethods.push_back(GetMethodConstant(*i));
    1956                 :   }
    1957                 : 
    1958               12:   std::vector<llvm::Constant*> Values(7);
    1959               12:   Values[0] = GetClassName(OCD->getIdentifier());
    1960               12:   Values[1] = GetClassName(Interface->getIdentifier());
    1961               12:   LazySymbols.insert(Interface->getIdentifier());
    1962                 :   Values[2] =
    1963                 :     EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
    1964                 :                    "__OBJC,__cat_inst_meth,regular,no_dead_strip",
    1965               12:                    InstanceMethods);
    1966                 :   Values[3] =
    1967                 :     EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
    1968                 :                    "__OBJC,__cat_cls_meth,regular,no_dead_strip",
    1969               12:                    ClassMethods);
                       12: branch 0 taken
                        0: branch 1 not taken
    1970               12:   if (Category) {
    1971                 :     Values[4] =
    1972                 :       EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
    1973                 :                        Category->protocol_begin(),
    1974               12:                        Category->protocol_end());
    1975                 :   } else {
    1976                0:     Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
    1977                 :   }
    1978               12:   Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
    1979                 : 
    1980                 :   // If there is no category @interface then there can be no properties.
                       12: branch 0 taken
                        0: branch 1 not taken
    1981               12:   if (Category) {
    1982                 :     Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
    1983               12:                                  OCD, Category, ObjCTypes);
    1984                 :   } else {
    1985                0:     Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
    1986                 :   }
    1987                 : 
    1988                 :   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
    1989               12:                                                    Values);
    1990                 : 
    1991                 :   llvm::GlobalVariable *GV =
    1992                 :     CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
    1993                 :                       "__OBJC,__category,regular,no_dead_strip",
    1994               12:                       4, true);
    1995               12:   DefinedCategories.push_back(GV);
    1996               12: }
    1997                 : 
    1998                 : // FIXME: Get from somewhere?
    1999                 : enum ClassFlags {
    2000                 :   eClassFlags_Factory              = 0x00001,
    2001                 :   eClassFlags_Meta                 = 0x00002,
    2002                 :   // <rdr://5142207>
    2003                 :   eClassFlags_HasCXXStructors      = 0x02000,
    2004                 :   eClassFlags_Hidden               = 0x20000,
    2005                 :   eClassFlags_ABI2_Hidden          = 0x00010,
    2006                 :   eClassFlags_ABI2_HasCXXStructors = 0x00004   // <rdr://4923634>
    2007                 : };
    2008                 : 
    2009                 : /*
    2010                 :   struct _objc_class {
    2011                 :   Class isa;
    2012                 :   Class super_class;
    2013                 :   const char *name;
    2014                 :   long version;
    2015                 :   long info;
    2016                 :   long instance_size;
    2017                 :   struct _objc_ivar_list *ivars;
    2018                 :   struct _objc_method_list *methods;
    2019                 :   struct _objc_cache *cache;
    2020                 :   struct _objc_protocol_list *protocols;
    2021                 :   // Objective-C 1.0 extensions (<rdr://4585769>)
    2022                 :   const char *ivar_layout;
    2023                 :   struct _objc_class_ext *ext;
    2024                 :   };
    2025                 : 
    2026                 :   See EmitClassExtension();
    2027                 : */
    2028              113: void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
    2029              113:   DefinedSymbols.insert(ID->getIdentifier());
    2030                 : 
    2031              113:   std::string ClassName = ID->getNameAsString();
    2032                 :   // FIXME: Gross
    2033                 :   ObjCInterfaceDecl *Interface =
    2034              113:     const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
    2035                 :   llvm::Constant *Protocols =
    2036                 :     EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
    2037                 :                      Interface->protocol_begin(),
    2038              113:                      Interface->protocol_end());
    2039              113:   unsigned Flags = eClassFlags_Factory;
    2040                 :   unsigned Size =
    2041              113:     CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8;
    2042                 : 
    2043                 :   // FIXME: Set CXX-structors flag.
                        1: branch 2 taken
                      112: branch 3 taken
    2044              113:   if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
    2045                1:     Flags |= eClassFlags_Hidden;
    2046                 : 
    2047              113:   std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
                      113: branch 2 taken
                      113: branch 3 taken
    2048              226:   for (ObjCImplementationDecl::instmeth_iterator
    2049              113:          i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
    2050                 :     // Instance methods should always be defined.
    2051              113:     InstanceMethods.push_back(GetMethodConstant(*i));
    2052                 :   }
                       31: branch 2 taken
                      113: branch 3 taken
    2053              144:   for (ObjCImplementationDecl::classmeth_iterator
    2054              113:          i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
    2055                 :     // Class methods should always be defined.
    2056               31:     ClassMethods.push_back(GetMethodConstant(*i));
    2057                 :   }
    2058                 : 
                       54: branch 2 taken
                      113: branch 3 taken
    2059              167:   for (ObjCImplementationDecl::propimpl_iterator
    2060              113:          i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
    2061               54:     ObjCPropertyImplDecl *PID = *i;
    2062                 : 
                       31: branch 1 taken
                       23: branch 2 taken
    2063               54:     if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
    2064               31:       ObjCPropertyDecl *PD = PID->getPropertyDecl();
    2065                 : 
                       31: branch 1 taken
                        0: branch 2 not taken
    2066               31:       if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
                       30: branch 1 taken
                        1: branch 2 taken
    2067               31:         if (llvm::Constant *C = GetMethodConstant(MD))
    2068               30:           InstanceMethods.push_back(C);
                       30: branch 1 taken
                        1: branch 2 taken
    2069               31:       if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
                       28: branch 1 taken
                        2: branch 2 taken
    2070               30:         if (llvm::Constant *C = GetMethodConstant(MD))
    2071               28:           InstanceMethods.push_back(C);
    2072                 :     }
    2073                 :   }
    2074                 : 
    2075              113:   std::vector<llvm::Constant*> Values(12);
    2076              113:   Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
                       50: branch 1 taken
                       63: branch 2 taken
    2077              113:   if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
    2078                 :     // Record a reference to the super class.
    2079               50:     LazySymbols.insert(Super->getIdentifier());
    2080                 : 
    2081                 :     Values[ 1] =
    2082                 :       llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
    2083               50:                                      ObjCTypes.ClassPtrTy);
    2084                 :   } else {
    2085               63:     Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
    2086                 :   }
    2087              113:   Values[ 2] = GetClassName(ID->getIdentifier());
    2088                 :   // Version is always 0.
    2089              113:   Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
    2090              113:   Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
    2091              113:   Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
    2092              113:   Values[ 6] = EmitIvarList(ID, false);
    2093                 :   Values[ 7] =
    2094                 :     EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
    2095                 :                    "__OBJC,__inst_meth,regular,no_dead_strip",
    2096              113:                    InstanceMethods);
    2097                 :   // cache is always NULL.
    2098              113:   Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
    2099              113:   Values[ 9] = Protocols;
    2100              113:   Values[10] = BuildIvarLayout(ID, true);
    2101              113:   Values[11] = EmitClassExtension(ID);
    2102                 :   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
    2103              113:                                                    Values);
    2104              113:   std::string Name("\01L_OBJC_CLASS_");
    2105              113:   Name += ClassName;
    2106              113:   const char *Section = "__OBJC,__class,regular,no_dead_strip";
    2107                 :   // Check for a forward reference.
    2108              113:   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
                        9: branch 0 taken
                      104: branch 1 taken
    2109              113:   if (GV) {
    2110                 :     assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
                        9: branch 2 taken
                        0: branch 3 not taken
    2111                9:            "Forward metaclass reference has incorrect type.");
    2112                9:     GV->setLinkage(llvm::GlobalValue::InternalLinkage);
    2113                9:     GV->setInitializer(Init);
    2114                9:     GV->setSection(Section);
    2115                9:     GV->setAlignment(4);
    2116                9:     CGM.AddUsedGlobal(GV);
    2117                 :   } 
    2118                 :   else
    2119              104:     GV = CreateMetadataVar(Name, Init, Section, 4, true);
    2120              113:   DefinedClasses.push_back(GV);
    2121              113: }
    2122                 : 
    2123                 : llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
    2124                 :                                          llvm::Constant *Protocols,
    2125              113:                                          const ConstantVector &Methods) {
    2126              113:   unsigned Flags = eClassFlags_Meta;
    2127              113:   unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
    2128                 : 
                        1: branch 2 taken
                      112: branch 3 taken
    2129              113:   if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
    2130                1:     Flags |= eClassFlags_Hidden;
    2131                 : 
    2132              113:   std::vector<llvm::Constant*> Values(12);
    2133                 :   // The isa for the metaclass is the root of the hierarchy.
    2134              113:   const ObjCInterfaceDecl *Root = ID->getClassInterface();
                       65: branch 1 taken
                      113: branch 2 taken
    2135              243:   while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
    2136               65:     Root = Super;
    2137                 :   Values[ 0] =
    2138                 :     llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
    2139              113:                                    ObjCTypes.ClassPtrTy);
    2140                 :   // The super class for the metaclass is emitted as the name of the
    2141                 :   // super class. The runtime fixes this up to point to the
    2142                 :   // *metaclass* for the super class.
                       50: branch 2 taken
                       63: branch 3 taken
    2143              113:   if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
    2144                 :     Values[ 1] =
    2145                 :       llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
    2146               50:                                      ObjCTypes.ClassPtrTy);
    2147                 :   } else {
    2148               63:     Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
    2149                 :   }
    2150              113:   Values[ 2] = GetClassName(ID->getIdentifier());
    2151                 :   // Version is always 0.
    2152              113:   Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
    2153              113:   Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
    2154              113:   Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
    2155              113:   Values[ 6] = EmitIvarList(ID, true);
    2156                 :   Values[ 7] =
    2157                 :     EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
    2158                 :                    "__OBJC,__cls_meth,regular,no_dead_strip",
    2159              113:                    Methods);
    2160                 :   // cache is always NULL.
    2161              113:   Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
    2162              113:   Values[ 9] = Protocols;
    2163                 :   // ivar_layout for metaclass is always NULL.
    2164              113:   Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
    2165                 :   // The class extension is always unused for metaclasses.
    2166              113:   Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
    2167                 :   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
    2168              113:                                                    Values);
    2169                 : 
    2170              113:   std::string Name("\01L_OBJC_METACLASS_");
    2171              113:   Name += ID->getNameAsCString();
    2172                 : 
    2173                 :   // Check for a forward reference.
    2174              113:   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
                        4: branch 0 taken
                      109: branch 1 taken
    2175              113:   if (GV) {
    2176                 :     assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
                        4: branch 2 taken
                        0: branch 3 not taken
    2177                4:            "Forward metaclass reference has incorrect type.");
    2178                4:     GV->setLinkage(llvm::GlobalValue::InternalLinkage);
    2179                4:     GV->setInitializer(Init);
    2180                 :   } else {
    2181                 :     GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
    2182                 :                                   llvm::GlobalValue::InternalLinkage,
    2183              109:                                   Init, Name);
    2184                 :   }
    2185              113:   GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
    2186              113:   GV->setAlignment(4);
    2187              113:   CGM.AddUsedGlobal(GV);
    2188                 : 
    2189              113:   return GV;
    2190                 : }
    2191                 : 
    2192               10: llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
    2193               10:   std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
    2194                 : 
    2195                 :   // FIXME: Should we look these up somewhere other than the module. Its a bit
    2196                 :   // silly since we only generate these while processing an implementation, so
    2197                 :   // exactly one pointer would work if know when we entered/exitted an
    2198                 :   // implementation block.
    2199                 : 
    2200                 :   // Check for an existing forward reference.
    2201                 :   // Previously, metaclass with internal linkage may have been defined.
    2202                 :   // pass 'true' as 2nd argument so it is returned.
                        6: branch 0 taken
                        4: branch 1 taken
    2203               10:   if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
    2204               10:                                                                    true)) {
    2205                 :     assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
                        6: branch 2 taken
                        0: branch 3 not taken
    2206                6:            "Forward metaclass reference has incorrect type.");
    2207                6:     return GV;
    2208                 :   } else {
    2209                 :     // Generate as an external reference to keep a consistent
    2210                 :     // module. This will be patched up when we emit the metaclass.
    2211                 :     return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
    2212                 :                                     llvm::GlobalValue::ExternalLinkage,
    2213                 :                                     0,
    2214                4:                                     Name);
    2215               10:   }
    2216                 : }
    2217                 : 
    2218               21: llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
    2219               21:   std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
    2220                 :   
                       12: branch 0 taken
                        9: branch 1 taken
    2221               21:   if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
    2222               21:                                                                    true)) {
    2223                 :     assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
                       12: branch 2 taken
                        0: branch 3 not taken
    2224               12:            "Forward class metadata reference has incorrect type.");
    2225               12:     return GV;
    2226                 :   } else {
    2227                 :     return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
    2228                 :                                     llvm::GlobalValue::ExternalLinkage,
    2229                 :                                     0,
    2230                9:                                     Name);
    2231               21:   }
    2232                 : }
    2233                 : 
    2234                 : /*
    2235                 :   struct objc_class_ext {
    2236                 :   uint32_t size;
    2237                 :   const char *weak_ivar_layout;
    2238                 :   struct _objc_property_list *properties;
    2239                 :   };
    2240                 : */
    2241                 : llvm::Constant *
    2242              113: CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
    2243                 :   uint64_t Size =
    2244              113:     CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
    2245                 : 
    2246              113:   std::vector<llvm::Constant*> Values(3);
    2247              113:   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
    2248              113:   Values[1] = BuildIvarLayout(ID, false);
    2249                 :   Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
    2250              113:                                ID, ID->getClassInterface(), ObjCTypes);
    2251                 : 
    2252                 :   // Return null if no extension bits are used.
                      109: branch 2 taken
                        4: branch 3 taken
                       87: branch 6 taken
                       22: branch 7 taken
                       87: branch 8 taken
                       26: branch 9 taken
    2253              113:   if (Values[1]->isNullValue() && Values[2]->isNullValue())
    2254               87:     return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
    2255                 : 
    2256                 :   llvm::Constant *Init =
    2257               26:     llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
    2258                 :   return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
    2259                 :                            Init, "__OBJC,__class_ext,regular,no_dead_strip",
    2260               26:                            4, true);
    2261                 : }
    2262                 : 
    2263                 : /*
    2264                 :   struct objc_ivar {
    2265                 :   char *ivar_name;
    2266                 :   char *ivar_type;
    2267                 :   int ivar_offset;
    2268                 :   };
    2269                 : 
    2270                 :   struct objc_ivar_list {
    2271                 :   int ivar_count;
    2272                 :   struct objc_ivar list[count];
    2273                 :   };
    2274                 : */
    2275                 : llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
    2276              226:                                         bool ForClass) {
    2277              226:   std::vector<llvm::Constant*> Ivars, Ivar(3);
    2278                 : 
    2279                 :   // When emitting the root class GCC emits ivar entries for the
    2280                 :   // actual class structure. It is not clear if we need to follow this
    2281                 :   // behavior; for now lets try and get away with not doing it. If so,
    2282                 :   // the cleanest solution would be to make up an ObjCInterfaceDecl
    2283                 :   // for the class.
                      113: branch 0 taken
                      113: branch 1 taken
    2284              226:   if (ForClass)
    2285              113:     return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
    2286                 : 
    2287                 :   ObjCInterfaceDecl *OID =
    2288              113:     const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
    2289                 : 
    2290              113:   llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
    2291              113:   CGM.getContext().ShallowCollectObjCIvars(OID, OIvars);
    2292                 : 
                      156: branch 1 taken
                      113: branch 2 taken
    2293              269:   for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
    2294              156:     ObjCIvarDecl *IVD = OIvars[i];
    2295                 :     // Ignore unnamed bit-fields.
                        2: branch 2 taken
                      154: branch 3 taken
    2296              156:     if (!IVD->getDeclName())
    2297                2:       continue;
    2298              154:     Ivar[0] = GetMethodVarName(IVD->getIdentifier());
    2299              154:     Ivar[1] = GetMethodVarType(IVD);
    2300                 :     Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy,
    2301              154:                                      ComputeIvarBaseOffset(CGM, OID, IVD));
    2302              154:     Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
    2303                 :   }
    2304                 : 
    2305                 :   // Return null for empty list.
                       67: branch 1 taken
                       46: branch 2 taken
    2306              113:   if (Ivars.empty())
    2307               67:     return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
    2308                 : 
    2309               46:   std::vector<llvm::Constant*> Values(2);
    2310               46:   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
    2311                 :   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
    2312               46:                                              Ivars.size());
    2313               46:   Values[1] = llvm::ConstantArray::get(AT, Ivars);
    2314               46:   llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
    2315                 : 
    2316                 :   llvm::GlobalVariable *GV;
                        0: branch 0 not taken
                       46: branch 1 taken
    2317               46:   if (ForClass)
    2318                 :     GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
    2319                 :                            Init, "__OBJC,__class_vars,regular,no_dead_strip",
    2320                0:                            4, true);
    2321                 :   else
    2322                 :     GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
    2323                 :                            Init, "__OBJC,__instance_vars,regular,no_dead_strip",
    2324               46:                            4, true);
    2325               46:   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
    2326                 : }
    2327                 : 
    2328                 : /*
    2329                 :   struct objc_method {
    2330                 :   SEL method_name;
    2331                 :   char *method_types;
    2332                 :   void *method;
    2333                 :   };
    2334                 : 
    2335                 :   struct objc_method_list {
    2336                 :   struct objc_method_list *obsolete;
    2337                 :   int count;
    2338                 :   struct objc_method methods_list[count];
    2339                 :   };
    2340                 : */
    2341                 : 
    2342                 : /// GetMethodConstant - Return a struct objc_method constant for the
    2343                 : /// given method if it has been defined. The result is null if the
    2344                 : /// method has not been defined. The return value has type MethodPtrTy.
    2345              213: llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
    2346                 :   // FIXME: Use DenseMap::lookup
    2347              213:   llvm::Function *Fn = MethodDefinitions[MD];
                        3: branch 0 taken
                      210: branch 1 taken
    2348              213:   if (!Fn)
    2349                3:     return 0;
    2350                 : 
    2351              210:   std::vector<llvm::Constant*> Method(3);
    2352                 :   Method[0] =
    2353                 :     llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
    2354              210:                                    ObjCTypes.SelectorPtrTy);
    2355              210:   Method[1] = GetMethodVarType(MD);
    2356              210:   Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
    2357              210:   return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
    2358                 : }
    2359                 : 
    2360                 : llvm::Constant *CGObjCMac::EmitMethodList(llvm::Twine Name,
    2361                 :                                           const char *Section,
    2362              250:                                           const ConstantVector &Methods) {
    2363                 :   // Return null for empty list.
                      158: branch 1 taken
                       92: branch 2 taken
    2364              250:   if (Methods.empty())
    2365              158:     return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
    2366                 : 
    2367               92:   std::vector<llvm::Constant*> Values(3);
    2368               92:   Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
    2369               92:   Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
    2370                 :   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
    2371               92:                                              Methods.size());
    2372               92:   Values[2] = llvm::ConstantArray::get(AT, Methods);
    2373               92:   llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
    2374                 : 
    2375               92:   llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
    2376                 :   return llvm::ConstantExpr::getBitCast(GV,
    2377               92:                                         ObjCTypes.MethodListPtrTy);
    2378                 : }
    2379                 : 
    2380                 : llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
    2381              284:                                                 const ObjCContainerDecl *CD) {
    2382              284:   llvm::SmallString<256> Name;
    2383              284:   GetNameForMethod(OMD, CD, Name);
    2384                 : 
    2385              284:   CodeGenTypes &Types = CGM.getTypes();
    2386                 :   const llvm::FunctionType *MethodTy =
    2387              284:     Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
    2388                 :   llvm::Function *Method =
    2389                 :     llvm::Function::Create(MethodTy,
    2390                 :                            llvm::GlobalValue::InternalLinkage,
    2391                 :                            Name.str(),
    2392              284:                            &CGM.getModule());
    2393              284:   MethodDefinitions.insert(std::make_pair(OMD, Method));
    2394                 : 
    2395              284:   return Method;
    2396                 : }
    2397                 : 
    2398                 : llvm::GlobalVariable *
    2399                 : CGObjCCommonMac::CreateMetadataVar(llvm::Twine Name,
    2400                 :                                    llvm::Constant *Init,
    2401                 :                                    const char *Section,
    2402                 :                                    unsigned Align,
    2403             2108:                                    bool AddToUsed) {
    2404             2108:   const llvm::Type *Ty = Init->getType();
    2405                 :   llvm::GlobalVariable *GV =
    2406                 :     new llvm::GlobalVariable(CGM.getModule(), Ty, false,
    2407             2108:                              llvm::GlobalValue::InternalLinkage, Init, Name);
                     2106: branch 0 taken
                        2: branch 1 taken
    2408             2108:   if (Section)
    2409             2106:     GV->setSection(Section);
                     1996: branch 0 taken
                      112: branch 1 taken
    2410             2108:   if (Align)
    2411             1996:     GV->setAlignment(Align);
                     2098: branch 0 taken
                       10: branch 1 taken
    2412             2108:   if (AddToUsed)
    2413             2098:     CGM.AddUsedGlobal(GV);
    2414             2108:   return GV;
    2415                 : }
    2416                 : 
    2417              109: llvm::Function *CGObjCMac::ModuleInitFunction() {
    2418                 :   // Abuse this interface function as a place to finalize.
    2419              109:   FinishModule();
    2420              109:   return NULL;
    2421                 : }
    2422                 : 
    2423                6: llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
    2424                6:   return ObjCTypes.getGetPropertyFn();
    2425                 : }
    2426                 : 
    2427                8: llvm::Constant *CGObjCMac::GetPropertySetFunction() {
    2428                8:   return ObjCTypes.getSetPropertyFn();
    2429                 : }
    2430                 : 
    2431                4: llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
    2432                4:   return ObjCTypes.getEnumerationMutationFn();
    2433                 : }
    2434                 : 
    2435                 : /*
    2436                 : 
    2437                 :   Objective-C setjmp-longjmp (sjlj) Exception Handling
    2438                 :   --
    2439                 : 
    2440                 :   The basic framework for a @try-catch-finally is as follows:
    2441                 :   {
    2442                 :   objc_exception_data d;
    2443                 :   id _rethrow = null;
    2444                 :   bool _call_try_exit = true;
    2445                 : 
    2446                 :   objc_exception_try_enter(&d);
    2447                 :   if (!setjmp(d.jmp_buf)) {
    2448                 :   ... try body ...
    2449                 :   } else {
    2450                 :   // exception path
    2451                 :   id _caught = objc_exception_extract(&d);
    2452                 : 
    2453                 :   // enter new try scope for handlers
    2454                 :   if (!setjmp(d.jmp_buf)) {
    2455                 :   ... match exception and execute catch blocks ...
    2456                 : 
    2457                 :   // fell off end, rethrow.
    2458                 :   _rethrow = _caught;
    2459                 :   ... jump-through-finally to finally_rethrow ...
    2460                 :   } else {
    2461                 :   // exception in catch block
    2462                 :   _rethrow = objc_exception_extract(&d);
    2463                 :   _call_try_exit = false;
    2464                 :   ... jump-through-finally to finally_rethrow ...
    2465                 :   }
    2466                 :   }
    2467                 :   ... jump-through-finally to finally_end ...
    2468                 : 
    2469                 :   finally:
    2470                 :   if (_call_try_exit)
    2471                 :   objc_exception_try_exit(&d);
    2472                 : 
    2473                 :   ... finally block ....
    2474                 :   ... dispatch to finally destination ...
    2475                 : 
    2476                 :   finally_rethrow:
    2477                 :   objc_exception_throw(_rethrow);
    2478                 : 
    2479                 :   finally_end:
    2480                 :   }
    2481                 : 
    2482                 :   This framework differs slightly from the one gcc uses, in that gcc
    2483                 :   uses _rethrow to determine if objc_exception_try_exit should be called
    2484                 :   and if the object should be rethrown. This breaks in the face of
    2485                 :   throwing nil and introduces unnecessary branches.
    2486                 : 
    2487                 :   We specialize this framework for a few particular circumstances:
    2488                 : 
    2489                 :   - If there are no catch blocks, then we avoid emitting the second
    2490                 :   exception handling context.
    2491                 : 
    2492                 :   - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
    2493                 :   e)) we avoid emitting the code to rethrow an uncaught exception.
    2494                 : 
    2495                 :   - FIXME: If there is no @finally block we can do a few more
    2496                 :   simplifications.
    2497                 : 
    2498                 :   Rethrows and Jumps-Through-Finally
    2499                 :   --
    2500                 : 
    2501                 :   Support for implicit rethrows and jumping through the finally block is
    2502                 :   handled by storing the current exception-handling context in
    2503                 :   ObjCEHStack.
    2504                 : 
    2505                 :   In order to implement proper @finally semantics, we support one basic
    2506                 :   mechanism for jumping through the finally block to an arbitrary
    2507                 :   destination. Constructs which generate exits from a @try or @catch
    2508                 :   block use this mechanism to implement the proper semantics by chaining
    2509                 :   jumps, as necessary.
    2510                 : 
    2511                 :   This mechanism works like the one used for indirect goto: we
    2512                 :   arbitrarily assign an ID to each destination and store the ID for the
    2513                 :   destination in a variable prior to entering the finally block. At the
    2514                 :   end of the finally block we simply create a switch to the proper
    2515                 :   destination.
    2516                 : 
    2517                 :   Code gen for @synchronized(expr) stmt;
    2518                 :   Effectively generating code for:
    2519                 :   objc_sync_enter(expr);
    2520                 :   @try stmt @finally { objc_sync_exit(expr); }
    2521                 : */
    2522                 : 
    2523                 : void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
    2524               15:                                           const Stmt &S) {
    2525               15:   bool isTry = isa<ObjCAtTryStmt>(S);
    2526                 :   // Create various blocks we refer to for handling @finally.
    2527               15:   llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
    2528               15:   llvm::BasicBlock *FinallyExit = CGF.createBasicBlock("finally.exit");
    2529               15:   llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit");
    2530               15:   llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
    2531               15:   llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
    2532                 : 
    2533                 :   // For @synchronized, call objc_sync_enter(sync.expr). The
    2534                 :   // evaluation of the expression must occur before we enter the
    2535                 :   // @synchronized. We can safely avoid a temp here because jumps into
    2536                 :   // @synchronized are illegal & this will dominate uses.
    2537               15:   llvm::Value *SyncArg = 0;
                        7: branch 0 taken
                        8: branch 1 taken
    2538               15:   if (!isTry) {
    2539                 :     SyncArg =
    2540                7:       CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
    2541                7:     SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
    2542                7:     CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg);
    2543                 :   }
    2544                 : 
    2545                 :   // Push an EH context entry, used for handling rethrows and jumps
    2546                 :   // through finally.
    2547               15:   CGF.PushCleanupBlock(FinallyBlock);
    2548                 : 
                       13: branch 1 taken
                        2: branch 2 taken
    2549               15:   if (CGF.ObjCEHValueStack.empty())
    2550               13:     CGF.ObjCEHValueStack.push_back(0);
    2551                 :   // If This is a nested @try, caught exception is that of enclosing @try.
    2552                 :   else
    2553                2:     CGF.ObjCEHValueStack.push_back(CGF.ObjCEHValueStack.back());
    2554                 :   // Allocate memory for the exception data and rethrow pointer.
    2555                 :   llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
    2556               15:                                                     "exceptiondata.ptr");
    2557                 :   llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy,
    2558               15:                                                  "_rethrow");
    2559                 :   llvm::Value *CallTryExitPtr = CGF.CreateTempAlloca(
    2560                 :                                                llvm::Type::getInt1Ty(VMContext),
    2561               15:                                                      "_call_try_exit");
    2562                 :   CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext),
    2563               15:                           CallTryExitPtr);
    2564                 : 
    2565                 :   // Enter a new try block and call setjmp.
    2566               15:   CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
    2567                 :   llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0,
    2568               15:                                                        "jmpbufarray");
    2569               15:   JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp");
    2570                 :   llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(),
    2571               15:                                                      JmpBufPtr, "result");
    2572                 : 
    2573               15:   llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
    2574               15:   llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
    2575                 :   CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"),
    2576               15:                            TryHandler, TryBlock);
    2577                 : 
    2578                 :   // Emit the @try block.
    2579               15:   CGF.EmitBlock(TryBlock);
    2580                 :   CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
                        8: branch 0 taken
                        7: branch 1 taken
    2581               15:                : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
    2582               15:   CGF.EmitBranchThroughCleanup(FinallyEnd);
    2583                 : 
    2584                 :   // Emit the "exception in @try" block.
    2585               15:   CGF.EmitBlock(TryHandler);
    2586                 : 
    2587                 :   // Retrieve the exception object.  We may emit multiple blocks but
    2588                 :   // nothing can cross this so the value is already in SSA form.
    2589                 :   llvm::Value *Caught =
    2590                 :     CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
    2591               15:                            ExceptionData, "caught");
    2592               15:   CGF.ObjCEHValueStack.back() = Caught;
                        7: branch 0 taken
                        8: branch 1 taken
    2593               15:   if (!isTry) {
    2594                7:     CGF.Builder.CreateStore(Caught, RethrowPtr);
    2595                 :     CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
    2596                7:                             CallTryExitPtr);
    2597                7:     CGF.EmitBranchThroughCleanup(FinallyRethrow);
                        7: branch 0 taken
                        1: branch 1 taken
    2598                8:   } else if (const ObjCAtCatchStmt* CatchStmt =
    2599                8:              cast<ObjCAtTryStmt>(S).getCatchStmts()) {
    2600                 :     // Enter a new exception try block (in case a @catch block throws
    2601                 :     // an exception).
    2602                7:     CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
    2603                 : 
    2604                 :     llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(),
    2605                7:                                                        JmpBufPtr, "result");
    2606                7:     llvm::Value *Threw = CGF.Builder.CreateIsNotNull(SetJmpResult, "threw");
    2607                 : 
    2608                7:     llvm::BasicBlock *CatchBlock = CGF.createBasicBlock("catch");
    2609                7:     llvm::BasicBlock *CatchHandler = CGF.createBasicBlock("catch.handler");
    2610                7:     CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
    2611                 : 
    2612                7:     CGF.EmitBlock(CatchBlock);
    2613                 : 
    2614                 :     // Handle catch list. As a special case we check if everything is
    2615                 :     // matched and avoid generating code for falling off the end if
    2616                 :     // so.
    2617                7:     bool AllMatched = false;
                        9: branch 1 taken
                        2: branch 2 taken
    2618               22:     for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
    2619                9:       llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch");
    2620                 : 
    2621                9:       const ParmVarDecl *CatchParam = CatchStmt->getCatchParamDecl();
    2622                9:       const ObjCObjectPointerType *OPT = 0;
    2623                 : 
    2624                 :       // catch(...) always matches.
                        2: branch 0 taken
                        7: branch 1 taken
    2625                9:       if (!CatchParam) {
    2626                2:         AllMatched = true;
    2627                 :       } else {
    2628                7:         OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
    2629                 : 
    2630                 :         // catch(id e) always matches.
    2631                 :         // FIXME: For the time being we also match id<X>; this should
    2632                 :         // be rejected by Sema instead.
                        7: branch 0 taken
                        0: branch 1 not taken
                        4: branch 3 taken
                        3: branch 4 taken
                        0: branch 6 not taken
                        4: branch 7 taken
                        3: branch 8 taken
                        4: branch 9 taken
    2633                7:         if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
    2634                3:           AllMatched = true;
    2635                 :       }
    2636                 : 
                        5: branch 0 taken
                        4: branch 1 taken
    2637                9:       if (AllMatched) {
                        3: branch 0 taken
                        2: branch 1 taken
    2638                5:         if (CatchParam) {
    2639                3:           CGF.EmitLocalBlockVarDecl(*CatchParam);
                        3: branch 1 taken
                        0: branch 2 not taken
    2640                3:           assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
    2641                3:           CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
    2642                 :         }
    2643                 : 
    2644                5:         CGF.EmitStmt(CatchStmt->getCatchBody());
    2645                5:         CGF.EmitBranchThroughCleanup(FinallyEnd);
    2646                5:         break;
    2647                 :       }
    2648                 : 
                        0: branch 0 not taken
                        4: branch 1 taken
    2649                4:       assert(OPT && "Unexpected non-object pointer type in @catch");
    2650                4:       QualType T = OPT->getPointeeType();
    2651                4:       const ObjCInterfaceType *ObjCType = T->getAs<ObjCInterfaceType>();
                        0: branch 0 not taken
                        4: branch 1 taken
    2652                4:       assert(ObjCType && "Catch parameter must have Objective-C type!");
    2653                 : 
    2654                 :       // Check if the @catch block matches the exception object.
    2655                4:       llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl());
    2656                 : 
    2657                 :       llvm::Value *Match =
    2658                 :         CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
    2659                4:                                 Class, Caught, "match");
    2660                 : 
    2661                4:       llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("matched");
    2662                 : 
    2663                 :       CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
    2664                4:                                MatchedBlock, NextCatchBlock);
    2665                 : 
    2666                 :       // Emit the @catch block.
    2667                4:       CGF.EmitBlock(MatchedBlock);
    2668                4:       CGF.EmitLocalBlockVarDecl(*CatchParam);
                        4: branch 1 taken
                        0: branch 2 not taken
    2669                4:       assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
    2670                 : 
    2671                 :       llvm::Value *Tmp =
    2672                 :         CGF.Builder.CreateBitCast(Caught,
    2673                 :                                   CGF.ConvertType(CatchParam->getType()),
    2674                4:                                   "tmp");
    2675                4:       CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
    2676                 : 
    2677                4:       CGF.EmitStmt(CatchStmt->getCatchBody());
    2678                4:       CGF.EmitBranchThroughCleanup(FinallyEnd);
    2679                 : 
    2680                4:       CGF.EmitBlock(NextCatchBlock);
    2681                 :     }
    2682                 : 
                        2: branch 0 taken
                        5: branch 1 taken
    2683                7:     if (!AllMatched) {
    2684                 :       // None of the handlers caught the exception, so store it to be
    2685                 :       // rethrown at the end of the @finally block.
    2686                2:       CGF.Builder.CreateStore(Caught, RethrowPtr);
    2687                2:       CGF.EmitBranchThroughCleanup(FinallyRethrow);
    2688                 :     }
    2689                 : 
    2690                 :     // Emit the exception handler for the @catch blocks.
    2691                7:     CGF.EmitBlock(CatchHandler);
    2692                 :     CGF.Builder.CreateStore(
    2693                 :       CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
    2694                 :                              ExceptionData),
    2695                7:       RethrowPtr);
    2696                 :     CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
    2697                7:                             CallTryExitPtr);
    2698                7:     CGF.EmitBranchThroughCleanup(FinallyRethrow);
    2699                 :   } else {
    2700                1:     CGF.Builder.CreateStore(Caught, RethrowPtr);
    2701                 :     CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext),
    2702                1:                             CallTryExitPtr);
    2703                1:     CGF.EmitBranchThroughCleanup(FinallyRethrow);
    2704                 :   }
    2705                 : 
    2706                 :   // Pop the exception-handling stack entry. It is important to do
    2707                 :   // this now, because the code in the @finally block is not in this
    2708                 :   // context.
    2709               15:   CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
    2710                 : 
    2711               15:   CGF.ObjCEHValueStack.pop_back();
    2712                 : 
    2713                 :   // Emit the @finally block.
    2714               15:   CGF.EmitBlock(FinallyBlock);
    2715               15:   llvm::Value* CallTryExit = CGF.Builder.CreateLoad(CallTryExitPtr, "tmp");
    2716                 : 
    2717               15:   CGF.Builder.CreateCondBr(CallTryExit, FinallyExit, FinallyNoExit);
    2718                 : 
    2719               15:   CGF.EmitBlock(FinallyExit);
    2720               15:   CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData);
    2721                 : 
    2722               15:   CGF.EmitBlock(FinallyNoExit);
                        8: branch 0 taken
                        7: branch 1 taken
    2723               15:   if (isTry) {
                        3: branch 0 taken
                        5: branch 1 taken
    2724                8:     if (const ObjCAtFinallyStmt* FinallyStmt =
    2725                8:         cast<ObjCAtTryStmt>(S).getFinallyStmt())
    2726                3:       CGF.EmitStmt(FinallyStmt->getFinallyBody());
    2727                 :   } else {
    2728                 :     // Emit objc_sync_exit(expr); as finally's sole statement for
    2729                 :     // @synchronized.
    2730                7:     CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg);
    2731                 :   }
    2732                 : 
    2733                 :   // Emit the switch block
                       15: branch 0 taken
                        0: branch 1 not taken
    2734               15:   if (Info.SwitchBlock)
    2735               15:     CGF.EmitBlock(Info.SwitchBlock);
                       15: branch 0 taken
                        0: branch 1 not taken
    2736               15:   if (Info.EndBlock)
    2737               15:     CGF.EmitBlock(Info.EndBlock);
    2738                 : 
    2739               15:   CGF.EmitBlock(FinallyRethrow);
    2740                 :   CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(),
    2741               15:                          CGF.Builder.CreateLoad(RethrowPtr));
    2742               15:   CGF.Builder.CreateUnreachable();
    2743                 : 
    2744               15:   CGF.EmitBlock(FinallyEnd);
    2745               15: }
    2746                 : 
    2747                 : void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
    2748                6:                               const ObjCAtThrowStmt &S) {
    2749                 :   llvm::Value *ExceptionAsObject;
    2750                 : 
                        3: branch 1 taken
                        3: branch 2 taken
    2751                6:   if (const Expr *ThrowExpr = S.getThrowExpr()) {
    2752                3:     llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
    2753                 :     ExceptionAsObject =
    2754                3:       CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
    2755                 :   } else {
    2756                 :     assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
                        3: branch 1 taken
                        0: branch 2 not taken
                        3: branch 4 taken
                        0: branch 5 not taken
    2757                3:            "Unexpected rethrow outside @catch block.");
    2758                3:     ExceptionAsObject = CGF.ObjCEHValueStack.back();
    2759                 :   }
    2760                 : 
    2761                6:   CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject);
    2762                6:   CGF.Builder.CreateUnreachable();
    2763                 : 
    2764                 :   // Clear the insertion point to indicate we are in unreachable code.
    2765                6:   CGF.Builder.ClearInsertionPoint();
    2766                6: }
    2767                 : 
    2768                 : /// EmitObjCWeakRead - Code gen for loading value of a __weak
    2769                 : /// object: objc_read_weak (id *src)
    2770                 : ///
    2771                 : llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
    2772               14:                                           llvm::Value *AddrWeakObj) {
    2773                 :   const llvm::Type* DestTy =
    2774               14:     cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
    2775                 :   AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
    2776               14:                                           ObjCTypes.PtrObjectPtrTy);
    2777                 :   llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
    2778               14:                                                   AddrWeakObj, "weakread");
    2779               14:   read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
    2780               14:   return read_weak;
    2781                 : }
    2782                 : 
    2783                 : /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
    2784                 : /// objc_assign_weak (id src, id *dst)
    2785                 : ///
    2786                 : void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
    2787               10:                                    llvm::Value *src, llvm::Value *dst) {
    2788               10:   const llvm::Type * SrcTy = src->getType();
                        0: branch 1 not taken
                       10: branch 2 taken
    2789               10:   if (!isa<llvm::PointerType>(SrcTy)) {
    2790                0:     unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
                        0: branch 0 not taken
                        0: branch 1 not taken
    2791                0:     assert(Size <= 8 && "does not support size > 8");
    2792                 :     src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
                        0: branch 0 not taken
                        0: branch 1 not taken
    2793                0:       : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
    2794                0:     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
    2795                 :   }
    2796               10:   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
    2797               10:   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
    2798                 :   CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
    2799               10:                           src, dst, "weakassign");
    2800                 :   return;
    2801                 : }
    2802                 : 
    2803                 : /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
    2804                 : /// objc_assign_global (id src, id *dst)
    2805                 : ///
    2806                 : void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
    2807               53:                                      llvm::Value *src, llvm::Value *dst) {
    2808               53:   const llvm::Type * SrcTy = src->getType();
                        0: branch 1 not taken
                       53: branch 2 taken
    2809               53:   if (!isa<llvm::PointerType>(SrcTy)) {
    2810                0:     unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
                        0: branch 0 not taken
                        0: branch 1 not taken
    2811                0:     assert(Size <= 8 && "does not support size > 8");
    2812                 :     src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
                        0: branch 0 not taken
                        0: branch 1 not taken
    2813                0:       : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
    2814                0:     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
    2815                 :   }
    2816               53:   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
    2817               53:   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
    2818                 :   CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
    2819               53:                           src, dst, "globalassign");
    2820                 :   return;
    2821                 : }
    2822                 : 
    2823                 : /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
    2824                 : /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
    2825                 : ///
    2826                 : void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
    2827                 :                                    llvm::Value *src, llvm::Value *dst,
    2828               28:                                    llvm::Value *ivarOffset) {
                        0: branch 0 not taken
                       28: branch 1 taken
    2829               28:   assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
    2830               28:   const llvm::Type * SrcTy = src->getType();
                        0: branch 1 not taken
                       28: branch 2 taken
    2831               28:   if (!isa<llvm::PointerType>(SrcTy)) {
    2832                0:     unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
                        0: branch 0 not taken
                        0: branch 1 not taken
    2833                0:     assert(Size <= 8 && "does not support size > 8");
    2834                 :     src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
                        0: branch 0 not taken
                        0: branch 1 not taken
    2835                0:       : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
    2836                0:     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
    2837                 :   }
    2838               28:   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
    2839               28:   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
    2840                 :   CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
    2841               28:                           src, dst, ivarOffset);
    2842                 :   return;
    2843                 : }
    2844                 : 
    2845                 : /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
    2846                 : /// objc_assign_strongCast (id src, id *dst)
    2847                 : ///
    2848                 : void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
    2849               17:                                          llvm::Value *src, llvm::Value *dst) {
    2850               17:   const llvm::Type * SrcTy = src->getType();
                        0: branch 1 not taken
                       17: branch 2 taken
    2851               17:   if (!isa<llvm::PointerType>(SrcTy)) {
    2852                0:     unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
                        0: branch 0 not taken
                        0: branch 1 not taken
    2853                0:     assert(Size <= 8 && "does not support size > 8");
    2854                 :     src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
                        0: branch 0 not taken
                        0: branch 1 not taken
    2855                0:       : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
    2856                0:     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
    2857                 :   }
    2858               17:   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
    2859               17:   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
    2860                 :   CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
    2861               17:                           src, dst, "weakassign");
    2862                 :   return;
    2863                 : }
    2864                 : 
    2865                 : void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
    2866                 :                                          llvm::Value *DestPtr,
    2867                 :                                          llvm::Value *SrcPtr,
    2868                5:                                          QualType Ty) {
    2869                 :   // Get size info for this aggregate.
    2870                5:   std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
    2871                5:   unsigned long size = TypeInfo.first/8;
    2872                5:   SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
    2873                5:   DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
    2874                5:   llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size);
    2875                 :   CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
    2876                5:                           DestPtr, SrcPtr, N);
    2877                 :   return;
    2878                 : }
    2879                 : 
    2880                 : /// EmitObjCValueForIvar - Code Gen for ivar reference.
    2881                 : ///
    2882                 : LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
    2883                 :                                        QualType ObjectTy,
    2884                 :                                        llvm::Value *BaseValue,
    2885                 :                                        const ObjCIvarDecl *Ivar,
    2886              235:                                        unsigned CVRQualifiers) {
    2887              235:   const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
    2888                 :   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
    2889              235:                                   EmitIvarOffset(CGF, ID, Ivar));
    2890                 : }
    2891                 : 
    2892                 : llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
    2893                 :                                        const ObjCInterfaceDecl *Interface,
    2894              249:                                        const ObjCIvarDecl *Ivar) {
    2895              249:   uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
    2896                 :   return llvm::ConstantInt::get(
    2897                 :     CGM.getTypes().ConvertType(CGM.getContext().LongTy),
    2898              249:     Offset);
    2899                 : }
    2900                 : 
    2901                 : /* *** Private Interface *** */
    2902                 : 
    2903                 : /// EmitImageInfo - Emit the image info marker used to encode some module
    2904                 : /// level information.
    2905                 : ///
    2906                 : /// See: <rdr://4810609&4810587&4810587>
    2907                 : /// struct IMAGE_INFO {
    2908                 : ///   unsigned version;
    2909                 : ///   unsigned flags;
    2910                 : /// };
    2911                 : enum ImageInfoFlags {
    2912                 :   eImageInfo_FixAndContinue      = (1 << 0), // FIXME: Not sure what
    2913                 :                                              // this implies.
    2914                 :   eImageInfo_GarbageCollected    = (1 << 1),
    2915                 :   eImageInfo_GCOnly              = (1 << 2),
    2916                 :   eImageInfo_OptimizedByDyld     = (1 << 3), // FIXME: When is this set.
    2917                 : 
    2918                 :   // A flag indicating that the module has no instances of an
    2919                 :   // @synthesize of a superclass variable. <rdar://problem/6803242>
    2920                 :   eImageInfo_CorrectedSynthesize = (1 << 4)
    2921                 : };
    2922                 : 
    2923              110: void CGObjCMac::EmitImageInfo() {
    2924              110:   unsigned version = 0; // Version is unused?
    2925              110:   unsigned flags = 0;
    2926                 : 
    2927                 :   // FIXME: Fix and continue?
                       24: branch 2 taken
                       86: branch 3 taken
    2928              110:   if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
    2929               24:     flags |= eImageInfo_GarbageCollected;
                        1: branch 2 taken
                      109: branch 3 taken
    2930              110:   if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
    2931                1:     flags |= eImageInfo_GCOnly;
    2932                 : 
    2933                 :   // We never allow @synthesize of a superclass property.
    2934              110:   flags |= eImageInfo_CorrectedSynthesize;
    2935                 : 
    2936                 :   // Emitted as int[2];
    2937                 :   llvm::Constant *values[2] = {
    2938                 :     llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), version),
    2939                 :     llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags)
    2940              110:   };
    2941              110:   llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext), 2);
    2942                 : 
    2943                 :   const char *Section;
                      110: branch 0 taken
                        0: branch 1 not taken
    2944              110:   if (ObjCABI == 1)
    2945              110:     Section = "__OBJC, __image_info,regular";
    2946                 :   else
    2947                0:     Section = "__DATA, __objc_imageinfo, regular, no_dead_strip";
    2948                 :   llvm::GlobalVariable *GV =
    2949                 :     CreateMetadataVar("\01L_OBJC_IMAGE_INFO",
    2950                 :                       llvm::ConstantArray::get(AT, values, 2),
    2951                 :                       Section,
    2952                 :                       0,
    2953              110:                       true);
    2954              110:   GV->setConstant(true);
    2955              110: }
    2956                 : 
    2957                 : 
    2958                 : // struct objc_module {
    2959                 : //   unsigned long version;
    2960                 : //   unsigned long size;
    2961                 : //   const char *name;
    2962                 : //   Symtab symtab;
    2963                 : // };
    2964                 : 
    2965                 : // FIXME: Get from somewhere
    2966                 : static const int ModuleVersion = 7;
    2967                 : 
    2968              109: void CGObjCMac::EmitModuleInfo() {
    2969              109:   uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy);
    2970                 : 
    2971              109:   std::vector<llvm::Constant*> Values(4);
    2972              109:   Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
    2973              109:   Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
    2974                 :   // This used to be the filename, now it is unused. <rdr://4327263>
    2975              109:   Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
    2976              109:   Values[3] = EmitModuleSymbols();
    2977                 :   CreateMetadataVar("\01L_OBJC_MODULES",
    2978                 :                     llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
    2979                 :                     "__OBJC,__module_info,regular,no_dead_strip",
    2980              109:                     4, true);
    2981              109: }
    2982                 : 
    2983              109: llvm::Constant *CGObjCMac::EmitModuleSymbols() {
    2984              109:   unsigned NumClasses = DefinedClasses.size();
    2985              109:   unsigned NumCategories = DefinedCategories.size();
    2986                 : 
    2987                 :   // Return null if no symbols were defined.
                       42: branch 0 taken
                       67: branch 1 taken
                       40: branch 2 taken
                        2: branch 3 taken
    2988              109:   if (!NumClasses && !NumCategories)
    2989               40:     return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
    2990                 : 
    2991               69:   std::vector<llvm::Constant*> Values(5);
    2992               69:   Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
    2993               69:   Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
    2994               69:   Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
    2995               69:   Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
    2996                 : 
    2997                 :   // The runtime expects exactly the list of defined classes followed
    2998                 :   // by the list of defined categories, in a single array.
    2999               69:   std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
                      113: branch 0 taken
                       69: branch 1 taken
    3000              182:   for (unsigned i=0; i<NumClasses; i++)
    3001                 :     Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
    3002              113:                                                 ObjCTypes.Int8PtrTy);
                       12: branch 0 taken
                       69: branch 1 taken
    3003               81:   for (unsigned i=0; i<NumCategories; i++)
    3004                 :     Symbols[NumClasses + i] =
    3005                 :       llvm::ConstantExpr::getBitCast(DefinedCategories[i],
    3006               12:                                      ObjCTypes.Int8PtrTy);
    3007                 : 
    3008                 :   Values[4] =
    3009                 :     llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
    3010                 :                                                   NumClasses + NumCategories),
    3011               69:                              Symbols);
    3012                 : 
    3013               69:   llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false);
    3014                 : 
    3015                 :   llvm::GlobalVariable *GV =
    3016                 :     CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
    3017                 :                       "__OBJC,__symbols,regular,no_dead_strip",
    3018               69:                       4, true);
    3019               69:   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
    3020                 : }
    3021                 : 
    3022                 : llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
    3023               42:                                      const ObjCInterfaceDecl *ID) {
    3024               42:   LazySymbols.insert(ID->getIdentifier());
    3025                 : 
    3026               42:   llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
    3027                 : 
                       33: branch 0 taken
                        9: branch 1 taken
    3028               42:   if (!Entry) {
    3029                 :     llvm::Constant *Casted =
    3030                 :       llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
    3031               33:                                      ObjCTypes.ClassPtrTy);
    3032                 :     Entry =
    3033                 :       CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
    3034                 :                         "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
    3035               33:                         4, true);
    3036                 :   }
    3037                 : 
    3038               42:   return Builder.CreateLoad(Entry, "tmp");
    3039                 : }
    3040                 : 
    3041              200: llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) {
    3042              200:   llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
    3043                 : 
                      114: branch 0 taken
                       86: branch 1 taken
    3044              200:   if (!Entry) {
    3045                 :     llvm::Constant *Casted =
    3046                 :       llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
    3047              114:                                      ObjCTypes.SelectorPtrTy);
    3048                 :     Entry =
    3049                 :       CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
    3050                 :                         "__OBJC,__message_refs,literal_pointers,no_dead_strip",
    3051              114:                         4, true);
    3052                 :   }
    3053                 : 
    3054              200:   return Builder.CreateLoad(Entry, "tmp");
    3055                 : }
    3056                 : 
    3057              730: llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
    3058              730:   llvm::GlobalVariable *&Entry = ClassNames[Ident];
    3059                 : 
                      351: branch 0 taken
                      379: branch 1 taken
    3060              730:   if (!Entry)
    3061                 :     Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
    3062                 :                           llvm::ConstantArray::get(VMContext,
    3063                 :                                                    Ident->getNameStart()),
    3064                 :                               "__TEXT,__cstring,cstring_literals",
    3065              351:                               1, true);
    3066                 : 
    3067              730:   return getConstantGEP(VMContext, Entry, 0, 0);
    3068                 : }
    3069                 : 
    3070                 : /// GetIvarLayoutName - Returns a unique constant for the given
    3071                 : /// ivar layout bitmap.
    3072                 : llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
    3073               84:                                        const ObjCCommonTypesHelper &ObjCTypes) {
    3074               84:   return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
    3075                 : }
    3076                 : 
    3077              154: static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
                       20: branch 1 taken
                      134: branch 2 taken
    3078              154:   if (FQT.isObjCGCStrong())
    3079               20:     return Qualifiers::Strong;
    3080                 : 
                       18: branch 1 taken
                      116: branch 2 taken
    3081              134:   if (FQT.isObjCGCWeak())
    3082               18:     return Qualifiers::Weak;
    3083                 : 
                       64: branch 2 taken
                       52: branch 3 taken
                        0: branch 6 not taken
                       64: branch 7 taken
                       52: branch 8 taken
                       64: branch 9 taken
    3084              116:   if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
    3085               52:     return Qualifiers::Strong;
    3086                 : 
                       26: branch 2 taken
                       38: branch 3 taken
    3087               64:   if (const PointerType *PT = FQT->getAs<PointerType>())
    3088               26:     return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
    3089                 : 
    3090               38:   return Qualifiers::GCNone;
    3091                 : }
    3092                 : 
    3093                 : void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
    3094                 :                                                 unsigned int BytePos,
    3095                 :                                                 bool ForStrongLayout,
    3096               26:                                                 bool &HasUnion) {
    3097               26:   const RecordDecl *RD = RT->getDecl();
    3098                 :   // FIXME - Use iterator.
    3099               26:   llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
    3100               26:   const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
    3101                 :   const llvm::StructLayout *RecLayout =
    3102               26:     CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
    3103                 : 
    3104                 :   BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
    3105               26:                       ForStrongLayout, HasUnion);
    3106               26: }
    3107                 : 
    3108                 : void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
    3109                 :                              const llvm::StructLayout *Layout,
    3110                 :                              const RecordDecl *RD,
    3111                 :                              const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
    3112                 :                              unsigned int BytePos, bool ForStrongLayout,
    3113               64:                              bool &HasUnion) {
                       26: branch 0 taken
                       38: branch 1 taken
                        0: branch 3 not taken
                       26: branch 4 taken
    3114               64:   bool IsUnion = (RD && RD->isUnion());
    3115               64:   uint64_t MaxUnionIvarSize = 0;
    3116               64:   uint64_t MaxSkippedUnionIvarSize = 0;
    3117               64:   FieldDecl *MaxField = 0;
    3118               64:   FieldDecl *MaxSkippedField = 0;
    3119               64:   FieldDecl *LastFieldBitfield = 0;
    3120               64:   uint64_t MaxFieldOffset = 0;
    3121               64:   uint64_t MaxSkippedFieldOffset = 0;
    3122               64:   uint64_t LastBitfieldOffset = 0;
    3123                 : 
                        0: branch 1 not taken
                       64: branch 2 taken
    3124               64:   if (RecFields.empty())
    3125                0:     return;
    3126               64:   unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
    3127               64:   unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
    3128                 : 
                      192: branch 1 taken
                       64: branch 2 taken
    3129              256:   for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
    3130              192:     FieldDecl *Field = RecFields[i];
    3131                 :     uint64_t FieldOffset;
                       74: branch 0 taken
                      118: branch 1 taken
    3132              192:     if (RD) {
                       32: branch 1 taken
                       42: branch 2 taken
    3133               74:       if (Field->isBitField()) {
    3134               32:         CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field);
    3135                 : 
    3136                 :         const llvm::Type *Ty =
    3137               32:           CGM.getTypes().ConvertTypeForMemRecursive(Field->getType());
    3138                 :         uint64_t TypeSize =
    3139               32:           CGM.getTypes().getTargetData().getTypeAllocSize(Ty);
    3140               32:         FieldOffset = Info.FieldNo * TypeSize;
    3141                 :       } else
    3142                 :         FieldOffset =
    3143               42:           Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
    3144                 :     } else
    3145              118:       FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field));
    3146                 : 
    3147                 :     // Skip over unnamed or bitfields
                      192: branch 1 taken
                        0: branch 2 not taken
                       38: branch 4 taken
                      154: branch 5 taken
                       38: branch 6 taken
                      154: branch 7 taken
    3148              192:     if (!Field->getIdentifier() || Field->isBitField()) {
    3149               38:       LastFieldBitfield = Field;
    3150               38:       LastBitfieldOffset = FieldOffset;
    3151               38:       continue;
    3152                 :     }
    3153                 : 
    3154              154:     LastFieldBitfield = 0;
    3155              154:     QualType FQT = Field->getType();
                      136: branch 2 taken
                       18: branch 3 taken
                        0: branch 6 not taken
                      136: branch 7 taken
                       18: branch 8 taken
                      136: branch 9 taken
    3156              154:     if (FQT->isRecordType() || FQT->isUnionType()) {
                        0: branch 2 not taken
                       18: branch 3 taken
    3157               18:       if (FQT->isUnionType())
    3158                0:         HasUnion = true;
    3159                 : 
    3160                 :       BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
    3161                 :                                 BytePos + FieldOffset,
    3162               18:                                 ForStrongLayout, HasUnion);
    3163               18:       continue;
    3164                 :     }
    3165                 : 
                       10: branch 2 taken
                      126: branch 3 taken
    3166              136:     if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
    3167                 :       const ConstantArrayType *CArray =
    3168               10:         dyn_cast_or_null<ConstantArrayType>(Array);
    3169               10:       uint64_t ElCount = CArray->getSize().getZExtValue();
                        0: branch 0 not taken
                       10: branch 1 taken
    3170               10:       assert(CArray && "only array with known element size is supported");
    3171               10:       FQT = CArray->getElementType();
                        6: branch 2 taken
                       10: branch 3 taken
    3172               22:       while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
    3173                 :         const ConstantArrayType *CArray =
    3174                6:           dyn_cast_or_null<ConstantArrayType>(Array);
    3175                6:         ElCount *= CArray->getSize().getZExtValue();
    3176                6:         FQT = CArray->getElementType();
    3177                 :       }
    3178                 : 
    3179                 :       assert(!FQT->isUnionType() &&
                       10: branch 2 taken
                        0: branch 3 not taken
    3180               10:              "layout for array of unions not supported");
                        8: branch 2 taken
                        2: branch 3 taken
    3181               10:       if (FQT->isRecordType()) {
    3182                8:         int OldIndex = IvarsInfo.size() - 1;
    3183                8:         int OldSkIndex = SkipIvars.size() -1;
    3184                 : 
    3185                8:         const RecordType *RT = FQT->getAs<RecordType>();
    3186                 :         BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
    3187                8:                                   ForStrongLayout, HasUnion);
    3188                 : 
    3189                 :         // Replicate layout information for each array element. Note that
    3190                 :         // one element is already done.
    3191                8:         uint64_t ElIx = 1;
                       10: branch 1 taken
                        8: branch 2 taken
    3192               26:         for (int FirstIndex = IvarsInfo.size() - 1,
    3193                8:                FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
    3194               10:           uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
                        4: branch 0 taken
                       10: branch 1 taken
    3195               14:           for (int i = OldIndex+1; i <= FirstIndex; ++i)
    3196                 :             IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
    3197                4:                                         IvarsInfo[i].ivar_size));
                       16: branch 0 taken
                       10: branch 1 taken
    3198               26:           for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
    3199                 :             SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
    3200               16:                                         SkipIvars[i].ivar_size));
    3201                 :         }
    3202                8:         continue;
    3203                 :       }
    3204                 :     }
    3205                 :     // At this point, we are done with Record/Union and array there of.
    3206                 :     // For other arrays we are down to its element type.
    3207              128:     Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
    3208                 : 
    3209              128:     unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
                       64: branch 0 taken
                       64: branch 1 taken
                       28: branch 2 taken
                       36: branch 3 taken
                       64: branch 4 taken
                       28: branch 5 taken
                        9: branch 6 taken
                       55: branch 7 taken
    3210              173:     if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
    3211                 :         || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
                        0: branch 0 not taken
                       45: branch 1 taken
    3212               45:       if (IsUnion) {
    3213                0:         uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
                        0: branch 0 not taken
                        0: branch 1 not taken
    3214                0:         if (UnionIvarSize > MaxUnionIvarSize) {
    3215                0:           MaxUnionIvarSize = UnionIvarSize;
    3216                0:           MaxField = Field;
    3217                0:           MaxFieldOffset = FieldOffset;
    3218                 :         }
    3219                 :       } else {
    3220                 :         IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
    3221               45:                                     FieldSize / WordSizeInBits));
    3222                 :       }
                       28: branch 0 taken
                       55: branch 1 taken
                        9: branch 2 taken
                       19: branch 3 taken
                        0: branch 4 not taken
                        9: branch 5 taken
                       55: branch 6 taken
                        0: branch 7 not taken
                       55: branch 8 taken
                        0: branch 9 not taken
    3223               83:     } else if ((ForStrongLayout &&
    3224                 :                 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
    3225                 :                || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
                        0: branch 0 not taken
                       83: branch 1 taken
    3226               83:       if (IsUnion) {
    3227                 :         // FIXME: Why the asymmetry? We divide by word size in bits on other
    3228                 :         // side.
    3229                0:         uint64_t UnionIvarSize = FieldSize;
                        0: branch 0 not taken
                        0: branch 1 not taken
    3230                0:         if (UnionIvarSize > MaxSkippedUnionIvarSize) {
    3231                0:           MaxSkippedUnionIvarSize = UnionIvarSize;
    3232                0:           MaxSkippedField = Field;
    3233                0:           MaxSkippedFieldOffset = FieldOffset;
    3234                 :         }
    3235                 :       } else {
    3236                 :         // FIXME: Why the asymmetry, we divide by byte size in bits here?
    3237                 :         SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
    3238               83:                                     FieldSize / ByteSizeInBits));
    3239                 :       }
    3240                 :     }
    3241                 :   }
    3242                 : 
                        4: branch 0 taken
                       60: branch 1 taken
    3243               64:   if (LastFieldBitfield) {
    3244                 :     // Last field was a bitfield. Must update skip info.
    3245                4:     Expr *BitWidth = LastFieldBitfield->getBitWidth();
    3246                 :     uint64_t BitFieldSize =
    3247                4:       BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
    3248                4:     GC_IVAR skivar;
    3249                4:     skivar.ivar_bytepos = BytePos + LastBitfieldOffset;
    3250                 :     skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
    3251                4:       + ((BitFieldSize % ByteSizeInBits) != 0);
    3252                4:     SkipIvars.push_back(skivar);
    3253                 :   }
    3254                 : 
                        0: branch 0 not taken
                       64: branch 1 taken
    3255               64:   if (MaxField)
    3256                 :     IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
    3257                0:                                 MaxUnionIvarSize));
                        0: branch 0 not taken
                       64: branch 1 taken
    3258               64:   if (MaxSkippedField)
    3259                 :     SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
    3260                0:                                 MaxSkippedUnionIvarSize));
    3261                 : }
    3262                 : 
    3263                 : /// BuildIvarLayout - Builds ivar layout bitmap for the class
    3264                 : /// implementation for the __strong or __weak case.
    3265                 : /// The layout map displays which words in ivar list must be skipped
    3266                 : /// and which must be scanned by GC (see below). String is built of bytes.
    3267                 : /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
    3268                 : /// of words to skip and right nibble is count of words to scan. So, each
    3269                 : /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
    3270                 : /// represented by a 0x00 byte which also ends the string.
    3271                 : /// 1. when ForStrongLayout is true, following ivars are scanned:
    3272                 : /// - id, Class
    3273                 : /// - object *
    3274                 : /// - __strong anything
    3275                 : ///
    3276                 : /// 2. When ForStrongLayout is false, following ivars are scanned:
    3277                 : /// - __weak anything
    3278                 : ///
    3279                 : llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
    3280                 :   const ObjCImplementationDecl *OMD,
    3281              310:   bool ForStrongLayout) {
    3282              310:   bool hasUnion = false;
    3283                 : 
    3284                 :   unsigned int WordsToScan, WordsToSkip;
    3285              310:   const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
                      272: branch 2 taken
                       38: branch 3 taken
    3286              310:   if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
    3287              272:     return llvm::Constant::getNullValue(PtrTy);
    3288                 : 
    3289               38:   llvm::SmallVector<FieldDecl*, 32> RecFields;
    3290               38:   const ObjCInterfaceDecl *OI = OMD->getClassInterface();
    3291               38:   CGM.getContext().CollectObjCIvars(OI, RecFields);
    3292                 : 
    3293                 :   // Add this implementations synthesized ivars.
    3294               38:   llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
    3295               38:   CGM.getContext().CollectSynthesizedIvars(OI, Ivars);
                       20: branch 1 taken
                       38: branch 2 taken
    3296               58:   for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
    3297               20:     RecFields.push_back(cast<FieldDecl>(Ivars[k]));
    3298                 : 
                        0: branch 1 not taken
                       38: branch 2 taken
    3299               38:   if (RecFields.empty())
    3300                0:     return llvm::Constant::getNullValue(PtrTy);
    3301                 : 
    3302               38:   SkipIvars.clear();
    3303               38:   IvarsInfo.clear();
    3304                 : 
    3305               38:   BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
                       18: branch 1 taken
                       20: branch 2 taken
    3306               38:   if (IvarsInfo.empty())
    3307               18:     return llvm::Constant::getNullValue(PtrTy);
    3308                 : 
    3309                 :   // Sort on byte position in case we encounterred a union nested in
    3310                 :   // the ivar list.
                        0: branch 0 not taken
                       20: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                       20: branch 6 taken
    3311               20:   if (hasUnion && !IvarsInfo.empty())
    3312                0:     std::sort(IvarsInfo.begin(), IvarsInfo.end());
                        0: branch 0 not taken
                       20: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                       20: branch 6 taken
    3313               20:   if (hasUnion && !SkipIvars.empty())
    3314                0:     std::sort(SkipIvars.begin(), SkipIvars.end());
    3315                 : 
    3316                 :   // Build the string of skip/scan nibbles
    3317               20:   llvm::SmallVector<SKIP_SCAN, 32> SkipScanIvars;
    3318                 :   unsigned int WordSize =
    3319               20:     CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
                       12: branch 1 taken
                        8: branch 2 taken
    3320               20:   if (IvarsInfo[0].ivar_bytepos == 0) {
    3321               12:     WordsToSkip = 0;
    3322               12:     WordsToScan = IvarsInfo[0].ivar_size;
    3323                 :   } else {
    3324                8:     WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
    3325                8:     WordsToScan = IvarsInfo[0].ivar_size;
    3326                 :   }
                       29: branch 1 taken
                       20: branch 2 taken
    3327               49:   for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
    3328                 :     unsigned int TailPrevGCObjC =
    3329               29:       IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
                       26: branch 1 taken
                        3: branch 2 taken
    3330               29:     if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
    3331                 :       // consecutive 'scanned' object pointers.
    3332               26:       WordsToScan += IvarsInfo[i].ivar_size;
    3333                 :     } else {
    3334                 :       // Skip over 'gc'able object pointer which lay over each other.
                        0: branch 1 not taken
                        3: branch 2 taken
    3335                3:       if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
    3336                0:         continue;
    3337                 :       // Must skip over 1 or more words. We save current skip/scan values
    3338                 :       //  and start a new pair.
    3339                3:       SKIP_SCAN SkScan;
    3340                3:       SkScan.skip = WordsToSkip;
    3341                3:       SkScan.scan = WordsToScan;
    3342                3:       SkipScanIvars.push_back(SkScan);
    3343                 : 
    3344                 :       // Skip the hole.
    3345                3:       SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
    3346                3:       SkScan.scan = 0;
    3347                3:       SkipScanIvars.push_back(SkScan);
    3348                3:       WordsToSkip = 0;
    3349                3:       WordsToScan = IvarsInfo[i].ivar_size;
    3350                 :     }
    3351                 :   }
                       20: branch 0 taken
                        0: branch 1 not taken
    3352               20:   if (WordsToScan > 0) {
    3353               20:     SKIP_SCAN SkScan;
    3354               20:     SkScan.skip = WordsToSkip;
    3355               20:     SkScan.scan = WordsToScan;
    3356               20:     SkipScanIvars.push_back(SkScan);
    3357                 :   }
    3358                 : 
                       10: branch 1 taken
                       10: branch 2 taken
    3359               20:   if (!SkipIvars.empty()) {
    3360               10:     unsigned int LastIndex = SkipIvars.size()-1;
    3361                 :     int LastByteSkipped =
    3362               10:       SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
    3363               10:     LastIndex = IvarsInfo.size()-1;
    3364                 :     int LastByteScanned =
    3365                 :       IvarsInfo[LastIndex].ivar_bytepos +
    3366               10:       IvarsInfo[LastIndex].ivar_size * WordSize;
    3367                 :     // Compute number of bytes to skip at the tail end of the last ivar scanned.
                        6: branch 0 taken
                        4: branch 1 taken
    3368               10:     if (LastByteSkipped > LastByteScanned) {
    3369                6:       unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
    3370                6:       SKIP_SCAN SkScan;
    3371                6:       SkScan.skip = TotalWords - (LastByteScanned/WordSize);
    3372                6:       SkScan.scan = 0;
    3373                6:       SkipScanIvars.push_back(SkScan);
    3374                 :     }
    3375                 :   }
    3376                 :   // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
    3377                 :   // as 0xMN.
    3378               20:   int SkipScan = SkipScanIvars.size()-1;
                       29: branch 0 taken
                       20: branch 1 taken
    3379               49:   for (int i = 0; i <= SkipScan; i++) {
                       11: branch 0 taken
                       18: branch 1 taken
                        9: branch 3 taken
                        2: branch 4 taken
                        3: branch 6 taken
                        6: branch 7 taken
                        3: branch 9 taken
                        0: branch 10 not taken
                        3: branch 12 taken
                        0: branch 13 not taken
                        3: branch 14 taken
                       26: branch 15 taken
    3380               29:     if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
    3381                 :         && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
    3382                 :       // 0xM0 followed by 0x0N detected.
    3383                3:       SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
                        1: branch 0 taken
                        3: branch 1 taken
    3384                4:       for (int j = i+1; j < SkipScan; j++)
    3385                1:         SkipScanIvars[j] = SkipScanIvars[j+1];
    3386                3:       --SkipScan;
    3387                 :     }
    3388                 :   }
    3389                 : 
    3390                 :   // Generate the string.
    3391               20:   std::string BitMap;
                       29: branch 0 taken
                       20: branch 1 taken
    3392               49:   for (int i = 0; i <= SkipScan; i++) {
    3393                 :     unsigned char byte;
    3394               29:     unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
    3395               29:     unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
    3396               29:     unsigned int skip_big  = SkipScanIvars[i].skip / 0xf;
    3397               29:     unsigned int scan_big  = SkipScanIvars[i].scan / 0xf;
    3398                 : 
    3399                 :     // first skip big.
                        0: branch 0 not taken
                       29: branch 1 taken
    3400               29:     for (unsigned int ix = 0; ix < skip_big; ix++)
    3401                0:       BitMap += (unsigned char)(0xf0);
    3402                 : 
    3403                 :     // next (skip small, scan)
                       17: branch 0 taken
                       12: branch 1 taken
    3404               29:     if (skip_small) {
    3405               17:       byte = skip_small << 4;
                        0: branch 0 not taken
                       17: branch 1 taken
    3406               17:       if (scan_big > 0) {
    3407                0:         byte |= 0xf;
    3408                0:         --scan_big;
                       11: branch 0 taken
                        6: branch 1 taken
    3409               17:       } else if (scan_small) {
    3410               11:         byte |= scan_small;
    3411               11:         scan_small = 0;
    3412                 :       }
    3413               17:       BitMap += byte;
    3414                 :     }
    3415                 :     // next scan big
                        1: branch 0 taken
                       29: branch 1 taken
    3416               30:     for (unsigned int ix = 0; ix < scan_big; ix++)
    3417                1:       BitMap += (unsigned char)(0x0f);
    3418                 :     // last scan small
                       12: branch 0 taken
                       17: branch 1 taken
    3419               29:     if (scan_small) {
    3420               12:       byte = scan_small;
    3421               12:       BitMap += byte;
    3422                 :     }
    3423                 :   }
    3424                 :   // null terminate string.
    3425               20:   unsigned char zero = 0;
    3426               20:   BitMap += zero;
    3427                 : 
                        0: branch 1 not taken
                       20: branch 2 taken
    3428               20:   if (CGM.getLangOptions().ObjCGCBitmapPrint) {
    3429                 :     printf("\n%s ivar layout for class '%s': ",
    3430                 :            ForStrongLayout ? "strong" : "weak",
                        0: branch 2 not taken
                        0: branch 3 not taken
    3431                0:            OMD->getClassInterface()->getNameAsCString());
    3432                0:     const unsigned char *s = (unsigned char*)BitMap.c_str();
                        0: branch 1 not taken
                        0: branch 2 not taken
    3433                0:     for (unsigned i = 0; i < BitMap.size(); i++)
                        0: branch 0 not taken
                        0: branch 1 not taken
    3434                0:       if (!(s[i] & 0xf0))
                        0: branch 0 not taken
                        0: branch 1 not taken
    3435                0:         printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
    3436                 :       else
                        0: branch 0 not taken
                        0: branch 1 not taken
    3437                0:         printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
    3438                0:     printf("\n");
    3439                 :   }
    3440                 :   llvm::GlobalVariable * Entry =
    3441                 :     CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
    3442                 :                       llvm::ConstantArray::get(VMContext, BitMap.c_str()),
    3443                 :                       "__TEXT,__cstring,cstring_literals",
    3444               20:                       1, true);
    3445               20:   return getConstantGEP(VMContext, Entry, 0, 0);
    3446                 : }
    3447                 : 
    3448              667: llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
    3449              667:   llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
    3450                 : 
    3451                 :   // FIXME: Avoid std::string copying.
                      495: branch 0 taken
                      172: branch 1 taken
    3452              667:   if (!Entry)
    3453                 :     Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
    3454                 :                         llvm::ConstantArray::get(VMContext, Sel.getAsString()),
    3455                 :                               "__TEXT,__cstring,cstring_literals",
    3456              495:                               1, true);
    3457                 : 
    3458              667:   return getConstantGEP(VMContext, Entry, 0, 0);
    3459                 : }
    3460                 : 
    3461                 : // FIXME: Merge into a single cstring creation function.
    3462              212: llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
    3463              212:   return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
    3464                 : }
    3465                 : 
    3466                 : // FIXME: Merge into a single cstring creation function.
    3467                0: llvm::Constant *CGObjCCommonMac::GetMethodVarName(const std::string &Name) {
    3468                0:   return GetMethodVarName(&CGM.getContext().Idents.get(Name));
    3469                 : }
    3470                 : 
    3471              212: llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
    3472              212:   std::string TypeStr;
    3473              212:   CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
    3474                 : 
    3475              212:   llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
    3476                 : 
                      142: branch 0 taken
                       70: branch 1 taken
    3477              212:   if (!Entry)
    3478                 :     Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
    3479                 :                               llvm::ConstantArray::get(VMContext, TypeStr),
    3480                 :                               "__TEXT,__cstring,cstring_literals",
    3481              142:                               1, true);
    3482                 : 
    3483              212:   return getConstantGEP(VMContext, Entry, 0, 0);
    3484                 : }
    3485                 : 
    3486              322: llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) {
    3487              322:   std::string TypeStr;
    3488                 :   CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
    3489              322:                                                 TypeStr);
    3490                 : 
    3491              322:   llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
    3492                 : 
                      154: branch 0 taken
                      168: branch 1 taken
    3493              322:   if (!Entry)
    3494                 :     Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
    3495                 :                               llvm::ConstantArray::get(VMContext, TypeStr),
    3496                 :                               "__TEXT,__cstring,cstring_literals",
    3497              154:                               1, true);
    3498                 : 
    3499              322:   return getConstantGEP(VMContext, Entry, 0, 0);
    3500                 : }
    3501                 : 
    3502                 : // FIXME: Merge into a single cstring creation function.
    3503              188: llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
    3504              188:   llvm::GlobalVariable *&Entry = PropertyNames[Ident];
    3505                 : 
                      160: branch 0 taken
                       28: branch 1 taken
    3506              188:   if (!Entry)
    3507                 :     Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
    3508                 :                           llvm::ConstantArray::get(VMContext,
    3509                 :                                                    Ident->getNameStart()),
    3510                 :                               "__TEXT,__cstring,cstring_literals",
    3511              160:                               1, true);
    3512                 : 
    3513              188:   return getConstantGEP(VMContext, Entry, 0, 0);
    3514                 : }
    3515                 : 
    3516                 : // FIXME: Merge into a single cstring creation function.
    3517                 : // FIXME: This Decl should be more precise.
    3518                 : llvm::Constant *
    3519                 : CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
    3520               94:                                        const Decl *Container) {
    3521               94:   std::string TypeStr;
    3522               94:   CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
    3523               94:   return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
    3524                 : }
    3525                 : 
    3526                 : void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
    3527                 :                                        const ObjCContainerDecl *CD,
    3528              284:                                        llvm::SmallVectorImpl<char> &Name) {
    3529              284:   llvm::raw_svector_ostream OS(Name);
                        0: branch 0 not taken
                      284: branch 1 taken
    3530              284:   assert (CD && "Missing container decl in GetNameForMethod");
    3531                 :   OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
                      243: branch 2 taken
                       41: branch 3 taken
    3532              284:      << '[' << CD->getName();
                       14: branch 0 taken
                      270: branch 1 taken
    3533              284:   if (const ObjCCategoryImplDecl *CID =
    3534              284:       dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
    3535               14:     OS << '(' << CID->getNameAsString() << ')';
    3536              284:   OS << ' ' << D->getSelector().getAsString() << ']';
    3537              284: }
    3538                 : 
    3539              109: void CGObjCMac::FinishModule() {
    3540              109:   EmitModuleInfo();
    3541                 : 
    3542                 :   // Emit the dummy bodies for any protocols which were referenced but
    3543                 :   // never defined.
                       19: branch 4 taken
                      109: branch 5 taken
    3544              113:   for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
    3545              109:          I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
                       15: branch 2 taken
                        4: branch 3 taken
    3546               19:     if (I->second->hasInitializer())
    3547               15:       continue;
    3548                 : 
    3549                4:     std::vector<llvm::Constant*> Values(5);
    3550                4:     Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
    3551                4:     Values[1] = GetClassName(I->first);
    3552                4:     Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
    3553                 :     Values[3] = Values[4] =
    3554                4:       llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
    3555                4:     I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
    3556                 :     I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
    3557                4:                                                         Values));
    3558                4:     CGM.AddUsedGlobal(I->second);
    3559                 :   }
    3560                 : 
    3561                 :   // Add assembler directives to add lazy undefined symbol references
    3562                 :   // for classes which are referenced but not defined. This is
    3563                 :   // important for correct linker interaction.
    3564                 :   //
    3565                 :   // FIXME: It would be nice if we had an LLVM construct for this.
                       65: branch 1 taken
                       44: branch 2 taken
                       29: branch 4 taken
                       36: branch 5 taken
                       73: branch 6 taken
                       36: branch 7 taken
    3566              109:   if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
    3567               73:     llvm::SmallString<256> Asm;
    3568               73:     Asm += CGM.getModule().getModuleInlineAsm();
                        0: branch 1 not taken
                       73: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                       73: branch 7 taken
    3569               73:     if (!Asm.empty() && Asm.back() != '\n')
    3570                0:       Asm += '\n';
    3571                 : 
    3572               73:     llvm::raw_svector_ostream OS(Asm);
                       93: branch 3 taken
                       73: branch 4 taken
    3573              239:     for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
    3574               73:            e = LazySymbols.end(); I != e; ++I)
    3575               93:       OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
                      113: branch 3 taken
                       73: branch 4 taken
    3576              259:     for (llvm::SetVector<IdentifierInfo*>