zcov: / lib/Sema/SemaDeclObjC.cpp


Files: 1 Branches Taken: 86.0% 986 / 1146
Generated: 2010-02-10 01:31 Branches Executed: 96.5% 1106 / 1146
Line Coverage: 93.9% 1161 / 1236


Programs: 2 Runs 3018


       1                 : //===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
       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 file implements semantic analysis for Objective C declarations.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "Sema.h"
      15                 : #include "Lookup.h"
      16                 : #include "clang/Sema/ExternalSemaSource.h"
      17                 : #include "clang/AST/Expr.h"
      18                 : #include "clang/AST/ASTContext.h"
      19                 : #include "clang/AST/DeclObjC.h"
      20                 : #include "clang/Parse/DeclSpec.h"
      21                 : using namespace clang;
      22                 : 
      23                 : bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
      24                 :                                             ObjCMethodDecl *GetterMethod,
      25              628:                                             SourceLocation Loc) {
                      182: branch 0 taken
                      446: branch 1 taken
                        6: branch 5 taken
                      176: branch 6 taken
                        6: branch 7 taken
                      622: branch 8 taken
      26              628:   if (GetterMethod &&
      27                 :       GetterMethod->getResultType() != property->getType()) {
      28                6:     AssignConvertType result = Incompatible;
                        5: branch 3 taken
                        1: branch 4 taken
      29                6:     if (property->getType()->isObjCObjectPointerType())
      30                5:       result = CheckAssignmentConstraints(GetterMethod->getResultType(), property->getType());
                        4: branch 0 taken
                        2: branch 1 taken
      31                6:     if (result != Compatible) {
      32                 :       Diag(Loc, diag::warn_accessor_property_type_mismatch)
      33                 :         << property->getDeclName()
      34                4:         << GetterMethod->getSelector();
      35                4:       Diag(GetterMethod->getLocation(), diag::note_declared_at);
      36                4:       return true;
      37                 :     }
      38                 :   }
      39              624:   return false;
      40                 : }
      41                 : 
      42                 : /// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
      43                 : /// and user declared, in the method definition's AST.
      44              917: void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
                      917: branch 1 taken
                        0: branch 2 not taken
      45              917:   assert(getCurMethodDecl() == 0 && "Method parsing confused");
      46              917:   ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D.getAs<Decl>());
      47                 : 
      48                 :   // If we don't have a valid method decl, simply return.
                        4: branch 0 taken
                      913: branch 1 taken
      49              917:   if (!MDecl)
      50                4:     return;
      51                 : 
      52              913:   CurFunctionNeedsScopeChecking = false;
      53                 : 
      54                 :   // Allow the rest of sema to find private method decl implementations.
                      735: branch 1 taken
                      178: branch 2 taken
      55              913:   if (MDecl->isInstanceMethod())
      56              735:     AddInstanceMethodToGlobalPool(MDecl);
      57                 :   else
      58              178:     AddFactoryMethodToGlobalPool(MDecl);
      59                 : 
      60                 :   // Allow all of Sema to see that we are entering a method definition.
                      913: branch 0 taken
                        0: branch 1 not taken
      61              913:   PushDeclContext(FnBodyScope, MDecl);
      62                 : 
      63                 :   // Create Decl objects for each parameter, entrring them in the scope for
      64                 :   // binding to their use.
      65                 : 
      66                 :   // Insert the invisible arguments, self and _cmd!
      67              913:   MDecl->createImplicitParams(Context, MDecl->getClassInterface());
      68                 : 
      69              913:   PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
      70              913:   PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
      71                 : 
      72                 :   // Introduce all of the other parameters into this scope.
                      416: branch 1 taken
                      913: branch 2 taken
      73             2242:   for (ObjCMethodDecl::param_iterator PI = MDecl->param_begin(),
      74              913:        E = MDecl->param_end(); PI != E; ++PI)
                      416: branch 1 taken
                        0: branch 2 not taken
      75              416:     if ((*PI)->getIdentifier())
      76              416:       PushOnScopeChains(*PI, FnBodyScope);
      77                 : }
      78                 : 
      79                 : Sema::DeclPtrTy Sema::
      80                 : ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
      81                 :                          IdentifierInfo *ClassName, SourceLocation ClassLoc,
      82                 :                          IdentifierInfo *SuperName, SourceLocation SuperLoc,
      83                 :                          const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs,
      84                 :                          const SourceLocation *ProtoLocs, 
      85             1554:                          SourceLocation EndProtoLoc, AttributeList *AttrList) {
                        0: branch 0 not taken
                     1554: branch 1 taken
      86             1554:   assert(ClassName && "Missing class identifier");
      87                 : 
      88                 :   // Check for another declaration kind with the same name.
      89             1554:   NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
                       94: branch 0 taken
                     1460: branch 1 taken
                        0: branch 3 not taken
                       94: branch 4 taken
                        0: branch 5 not taken
                     1554: branch 6 taken
      90             1554:   if (PrevDecl && PrevDecl->isTemplateParameter()) {
      91                 :     // Maybe we will complain about the shadowed template parameter.
      92                0:     DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
      93                 :     // Just pretend that we didn't see the previous declaration.
      94                0:     PrevDecl = 0;
      95                 :   }
      96                 : 
                       94: branch 0 taken
                     1460: branch 1 taken
                        2: branch 3 taken
                       92: branch 4 taken
                        2: branch 5 taken
                     1552: branch 6 taken
      97             1554:   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
      98                2:     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
      99                2:     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
     100                 :   }
     101                 : 
     102             1554:   ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
                       92: branch 0 taken
                     1462: branch 1 taken
     103             1554:   if (IDecl) {
     104                 :     // Class already seen. Is it a forward declaration?
                        6: branch 1 taken
                       86: branch 2 taken
     105               92:     if (!IDecl->isForwardDecl()) {
     106                6:       IDecl->setInvalidDecl();
     107                6:       Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
     108                6:       Diag(IDecl->getLocation(), diag::note_previous_definition);
     109                 : 
     110                 :       // Return the previous class interface.
     111                 :       // FIXME: don't leak the objects passed in!
     112                6:       return DeclPtrTy::make(IDecl);
     113                 :     } else {
     114               86:       IDecl->setLocation(AtInterfaceLoc);
     115               86:       IDecl->setForwardDecl(false);
     116               86:       IDecl->setClassLoc(ClassLoc);
     117                 :       
     118                 :       // Since this ObjCInterfaceDecl was created by a forward declaration,
     119                 :       // we now add it to the DeclContext since it wasn't added before
     120                 :       // (see ActOnForwardClassDeclaration).
     121               86:       CurContext->addDecl(IDecl);
     122                 :       
                        0: branch 0 not taken
                       86: branch 1 taken
     123               86:       if (AttrList)
     124                0:         ProcessDeclAttributeList(TUScope, IDecl, AttrList);
     125                 :     }
     126                 :   } else {
     127                 :     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
     128             1462:                                       ClassName, ClassLoc);
                       14: branch 0 taken
                     1448: branch 1 taken
     129             1462:     if (AttrList)
     130               14:       ProcessDeclAttributeList(TUScope, IDecl, AttrList);
     131                 : 
     132             1462:     PushOnScopeChains(IDecl, TUScope);
     133                 :   }
     134                 : 
                      727: branch 0 taken
                      821: branch 1 taken
     135             1548:   if (SuperName) {
     136                 :     // Check if a different kind of symbol declared in this scope.
     137              727:     PrevDecl = LookupSingleName(TUScope, SuperName, LookupOrdinaryName);
     138                 : 
                        4: branch 0 taken
                      723: branch 1 taken
     139              727:     if (!PrevDecl) {
     140                 :       // Try to correct for a typo in the superclass name.
     141                4:       LookupResult R(*this, SuperName, SuperLoc, LookupOrdinaryName);
                        2: branch 1 taken
                        2: branch 2 taken
                        2: branch 4 taken
                        0: branch 5 not taken
                        2: branch 6 taken
                        2: branch 7 taken
     142                4:       if (CorrectTypo(R, TUScope, 0) &&
     143                 :           (PrevDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
     144                 :         Diag(SuperLoc, diag::err_undef_superclass_suggest)
     145                2:           << SuperName << ClassName << PrevDecl->getDeclName();
     146                 :         Diag(PrevDecl->getLocation(), diag::note_previous_decl)
     147                2:           << PrevDecl->getDeclName();
     148                4:       }
     149                 :     }
     150                 : 
                        1: branch 0 taken
                      726: branch 1 taken
     151              727:     if (PrevDecl == IDecl) {
     152                 :       Diag(SuperLoc, diag::err_recursive_superclass)
     153                1:         << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
     154                1:       IDecl->setLocEnd(ClassLoc);
     155                 :     } else {
     156                 :       ObjCInterfaceDecl *SuperClassDecl =
     157              726:                                 dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
     158                 : 
     159                 :       // Diagnose classes that inherit from deprecated classes.
                      722: branch 0 taken
                        4: branch 1 taken
     160              726:       if (SuperClassDecl)
     161              722:         (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
     162                 : 
                      724: branch 0 taken
                        2: branch 1 taken
                        2: branch 2 taken
                      722: branch 3 taken
     163              726:       if (PrevDecl && SuperClassDecl == 0) {
     164                 :         // The previous declaration was not a class decl. Check if we have a
     165                 :         // typedef. If we do, get the underlying class type.
                        2: branch 1 taken
                        0: branch 2 not taken
     166                2:         if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
     167                2:           QualType T = TDecl->getUnderlyingType();
                        1: branch 2 taken
                        1: branch 3 taken
     168                2:           if (T->isObjCInterfaceType()) {
                        1: branch 3 taken
                        0: branch 4 not taken
     169                1:             if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl())
     170                1:               SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
     171                 :           }
     172                 :         }
     173                 : 
     174                 :         // This handles the following case:
     175                 :         //
     176                 :         // typedef int SuperClass;
     177                 :         // @interface MyClass : SuperClass {} @end
     178                 :         //
                        1: branch 0 taken
                        1: branch 1 taken
     179                2:         if (!SuperClassDecl) {
     180                1:           Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
     181                1:           Diag(PrevDecl->getLocation(), diag::note_previous_definition);
     182                 :         }
     183                 :       }
     184                 : 
                      724: branch 1 taken
                        2: branch 2 taken
     185              726:       if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
                        2: branch 0 taken
                      722: branch 1 taken
     186              724:         if (!SuperClassDecl)
     187                 :           Diag(SuperLoc, diag::err_undef_superclass)
     188                2:             << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
                        4: branch 1 taken
                      718: branch 2 taken
     189              722:         else if (SuperClassDecl->isForwardDecl())
     190                 :           Diag(SuperLoc, diag::err_undef_superclass)
     191                 :             << SuperClassDecl->getDeclName() << ClassName
     192                4:             << SourceRange(AtInterfaceLoc, ClassLoc);
     193                 :       }
     194              726:       IDecl->setSuperClass(SuperClassDecl);
     195              726:       IDecl->setSuperClassLoc(SuperLoc);
     196              726:       IDecl->setLocEnd(SuperLoc);
     197                 :     }
     198                 :   } else { // we have a root class.
     199              821:     IDecl->setLocEnd(ClassLoc);
     200                 :   }
     201                 : 
     202                 :   /// Check then save referenced protocols.
                      418: branch 0 taken
                     1130: branch 1 taken
     203             1548:   if (NumProtoRefs) {
     204                 :     IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
     205              418:                            ProtoLocs, Context);
     206              418:     IDecl->setLocEnd(EndProtoLoc);
     207                 :   }
     208                 : 
     209             1548:   CheckObjCDeclScope(IDecl);
     210             1548:   return DeclPtrTy::make(IDecl);
     211                 : }
     212                 : 
     213                 : /// ActOnCompatiblityAlias - this action is called after complete parsing of
     214                 : /// @compatibility_alias declaration. It sets up the alias relationships.
     215                 : Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
     216                 :                                              IdentifierInfo *AliasName,
     217                 :                                              SourceLocation AliasLocation,
     218                 :                                              IdentifierInfo *ClassName,
     219               10:                                              SourceLocation ClassLocation) {
     220                 :   // Look for previous declaration of alias name
     221               10:   NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, LookupOrdinaryName);
                        2: branch 0 taken
                        8: branch 1 taken
     222               10:   if (ADecl) {
                        0: branch 1 not taken
                        2: branch 2 taken
     223                2:     if (isa<ObjCCompatibleAliasDecl>(ADecl))
     224                0:       Diag(AliasLocation, diag::warn_previous_alias_decl);
     225                 :     else
     226                2:       Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
     227                2:     Diag(ADecl->getLocation(), diag::note_previous_declaration);
     228                2:     return DeclPtrTy();
     229                 :   }
     230                 :   // Check for class declaration
     231                8:   NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
                        2: branch 1 taken
                        6: branch 2 taken
     232                8:   if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
     233                2:     QualType T = TDecl->getUnderlyingType();
                        1: branch 2 taken
                        1: branch 3 taken
     234                2:     if (T->isObjCInterfaceType()) {
                        1: branch 3 taken
                        0: branch 4 not taken
     235                1:       if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl()) {
     236                1:         ClassName = IDecl->getIdentifier();
     237                1:         CDeclU = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
     238                 :       }
     239                 :     }
     240                 :   }
     241                8:   ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
                        2: branch 0 taken
                        6: branch 1 taken
     242                8:   if (CDecl == 0) {
     243                2:     Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
                        1: branch 0 taken
                        1: branch 1 taken
     244                2:     if (CDeclU)
     245                1:       Diag(CDeclU->getLocation(), diag::note_previous_declaration);
     246                2:     return DeclPtrTy();
     247                 :   }
     248                 : 
     249                 :   // Everything checked out, instantiate a new alias declaration AST.
     250                 :   ObjCCompatibleAliasDecl *AliasDecl =
     251                6:     ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl);
     252                 : 
                        5: branch 1 taken
                        1: branch 2 taken
     253                6:   if (!CheckObjCDeclScope(AliasDecl))
     254                5:     PushOnScopeChains(AliasDecl, TUScope);
     255                 : 
     256                6:   return DeclPtrTy::make(AliasDecl);
     257                 : }
     258                 : 
     259                 : void Sema::CheckForwardProtocolDeclarationForCircularDependency(
     260                 :   IdentifierInfo *PName,
     261                 :   SourceLocation &Ploc, SourceLocation PrevLoc,
     262               33:   const ObjCList<ObjCProtocolDecl> &PList) {
                       17: branch 1 taken
                       33: branch 2 taken
     263               83:   for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(),
     264               33:        E = PList.end(); I != E; ++I) {
     265                 : 
                       17: branch 2 taken
                        0: branch 3 not taken
     266               17:     if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier())) {
                        1: branch 1 taken
                       16: branch 2 taken
     267               17:       if (PDecl->getIdentifier() == PName) {
     268                1:         Diag(Ploc, diag::err_protocol_has_circular_dependency);
     269                1:         Diag(PrevLoc, diag::note_previous_definition);
     270                 :       }
     271                 :       CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc,
     272               17:         PDecl->getLocation(), PDecl->getReferencedProtocols());
     273                 :     }
     274                 :   }
     275               33: }
     276                 : 
     277                 : Sema::DeclPtrTy
     278                 : Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
     279                 :                                   IdentifierInfo *ProtocolName,
     280                 :                                   SourceLocation ProtocolLoc,
     281                 :                                   const DeclPtrTy *ProtoRefs,
     282                 :                                   unsigned NumProtoRefs,
     283                 :                                   const SourceLocation *ProtoLocs,
     284                 :                                   SourceLocation EndProtoLoc,
     285              659:                                   AttributeList *AttrList) {
     286                 :   // FIXME: Deal with AttrList.
                        0: branch 0 not taken
                      659: branch 1 taken
     287              659:   assert(ProtocolName && "Missing protocol identifier");
     288              659:   ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolName);
                       18: branch 0 taken
                      641: branch 1 taken
     289              659:   if (PDecl) {
     290                 :     // Protocol already seen. Better be a forward protocol declaration
                        2: branch 1 taken
                       16: branch 2 taken
     291               18:     if (!PDecl->isForwardDecl()) {
     292                2:       Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
     293                2:       Diag(PDecl->getLocation(), diag::note_previous_definition);
     294                 :       // Just return the protocol we already had.
     295                 :       // FIXME: don't leak the objects passed in!
     296                2:       return DeclPtrTy::make(PDecl);
     297                 :     }
     298               16:     ObjCList<ObjCProtocolDecl> PList;
     299               16:     PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
     300                 :     CheckForwardProtocolDeclarationForCircularDependency(
     301               16:       ProtocolName, ProtocolLoc, PDecl->getLocation(), PList);
     302               16:     PList.Destroy(Context);
     303                 : 
     304                 :     // Make sure the cached decl gets a valid start location.
     305               16:     PDecl->setLocation(AtProtoInterfaceLoc);
     306               16:     PDecl->setForwardDecl(false);
     307                 :   } else {
     308                 :     PDecl = ObjCProtocolDecl::Create(Context, CurContext,
     309              641:                                      AtProtoInterfaceLoc,ProtocolName);
     310              641:     PushOnScopeChains(PDecl, TUScope);
     311              641:     PDecl->setForwardDecl(false);
     312                 :   }
                        2: branch 0 taken
                      655: branch 1 taken
     313              657:   if (AttrList)
     314                2:     ProcessDeclAttributeList(TUScope, PDecl, AttrList);
                       83: branch 0 taken
                      574: branch 1 taken
     315              657:   if (NumProtoRefs) {
     316                 :     /// Check then save referenced protocols.
     317                 :     PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
     318               83:                            ProtoLocs, Context);
     319               83:     PDecl->setLocEnd(EndProtoLoc);
     320                 :   }
     321                 : 
     322              657:   CheckObjCDeclScope(PDecl);
     323              657:   return DeclPtrTy::make(PDecl);
     324                 : }
     325                 : 
     326                 : /// FindProtocolDeclaration - This routine looks up protocols and
     327                 : /// issues an error if they are not declared. It returns list of
     328                 : /// protocol declarations in its 'Protocols' argument.
     329                 : void
     330                 : Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
     331                 :                               const IdentifierLocPair *ProtocolId,
     332                 :                               unsigned NumProtocols,
     333              856:                               llvm::SmallVectorImpl<DeclPtrTy> &Protocols) {
                     1224: branch 0 taken
                      856: branch 1 taken
     334             2080:   for (unsigned i = 0; i != NumProtocols; ++i) {
     335             1224:     ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first);
                        5: branch 0 taken
                     1219: branch 1 taken
     336             1224:     if (!PDecl) {
     337                 :       LookupResult R(*this, ProtocolId[i].first, ProtocolId[i].second,
     338                5:                      LookupObjCProtocolName);
                        2: branch 1 taken
                        3: branch 2 taken
                        2: branch 4 taken
                        0: branch 5 not taken
                        2: branch 6 taken
                        3: branch 7 taken
     339                5:       if (CorrectTypo(R, TUScope, 0) &&
     340                 :           (PDecl = R.getAsSingle<ObjCProtocolDecl>())) {
     341                 :         Diag(ProtocolId[i].second, diag::err_undeclared_protocol_suggest)
     342                2:           << ProtocolId[i].first << R.getLookupName();
     343                 :         Diag(PDecl->getLocation(), diag::note_previous_decl)
     344                2:           << PDecl->getDeclName();
     345                5:       }
     346                 :     }
     347                 : 
                        3: branch 0 taken
                     1221: branch 1 taken
     348             1224:     if (!PDecl) {
     349                 :       Diag(ProtocolId[i].second, diag::err_undeclared_protocol)
     350                3:         << ProtocolId[i].first;
     351                3:       continue;
     352                 :     }
     353                 : 
     354             1221:     (void)DiagnoseUseOfDecl(PDecl, ProtocolId[i].second);
     355                 : 
     356                 :     // If this is a forward declaration and we are supposed to warn in this
     357                 :     // case, do it.
                      701: branch 0 taken
                      520: branch 1 taken
                        6: branch 3 taken
                      695: branch 4 taken
                        6: branch 5 taken
                     1215: branch 6 taken
     358             1221:     if (WarnOnDeclarations && PDecl->isForwardDecl())
     359                 :       Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
     360                6:         << ProtocolId[i].first;
     361             1221:     Protocols.push_back(DeclPtrTy::make(PDecl));
     362                 :   }
     363              856: }
     364                 : 
     365                 : /// DiagnosePropertyMismatch - Compares two properties for their
     366                 : /// attributes and types and warns on a variety of inconsistencies.
     367                 : ///
     368                 : void
     369                 : Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
     370                 :                                ObjCPropertyDecl *SuperProperty,
     371               18:                                const IdentifierInfo *inheritedName) {
     372                 :   ObjCPropertyDecl::PropertyAttributeKind CAttr =
     373               18:   Property->getPropertyAttributes();
     374                 :   ObjCPropertyDecl::PropertyAttributeKind SAttr =
     375               18:   SuperProperty->getPropertyAttributes();
                        6: branch 0 taken
                       12: branch 1 taken
                        1: branch 2 taken
                        5: branch 3 taken
     376               18:   if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
     377                 :       && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
     378                 :     Diag(Property->getLocation(), diag::warn_readonly_property)
     379                1:       << Property->getDeclName() << inheritedName;
                        3: branch 0 taken
                       15: branch 1 taken
     380               18:   if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
     381                 :       != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
     382                 :     Diag(Property->getLocation(), diag::warn_property_attribute)
     383                3:       << Property->getDeclName() << "copy" << inheritedName;
                        0: branch 0 not taken
                       15: branch 1 taken
     384               15:   else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
     385                 :            != (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
     386                 :     Diag(Property->getLocation(), diag::warn_property_attribute)
     387                0:       << Property->getDeclName() << "retain" << inheritedName;
     388                 : 
                        0: branch 0 not taken
                       18: branch 1 taken
     389               18:   if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
     390                 :       != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
     391                 :     Diag(Property->getLocation(), diag::warn_property_attribute)
     392                0:       << Property->getDeclName() << "atomic" << inheritedName;
                        0: branch 3 not taken
                       18: branch 4 taken
     393               18:   if (Property->getSetterName() != SuperProperty->getSetterName())
     394                 :     Diag(Property->getLocation(), diag::warn_property_attribute)
     395                0:       << Property->getDeclName() << "setter" << inheritedName;
                        0: branch 3 not taken
                       18: branch 4 taken
     396               18:   if (Property->getGetterName() != SuperProperty->getGetterName())
     397                 :     Diag(Property->getLocation(), diag::warn_property_attribute)
     398                0:       << Property->getDeclName() << "getter" << inheritedName;
     399                 : 
     400                 :   QualType LHSType =
     401               18:     Context.getCanonicalType(SuperProperty->getType());
     402                 :   QualType RHSType =
     403               18:     Context.getCanonicalType(Property->getType());
     404                 : 
                        3: branch 1 taken
                       15: branch 2 taken
     405               18:   if (!Context.typesAreCompatible(LHSType, RHSType)) {
     406                 :     // FIXME: Incorporate this test with typesAreCompatible.
                        1: branch 2 taken
                        2: branch 3 taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        2: branch 9 taken
     407                3:     if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType())
                        0: branch 1 not taken
                        1: branch 2 taken
     408                1:       if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false))
     409                0:         return;
     410                 :     Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
     411                3:       << Property->getType() << SuperProperty->getType() << inheritedName;
     412                 :   }
     413                 : }
     414                 : 
     415                 : /// ComparePropertiesInBaseAndSuper - This routine compares property
     416                 : /// declarations in base and its super class, if any, and issues
     417                 : /// diagnostics in a variety of inconsistant situations.
     418                 : ///
     419             1554: void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
     420             1554:   ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
                      828: branch 0 taken
                      726: branch 1 taken
     421             1554:   if (!SDecl)
     422              828:     return;
     423                 :   // FIXME: O(N^2)
                       78: branch 3 taken
                      726: branch 4 taken
     424             1530:   for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(),
     425              726:        E = SDecl->prop_end(); S != E; ++S) {
     426               78:     ObjCPropertyDecl *SuperPDecl = (*S);
     427                 :     // Does property in super class has declaration in current class?
                       66: branch 3 taken
                       78: branch 4 taken
     428              222:     for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(),
     429               78:          E = IDecl->prop_end(); I != E; ++I) {
     430               66:       ObjCPropertyDecl *PDecl = (*I);
                       12: branch 2 taken
                       54: branch 3 taken
     431               66:       if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
     432                 :           DiagnosePropertyMismatch(PDecl, SuperPDecl,
     433               12:                                    SDecl->getIdentifier());
     434                 :     }
     435                 :   }
     436                 : }
     437                 : 
     438                 : /// MatchOneProtocolPropertiesInClass - This routine goes thru the list
     439                 : /// of properties declared in a protocol and compares their attribute against
     440                 : /// the same property declared in the class or category.
     441                 : void
     442                 : Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl,
     443              736:                                           ObjCProtocolDecl *PDecl) {
     444              736:   ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
                       24: branch 0 taken
                      712: branch 1 taken
     445              736:   if (!IDecl) {
     446                 :     // Category
     447               24:     ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
                        0: branch 0 not taken
                       24: branch 1 taken
     448               24:     assert (CatDecl && "MatchOneProtocolPropertiesInClass");
                        5: branch 3 taken
                       24: branch 4 taken
     449               53:     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
     450               24:          E = PDecl->prop_end(); P != E; ++P) {
     451                5:       ObjCPropertyDecl *Pr = (*P);
     452                5:       ObjCCategoryDecl::prop_iterator CP, CE;
     453                 :       // Is this property already in  category's list of properties?
                        3: branch 4 taken
                        3: branch 5 taken
     454                6:       for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP != CE; ++CP)
                        2: branch 3 taken
                        1: branch 4 taken
     455                3:         if ((*CP)->getIdentifier() == Pr->getIdentifier())
     456                2:           break;
                        2: branch 1 taken
                        3: branch 2 taken
     457                5:       if (CP != CE)
     458                 :         // Property protocol already exist in class. Diagnose any mismatch.
     459                2:         DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier());
     460                 :     }
     461               24:     return;
     462                 :   }
                       37: branch 3 taken
                      712: branch 4 taken
     463             1461:   for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
     464              712:        E = PDecl->prop_end(); P != E; ++P) {
     465               37:     ObjCPropertyDecl *Pr = (*P);
     466               37:     ObjCInterfaceDecl::prop_iterator CP, CE;
     467                 :     // Is this property already in  class's list of properties?
                       29: branch 4 taken
                       33: branch 5 taken
     468               62:     for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP)
                        4: branch 3 taken
                       25: branch 4 taken
     469               29:       if ((*CP)->getIdentifier() == Pr->getIdentifier())
     470                4:         break;
                        4: branch 1 taken
                       33: branch 2 taken
     471               37:     if (CP != CE)
     472                 :       // Property protocol already exist in class. Diagnose any mismatch.
     473                4:       DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier());
     474                 :     }
     475                 : }
     476                 : 
     477                 : /// CompareProperties - This routine compares properties
     478                 : /// declared in 'ClassOrProtocol' objects (which can be a class or an
     479                 : /// inherited protocol with the list of properties for class/category 'CDecl'
     480                 : ///
     481                 : void Sema::CompareProperties(Decl *CDecl,
     482             2440:                              DeclPtrTy ClassOrProtocol) {
     483             2440:   Decl *ClassDecl = ClassOrProtocol.getAs<Decl>();
     484             2440:   ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
     485                 : 
                      207: branch 0 taken
                     2233: branch 1 taken
     486             2440:   if (!IDecl) {
     487                 :     // Category
     488              207:     ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
                        0: branch 0 not taken
                      207: branch 1 taken
     489              207:     assert (CatDecl && "CompareProperties");
                      185: branch 1 taken
                       22: branch 2 taken
     490              207:     if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
                       22: branch 1 taken
                      185: branch 2 taken
     491              392:       for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(),
     492              185:            E = MDecl->protocol_end(); P != E; ++P)
     493                 :       // Match properties of category with those of protocol (*P)
     494               22:       MatchOneProtocolPropertiesInClass(CatDecl, *P);
     495                 : 
     496                 :       // Go thru the list of protocols for this category and recursively match
     497                 :       // their properties with those in the category.
                       22: branch 1 taken
                      185: branch 2 taken
     498              392:       for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(),
     499              185:            E = CatDecl->protocol_end(); P != E; ++P)
     500               22:         CompareProperties(CatDecl, DeclPtrTy::make(*P));
     501                 :     } else {
     502               22:       ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
                        2: branch 1 taken
                       22: branch 2 taken
     503               46:       for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
     504               22:            E = MD->protocol_end(); P != E; ++P)
     505                2:         MatchOneProtocolPropertiesInClass(CatDecl, *P);
     506                 :     }
     507              207:     return;
     508                 :   }
     509                 : 
                     1554: branch 1 taken
                      679: branch 2 taken
     510             2233:   if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
                      679: branch 1 taken
                     1554: branch 2 taken
     511             3787:     for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
     512             1554:          E = MDecl->protocol_end(); P != E; ++P)
     513                 :       // Match properties of class IDecl with those of protocol (*P).
     514              679:       MatchOneProtocolPropertiesInClass(IDecl, *P);
     515                 : 
     516                 :     // Go thru the list of protocols for this class and recursively match
     517                 :     // their properties with those declared in the class.
                      679: branch 1 taken
                     1554: branch 2 taken
     518             3787:     for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
     519             1554:          E = IDecl->protocol_end(); P != E; ++P)
     520              679:       CompareProperties(IDecl, DeclPtrTy::make(*P));
     521                 :   } else {
     522              679:     ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
                       33: branch 1 taken
                      679: branch 2 taken
     523             1391:     for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
     524              679:          E = MD->protocol_end(); P != E; ++P)
     525               33:       MatchOneProtocolPropertiesInClass(IDecl, *P);
     526                 :   }
     527                 : }
     528                 : 
     529                 : /// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of
     530                 : /// a class method in its extension.
     531                 : ///
     532                 : void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
     533               29:                                             ObjCInterfaceDecl *ID) {
                        0: branch 0 not taken
                       29: branch 1 taken
     534               29:   if (!ID)
     535                0:     return;  // Possibly due to previous error
     536                 : 
     537               29:   llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
                      179: branch 3 taken
                       29: branch 4 taken
     538              237:   for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(),
     539               29:        e =  ID->meth_end(); i != e; ++i) {
     540              179:     ObjCMethodDecl *MD = *i;
     541              179:     MethodMap[MD->getSelector()] = MD;
     542                 :   }
     543                 : 
                        7: branch 1 taken
                       22: branch 2 taken
     544               29:   if (MethodMap.empty())
     545                7:     return;
                       24: branch 3 taken
                       22: branch 4 taken
     546               68:   for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(),
     547               22:        e =  CAT->meth_end(); i != e; ++i) {
     548               24:     ObjCMethodDecl *Method = *i;
     549               24:     const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
                        4: branch 0 taken
                       20: branch 1 taken
                        2: branch 3 taken
                        2: branch 4 taken
                        2: branch 5 taken
                       22: branch 6 taken
     550               24:     if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) {
     551                 :       Diag(Method->getLocation(), diag::err_duplicate_method_decl)
     552                2:             << Method->getDeclName();
     553                2:       Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
     554                 :     }
                       22: branch 1 taken
                        7: branch 2 taken
     555               29:   }
     556                 : }
     557                 : 
     558                 : /// ActOnForwardProtocolDeclaration - Handle @protocol foo;
     559                 : Action::DeclPtrTy
     560                 : Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
     561                 :                                       const IdentifierLocPair *IdentList,
     562                 :                                       unsigned NumElts,
     563               71:                                       AttributeList *attrList) {
     564               71:   llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
     565               71:   llvm::SmallVector<SourceLocation, 8> ProtoLocs;
     566                 : 
                       83: branch 0 taken
                       71: branch 1 taken
     567              154:   for (unsigned i = 0; i != NumElts; ++i) {
     568               83:     IdentifierInfo *Ident = IdentList[i].first;
     569               83:     ObjCProtocolDecl *PDecl = LookupProtocol(Ident);
                       81: branch 0 taken
                        2: branch 1 taken
     570               83:     if (PDecl == 0) { // Not already seen?
     571                 :       PDecl = ObjCProtocolDecl::Create(Context, CurContext,
     572               81:                                        IdentList[i].second, Ident);
     573               81:       PushOnScopeChains(PDecl, TUScope);
     574                 :     }
                        3: branch 0 taken
                       80: branch 1 taken
     575               83:     if (attrList)
     576                3:       ProcessDeclAttributeList(TUScope, PDecl, attrList);
     577               83:     Protocols.push_back(PDecl);
     578               83:     ProtoLocs.push_back(IdentList[i].second);
     579                 :   }
     580                 : 
     581                 :   ObjCForwardProtocolDecl *PDecl =
     582                 :     ObjCForwardProtocolDecl::Create(Context, CurContext, AtProtocolLoc,
     583                 :                                     Protocols.data(), Protocols.size(),
     584               71:                                     ProtoLocs.data());
     585               71:   CurContext->addDecl(PDecl);
     586               71:   CheckObjCDeclScope(PDecl);
     587               71:   return DeclPtrTy::make(PDecl);
     588                 : }
     589                 : 
     590                 : Sema::DeclPtrTy Sema::
     591                 : ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
     592                 :                             IdentifierInfo *ClassName, SourceLocation ClassLoc,
     593                 :                             IdentifierInfo *CategoryName,
     594                 :                             SourceLocation CategoryLoc,
     595                 :                             const DeclPtrTy *ProtoRefs,
     596                 :                             unsigned NumProtoRefs,
     597                 :                             const SourceLocation *ProtoLocs,
     598              185:                             SourceLocation EndProtoLoc) {
     599                 :   ObjCCategoryDecl *CDecl =
     600                 :     ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, ClassLoc,
     601              185:                              CategoryLoc, CategoryName);
     602                 :   // FIXME: PushOnScopeChains?
     603              185:   CurContext->addDecl(CDecl);
     604                 : 
     605              185:   ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc);
     606                 :   /// Check that class of this category is already completely declared.
                      183: branch 0 taken
                        2: branch 1 taken
                        1: branch 3 taken
                      182: branch 4 taken
                        3: branch 5 taken
                      182: branch 6 taken
     607              185:   if (!IDecl || IDecl->isForwardDecl()) {
     608                3:     CDecl->setInvalidDecl();
     609                3:     Diag(ClassLoc, diag::err_undef_interface) << ClassName;
     610                3:     return DeclPtrTy::make(CDecl);
     611                 :   }
     612                 : 
     613              182:   CDecl->setClassInterface(IDecl);
     614                 : 
     615                 :   // If the interface is deprecated, warn about it.
     616              182:   (void)DiagnoseUseOfDecl(IDecl, ClassLoc);
     617                 : 
     618                 :   /// Check for duplicate interface declaration for this category
     619                 :   ObjCCategoryDecl *CDeclChain;
                       81: branch 2 taken
                      173: branch 3 taken
     620              254:   for (CDeclChain = IDecl->getCategoryList(); CDeclChain;
     621                 :        CDeclChain = CDeclChain->getNextClassCategory()) {
                       77: branch 0 taken
                        4: branch 1 taken
                        9: branch 3 taken
                       68: branch 4 taken
                        9: branch 5 taken
                       72: branch 6 taken
     622               81:     if (CategoryName && CDeclChain->getIdentifier() == CategoryName) {
     623                 :       Diag(CategoryLoc, diag::warn_dup_category_def)
     624                9:       << ClassName << CategoryName;
     625                9:       Diag(CDeclChain->getLocation(), diag::note_previous_definition);
     626                9:       break;
     627                 :     }
     628                 :   }
                      173: branch 0 taken
                        9: branch 1 taken
     629              182:   if (!CDeclChain)
     630              173:     CDecl->insertNextClassCategory();
     631                 : 
                       18: branch 0 taken
                      164: branch 1 taken
     632              182:   if (NumProtoRefs) {
     633                 :     CDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs, 
     634               18:                            ProtoLocs, Context);
     635                 :     // Protocols in the class extension belong to the class.
                        5: branch 1 taken
                       13: branch 2 taken
     636               18:     if (!CDecl->getIdentifier())
     637                 :      IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl**)ProtoRefs, 
     638                 :                                             NumProtoRefs, ProtoLocs,
     639                5:                                             Context); 
     640                 :   }
     641                 : 
     642              182:   CheckObjCDeclScope(CDecl);
     643              182:   return DeclPtrTy::make(CDecl);
     644                 : }
     645                 : 
     646                 : /// ActOnStartCategoryImplementation - Perform semantic checks on the
     647                 : /// category implementation declaration and build an ObjCCategoryImplDecl
     648                 : /// object.
     649                 : Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
     650                 :                       SourceLocation AtCatImplLoc,
     651                 :                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
     652               68:                       IdentifierInfo *CatName, SourceLocation CatLoc) {
     653               68:   ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc);
     654               68:   ObjCCategoryDecl *CatIDecl = 0;
                       65: branch 0 taken
                        3: branch 1 taken
     655               68:   if (IDecl) {
     656               65:     CatIDecl = IDecl->FindCategoryDeclaration(CatName);
                       24: branch 0 taken
                       41: branch 1 taken
     657               65:     if (!CatIDecl) {
     658                 :       // Category @implementation with no corresponding @interface.
     659                 :       // Create and install one.
     660                 :       CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, SourceLocation(),
     661                 :                                           SourceLocation(), SourceLocation(),
     662               24:                                           CatName);
     663               24:       CatIDecl->setClassInterface(IDecl);
     664               24:       CatIDecl->insertNextClassCategory();
     665                 :     }
     666                 :   }
     667                 : 
     668                 :   ObjCCategoryImplDecl *CDecl =
     669                 :     ObjCCategoryImplDecl::Create(Context, CurContext, AtCatImplLoc, CatName,
     670               68:                                  IDecl);
     671                 :   /// Check that class of this category is already completely declared.
                       65: branch 0 taken
                        3: branch 1 taken
                        0: branch 3 not taken
                       65: branch 4 taken
                        3: branch 5 taken
                       65: branch 6 taken
     672               68:   if (!IDecl || IDecl->isForwardDecl())
     673                3:     Diag(ClassLoc, diag::err_undef_interface) << ClassName;
     674                 : 
     675                 :   // FIXME: PushOnScopeChains?
     676               68:   CurContext->addDecl(CDecl);
     677                 : 
     678                 :   /// Check that CatName, category name, is not used in another implementation.
                       65: branch 0 taken
                        3: branch 1 taken
     679               68:   if (CatIDecl) {
                        1: branch 1 taken
                       64: branch 2 taken
     680               65:     if (CatIDecl->getImplementation()) {
     681                 :       Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName
     682                1:         << CatName;
     683                 :       Diag(CatIDecl->getImplementation()->getLocation(),
     684                1:            diag::note_previous_definition);
     685                 :     } else
     686               64:       CatIDecl->setImplementation(CDecl);
     687                 :   }
     688                 : 
     689               68:   CheckObjCDeclScope(CDecl);
     690               68:   return DeclPtrTy::make(CDecl);
     691                 : }
     692                 : 
     693                 : Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
     694                 :                       SourceLocation AtClassImplLoc,
     695                 :                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
     696                 :                       IdentifierInfo *SuperClassname,
     697              573:                       SourceLocation SuperClassLoc) {
     698              573:   ObjCInterfaceDecl* IDecl = 0;
     699                 :   // Check for another declaration kind with the same name.
     700                 :   NamedDecl *PrevDecl
     701              573:     = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
                      549: branch 0 taken
                       24: branch 1 taken
                        1: branch 3 taken
                      548: branch 4 taken
                        1: branch 5 taken
                      572: branch 6 taken
     702              573:   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
     703                1:     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
     704                1:     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
                      548: branch 1 taken
                       24: branch 2 taken
     705              572:   } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
     706                 :     // If this is a forward declaration of an interface, warn.
                        4: branch 1 taken
                      544: branch 2 taken
     707              548:     if (IDecl->isForwardDecl()) {
     708                4:       Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
     709                4:       IDecl = 0;
     710                 :     }
     711                 :   } else {
     712                 :     // We did not find anything with the name ClassName; try to correct for 
     713                 :     // typos in the class name.
     714               24:     LookupResult R(*this, ClassName, ClassLoc, LookupOrdinaryName);
                        1: branch 1 taken
                       23: branch 2 taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        1: branch 6 taken
                       23: branch 7 taken
     715               24:     if (CorrectTypo(R, TUScope, 0) &&
     716                 :         (IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
     717                 :       // Suggest the (potentially) correct interface name. However, put the
     718                 :       // fix-it hint itself in a separate note, since changing the name in 
     719                 :       // the warning would make the fix-it change semantics.However, don't
     720                 :       // provide a code-modification hint or use the typo name for recovery,
     721                 :       // because this is just a warning. The program may actually be correct.
     722                 :       Diag(ClassLoc, diag::warn_undef_interface_suggest)
     723                1:         << ClassName << R.getLookupName();
     724                 :       Diag(IDecl->getLocation(), diag::note_previous_decl)
     725                 :         << R.getLookupName()
     726                 :         << CodeModificationHint::CreateReplacement(ClassLoc,
     727                1:                                                R.getLookupName().getAsString());
     728                1:       IDecl = 0;
     729                 :     } else {
     730               23:       Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
     731               24:     }
     732                 :   }
     733                 : 
     734                 :   // Check that super class name is valid class name
     735              573:   ObjCInterfaceDecl* SDecl = 0;
                       16: branch 0 taken
                      557: branch 1 taken
     736              573:   if (SuperClassname) {
     737                 :     // Check if a different kind of symbol declared in this scope.
     738               16:     PrevDecl = LookupSingleName(TUScope, SuperClassname, LookupOrdinaryName);
                       15: branch 0 taken
                        1: branch 1 taken
                        0: branch 3 not taken
                       15: branch 4 taken
                        0: branch 5 not taken
                       16: branch 6 taken
     739               16:     if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
     740                 :       Diag(SuperClassLoc, diag::err_redefinition_different_kind)
     741                0:         << SuperClassname;
     742                0:       Diag(PrevDecl->getLocation(), diag::note_previous_definition);
     743                 :     } else {
     744               16:       SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
                        1: branch 0 taken
                       15: branch 1 taken
     745               16:       if (!SDecl)
     746                 :         Diag(SuperClassLoc, diag::err_undef_superclass)
     747                1:           << SuperClassname << ClassName;
                        9: branch 0 taken
                        6: branch 1 taken
                        2: branch 3 taken
                        7: branch 4 taken
                        2: branch 5 taken
                       13: branch 6 taken
     748               15:       else if (IDecl && IDecl->getSuperClass() != SDecl) {
     749                 :         // This implementation and its interface do not have the same
     750                 :         // super class.
     751                 :         Diag(SuperClassLoc, diag::err_conflicting_super_class)
     752                2:           << SDecl->getDeclName();
     753                2:         Diag(SDecl->getLocation(), diag::note_previous_definition);
     754                 :       }
     755                 :     }
     756                 :   }
     757                 : 
                       29: branch 0 taken
                      544: branch 1 taken
     758              573:   if (!IDecl) {
     759                 :     // Legacy case of @implementation with no corresponding @interface.
     760                 :     // Build, chain & install the interface decl into the identifier.
     761                 : 
     762                 :     // FIXME: Do we support attributes on the @implementation? If so we should
     763                 :     // copy them over.
     764                 :     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
     765               29:                                       ClassName, ClassLoc, false, true);
     766               29:     IDecl->setSuperClass(SDecl);
     767               29:     IDecl->setLocEnd(ClassLoc);
     768                 : 
     769               29:     PushOnScopeChains(IDecl, TUScope);
     770                 :   } else {
     771                 :     // Mark the interface as being completed, even if it was just as
     772                 :     //   @class ....;
     773                 :     // declaration; the user cannot reopen it.
     774              544:     IDecl->setForwardDecl(false);
     775                 :   }
     776                 : 
     777                 :   ObjCImplementationDecl* IMPDecl =
     778                 :     ObjCImplementationDecl::Create(Context, CurContext, AtClassImplLoc,
     779              573:                                    IDecl, SDecl);
     780                 : 
                        1: branch 1 taken
                      572: branch 2 taken
     781              573:   if (CheckObjCDeclScope(IMPDecl))
     782                1:     return DeclPtrTy::make(IMPDecl);
     783                 : 
     784                 :   // Check that there is no duplicate implementation of this class.
                        1: branch 1 taken
                      571: branch 2 taken
     785              572:   if (IDecl->getImplementation()) {
     786                 :     // FIXME: Don't leak everything!
     787                1:     Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
     788                 :     Diag(IDecl->getImplementation()->getLocation(),
     789                1:          diag::note_previous_definition);
     790                 :   } else { // add it to the list.
     791              571:     IDecl->setImplementation(IMPDecl);
     792              571:     PushOnScopeChains(IMPDecl, TUScope);
     793                 :   }
     794              572:   return DeclPtrTy::make(IMPDecl);
     795                 : }
     796                 : 
     797                 : void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
     798                 :                                     ObjCIvarDecl **ivars, unsigned numIvars,
     799               14:                                     SourceLocation RBrace) {
                        0: branch 0 not taken
                       14: branch 1 taken
     800               14:   assert(ImpDecl && "missing implementation decl");
     801               14:   ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface();
                        0: branch 0 not taken
                       14: branch 1 taken
     802               14:   if (!IDecl)
     803                0:     return;
     804                 :   /// Check case of non-existing @interface decl.
     805                 :   /// (legacy objective-c @implementation decl without an @interface decl).
     806                 :   /// Add implementations's ivar to the synthesize class's ivar list.
                        3: branch 1 taken
                       11: branch 2 taken
     807               14:   if (IDecl->isImplicitInterfaceDecl()) {
     808                3:     IDecl->setIVarList(ivars, numIvars, Context);
     809                3:     IDecl->setLocEnd(RBrace);
     810                3:     return;
     811                 :   }
     812                 :   // If implementation has empty ivar list, just return.
                        5: branch 0 taken
                        6: branch 1 taken
     813               11:   if (numIvars == 0)
     814                5:     return;
     815                 : 
                        0: branch 0 not taken
                        6: branch 1 taken
     816                6:   assert(ivars && "missing @implementation ivars");
     817                 : 
     818                 :   // Check interface's Ivar list against those in the implementation.
     819                 :   // names and types must match.
     820                 :   //
     821                6:   unsigned j = 0;
     822                 :   ObjCInterfaceDecl::ivar_iterator
     823                6:     IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
                       10: branch 0 taken
                        5: branch 1 taken
                        9: branch 2 taken
                        1: branch 3 taken
     824               15:   for (; numIvars > 0 && IVI != IVE; ++IVI) {
     825                9:     ObjCIvarDecl* ImplIvar = ivars[j++];
     826                9:     ObjCIvarDecl* ClsIvar = *IVI;
                        0: branch 0 not taken
                        9: branch 1 taken
     827                9:     assert (ImplIvar && "missing implementation ivar");
                        0: branch 0 not taken
                        9: branch 1 taken
     828                9:     assert (ClsIvar && "missing class ivar");
     829                 : 
     830                 :     // First, make sure the types match.
                        2: branch 5 taken
                        7: branch 6 taken
     831                9:     if (Context.getCanonicalType(ImplIvar->getType()) !=
     832                 :         Context.getCanonicalType(ClsIvar->getType())) {
     833                 :       Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
     834                 :         << ImplIvar->getIdentifier()
     835                2:         << ImplIvar->getType() << ClsIvar->getType();
     836                2:       Diag(ClsIvar->getLocation(), diag::note_previous_definition);
                        3: branch 1 taken
                        4: branch 2 taken
                        3: branch 4 taken
                        0: branch 5 not taken
                        3: branch 6 taken
                        4: branch 7 taken
     837                7:     } else if (ImplIvar->isBitField() && ClsIvar->isBitField()) {
     838                3:       Expr *ImplBitWidth = ImplIvar->getBitWidth();
     839                3:       Expr *ClsBitWidth = ClsIvar->getBitWidth();
                        1: branch 6 taken
                        2: branch 7 taken
     840                3:       if (ImplBitWidth->EvaluateAsInt(Context).getZExtValue() !=
     841                 :           ClsBitWidth->EvaluateAsInt(Context).getZExtValue()) {
     842                 :         Diag(ImplBitWidth->getLocStart(), diag::err_conflicting_ivar_bitwidth)
     843                1:           << ImplIvar->getIdentifier();
     844                1:         Diag(ClsBitWidth->getLocStart(), diag::note_previous_definition);
     845                 :       }
     846                 :     }
     847                 :     // Make sure the names are identical.
                        1: branch 2 taken
                        8: branch 3 taken
     848                9:     if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
     849                 :       Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
     850                1:         << ImplIvar->getIdentifier() << ClsIvar->getIdentifier();
     851                1:       Diag(ClsIvar->getLocation(), diag::note_previous_definition);
     852                 :     }
     853                9:     --numIvars;
     854                 :   }
     855                 : 
                        1: branch 0 taken
                        5: branch 1 taken
     856                6:   if (numIvars > 0)
     857                1:     Diag(ivars[j]->getLocation(), diag::err_inconsistant_ivar_count);
                        1: branch 0 taken
                        4: branch 1 taken
     858                5:   else if (IVI != IVE)
     859                1:     Diag((*IVI)->getLocation(), diag::err_inconsistant_ivar_count);
     860                 : }
     861                 : 
     862                 : void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
     863               71:                                bool &IncompleteImpl) {
                       32: branch 0 taken
                       39: branch 1 taken
     864               71:   if (!IncompleteImpl) {
     865               32:     Diag(ImpLoc, diag::warn_incomplete_impl);
     866               32:     IncompleteImpl = true;
     867                 :   }
     868               71:   Diag(ImpLoc, diag::warn_undef_method_impl) << method->getDeclName();
     869               71: }
     870                 : 
     871                 : void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
     872              584:                                        ObjCMethodDecl *IntfMethodDecl) {
                        4: branch 3 taken
                      580: branch 4 taken
                        4: branch 8 taken
                        0: branch 9 not taken
                        4: branch 10 taken
                      580: branch 11 taken
     873              584:   if (!Context.typesAreCompatible(IntfMethodDecl->getResultType(),
     874                 :                                   ImpMethodDecl->getResultType()) &&
     875                 :       !Context.QualifiedIdConformsQualifiedId(IntfMethodDecl->getResultType(),
     876                 :                                               ImpMethodDecl->getResultType())) {
     877                 :     Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_ret_types)
     878                 :       << ImpMethodDecl->getDeclName() << IntfMethodDecl->getResultType()
     879                4:       << ImpMethodDecl->getResultType();
     880                4:     Diag(IntfMethodDecl->getLocation(), diag::note_previous_definition);
     881                 :   }
     882                 : 
                      249: branch 1 taken
                      584: branch 2 taken
     883             1417:   for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
     884              584:        IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
     885                 :        IM != EM; ++IM, ++IF) {
     886              249:     QualType ParmDeclTy = (*IF)->getType().getUnqualifiedType();
     887              249:     QualType ParmImpTy = (*IM)->getType().getUnqualifiedType();
                       10: branch 1 taken
                      239: branch 2 taken
                        0: branch 4 not taken
                       10: branch 5 taken
                      239: branch 6 taken
                       10: branch 7 taken
     888              249:     if (Context.typesAreCompatible(ParmDeclTy, ParmImpTy) ||
     889                 :         Context.QualifiedIdConformsQualifiedId(ParmDeclTy, ParmImpTy))
     890              239:       continue;
     891                 : 
     892                 :     Diag((*IM)->getLocation(), diag::warn_conflicting_param_types)
     893                 :       << ImpMethodDecl->getDeclName() << (*IF)->getType()
     894               10:       << (*IM)->getType();
     895               10:     Diag((*IF)->getLocation(), diag::note_previous_definition);
     896                 :   }
     897              584: }
     898                 : 
     899                 : /// isPropertyReadonly - Return true if property is readonly, by searching
     900                 : /// for the property in the class and in its categories and implementations
     901                 : ///
     902                 : bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
     903               89:                               ObjCInterfaceDecl *IDecl) {
     904                 :   // by far the most common case.
                       79: branch 1 taken
                       10: branch 2 taken
     905               89:   if (!PDecl->isReadOnly())
     906               79:     return false;
     907                 :   // Even if property is ready only, if interface has a user defined setter,
     908                 :   // it is not considered read only.
                        1: branch 2 taken
                        9: branch 3 taken
     909               10:   if (IDecl->getInstanceMethod(PDecl->getSetterName()))
     910                1:     return false;
     911                 : 
     912                 :   // Main class has the property as 'readonly'. Must search
     913                 :   // through the category list to see if the property's
     914                 :   // attribute has been over-ridden to 'readwrite'.
                        6: branch 2 taken
                        7: branch 3 taken
     915               13:   for (ObjCCategoryDecl *Category = IDecl->getCategoryList();
     916                 :        Category; Category = Category->getNextClassCategory()) {
     917                 :     // Even if property is ready only, if a category has a user defined setter,
     918                 :     // it is not considered read only.
                        2: branch 2 taken
                        4: branch 3 taken
     919                6:     if (Category->getInstanceMethod(PDecl->getSetterName()))
     920                2:       return false;
     921                 :     ObjCPropertyDecl *P =
     922                4:       Category->FindPropertyDeclaration(PDecl->getIdentifier());
                        1: branch 0 taken
                        3: branch 1 taken
                        0: branch 3 not taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        4: branch 6 taken
     923                4:     if (P && !P->isReadOnly())
     924                0:       return false;
     925                 :   }
     926                 : 
     927                 :   // Also, check for definition of a setter method in the implementation if
     928                 :   // all else failed.
                        5: branch 1 taken
                        2: branch 2 taken
     929                7:   if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) {
                        4: branch 0 taken
                        1: branch 1 taken
     930                5:     if (ObjCImplementationDecl *IMD =
     931                5:         dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
                        1: branch 2 taken
                        3: branch 3 taken
     932                4:       if (IMD->getInstanceMethod(PDecl->getSetterName()))
     933                1:         return false;
                        1: branch 0 taken
                        0: branch 1 not taken
     934                1:     } else if (ObjCCategoryImplDecl *CIMD =
     935                1:                dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
                        1: branch 2 taken
                        0: branch 3 not taken
     936                1:       if (CIMD->getInstanceMethod(PDecl->getSetterName()))
     937                1:         return false;
     938                 :     }
     939                 :   }
     940                 :   // Lastly, look through the implementation (if one is in scope).
                        4: branch 1 taken
                        1: branch 2 taken
     941                5:   if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation())
                        1: branch 2 taken
                        3: branch 3 taken
     942                4:     if (ImpDecl->getInstanceMethod(PDecl->getSetterName()))
     943                1:       return false;
     944                 :   // If all fails, look at the super class.
                        1: branch 1 taken
                        3: branch 2 taken
     945                4:   if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass())
     946                1:     return isPropertyReadonly(PDecl, SIDecl);
     947                3:   return true;
     948                 : }
     949                 : 
     950                 : /// FIXME: Type hierarchies in Objective-C can be deep. We could most likely
     951                 : /// improve the efficiency of selector lookups and type checking by associating
     952                 : /// with each protocol / interface / category the flattened instance tables. If
     953                 : /// we used an immutable set to keep the table then it wouldn't add significant
     954                 : /// memory cost and it would be handy for lookups.
     955                 : 
     956                 : /// CheckProtocolMethodDefs - This routine checks unimplemented methods
     957                 : /// Declared in protocol, and those referenced by it.
     958                 : void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
     959                 :                                    ObjCProtocolDecl *PDecl,
     960                 :                                    bool& IncompleteImpl,
     961                 :                                    const llvm::DenseSet<Selector> &InsMap,
     962                 :                                    const llvm::DenseSet<Selector> &ClsMap,
     963               71:                                    ObjCInterfaceDecl *IDecl) {
     964               71:   ObjCInterfaceDecl *Super = IDecl->getSuperClass();
     965               71:   ObjCInterfaceDecl *NSIDecl = 0;
                       69: branch 1 taken
                        2: branch 2 taken
     966               71:   if (getLangOptions().NeXTRuntime) {
     967                 :     // check to see if class implements forwardInvocation method and objects
     968                 :     // of this class are derived from 'NSProxy' so that to forward requests
     969                 :     // from one object to another.
     970                 :     // Under such conditions, which means that every method possible is
     971                 :     // implemented in the class, we should not issue "Method definition not
     972                 :     // found" warnings.
     973                 :     // FIXME: Use a general GetUnarySelector method for this.
     974               69:     IdentifierInfo* II = &Context.Idents.get("forwardInvocation");
     975               69:     Selector fISelector = Context.Selectors.getSelector(1, &II);
                        1: branch 1 taken
                       68: branch 2 taken
     976               69:     if (InsMap.count(fISelector))
     977                 :       // Is IDecl derived from 'NSProxy'? If so, no instance methods
     978                 :       // need be implemented in the implementation.
     979                1:       NSIDecl = IDecl->lookupInheritedClass(&Context.Idents.get("NSProxy"));
     980                 :   }
     981                 : 
     982                 :   // If a method lookup fails locally we still need to look and see if
     983                 :   // the method was implemented by a base class or an inherited
     984                 :   // protocol. This lookup is slow, but occurs rarely in correct code
     985                 :   // and otherwise would terminate in a warning.
     986                 : 
     987                 :   // check unimplemented instance methods.
                       70: branch 0 taken
                        1: branch 1 taken
     988               71:   if (!NSIDecl)
                      109: branch 3 taken
                       70: branch 4 taken
     989              249:     for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
     990               70:          E = PDecl->instmeth_end(); I != E; ++I) {
     991              109:       ObjCMethodDecl *method = *I;
                       86: branch 1 taken
                       23: branch 2 taken
                       50: branch 4 taken
                       36: branch 5 taken
                       30: branch 8 taken
                       20: branch 9 taken
                       20: branch 10 taken
                       10: branch 11 taken
                        8: branch 14 taken
                       12: branch 15 taken
                       18: branch 16 taken
                       91: branch 17 taken
     992              109:       if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
     993                 :           !method->isSynthesized() && !InsMap.count(method->getSelector()) &&
     994                 :           (!Super ||
     995                 :            !Super->lookupInstanceMethod(method->getSelector()))) {
     996                 :             // Ugly, but necessary. Method declared in protcol might have
     997                 :             // have been synthesized due to a property declared in the class which
     998                 :             // uses the protocol.
     999                 :             ObjCMethodDecl *MethodInClass =
    1000               18:             IDecl->lookupInstanceMethod(method->getSelector());
                       18: branch 0 taken
                        0: branch 1 not taken
                       17: branch 3 taken
                        1: branch 4 taken
                       17: branch 5 taken
                        1: branch 6 taken
    1001               18:             if (!MethodInClass || !MethodInClass->isSynthesized())
    1002               17:               WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
    1003                 :           }
    1004                 :     }
    1005                 :   // check unimplemented class methods
                        8: branch 2 taken
                       71: branch 3 taken
    1006               79:   for (ObjCProtocolDecl::classmeth_iterator
    1007               71:          I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
    1008                 :        I != E; ++I) {
    1009                8:     ObjCMethodDecl *method = *I;
                        8: branch 1 taken
                        0: branch 2 not taken
                        4: branch 5 taken
                        4: branch 6 taken
                        0: branch 7 not taken
                        4: branch 8 taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                        4: branch 13 taken
                        4: branch 14 taken
    1010                8:     if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
    1011                 :         !ClsMap.count(method->getSelector()) &&
    1012                 :         (!Super || !Super->lookupClassMethod(method->getSelector())))
    1013                4:       WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
    1014                 :   }
    1015                 :   // Check on this protocols's referenced protocols, recursively.
                       14: branch 1 taken
                       71: branch 2 taken
    1016              156:   for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
    1017               71:        E = PDecl->protocol_end(); PI != E; ++PI)
    1018               14:     CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
    1019               71: }
    1020                 : 
    1021                 : /// MatchAllMethodDeclarations - Check methods declaraed in interface or
    1022                 : /// or protocol against those declared in their implementations.
    1023                 : ///
    1024                 : void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
    1025                 :                                       const llvm::DenseSet<Selector> &ClsMap,
    1026                 :                                       llvm::DenseSet<Selector> &InsMapSeen,
    1027                 :                                       llvm::DenseSet<Selector> &ClsMapSeen,
    1028                 :                                       ObjCImplDecl* IMPDecl,
    1029                 :                                       ObjCContainerDecl* CDecl,
    1030                 :                                       bool &IncompleteImpl,
    1031             1137:                                       bool ImmediateClass) {
    1032                 :   // Check and see if instance methods in class interface have been
    1033                 :   // implemented in the implementation class. If so, their types match.
                     1615: branch 3 taken
                     1137: branch 4 taken
    1034             3889:   for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(),
    1035             1137:        E = CDecl->instmeth_end(); I != E; ++I) {
                       45: branch 3 taken
                     1570: branch 4 taken
    1036             1615:     if (InsMapSeen.count((*I)->getSelector()))
    1037               45:         continue;
    1038             1570:     InsMapSeen.insert((*I)->getSelector());
                      848: branch 2 taken
                      722: branch 3 taken
                      467: branch 7 taken
                      381: branch 8 taken
                      467: branch 9 taken
                     1103: branch 10 taken
    1039             1570:     if (!(*I)->isSynthesized() &&
    1040                 :         !InsMap.count((*I)->getSelector())) {
                       45: branch 0 taken
                      422: branch 1 taken
    1041              467:       if (ImmediateClass)
    1042               45:         WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
    1043              467:       continue;
    1044                 :     } else {
    1045                 :       ObjCMethodDecl *ImpMethodDecl =
    1046             1103:       IMPDecl->getInstanceMethod((*I)->getSelector());
    1047                 :       ObjCMethodDecl *IntfMethodDecl =
    1048             1103:       CDecl->getInstanceMethod((*I)->getSelector());
    1049                 :       assert(IntfMethodDecl &&
                        0: branch 0 not taken
                     1103: branch 1 taken
    1050             1103:              "IntfMethodDecl is null in ImplMethodsVsClassMethods");
    1051                 :       // ImpMethodDecl may be null as in a @dynamic property.
                      479: branch 0 taken
                      624: branch 1 taken
    1052             1103:       if (ImpMethodDecl)
    1053              479:         WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
    1054                 :     }
    1055                 :   }
    1056                 : 
    1057                 :   // Check and see if class methods in class interface have been
    1058                 :   // implemented in the implementation class. If so, their types match.
                      213: branch 2 taken
                     1137: branch 3 taken
    1059             1350:    for (ObjCInterfaceDecl::classmeth_iterator
    1060             1137:        I = CDecl->classmeth_begin(), E = CDecl->classmeth_end(); I != E; ++I) {
                        3: branch 3 taken
                      210: branch 4 taken
    1061              213:      if (ClsMapSeen.count((*I)->getSelector()))
    1062                3:        continue;
    1063              210:      ClsMapSeen.insert((*I)->getSelector());
                      105: branch 3 taken
                      105: branch 4 taken
    1064              210:     if (!ClsMap.count((*I)->getSelector())) {
                        5: branch 0 taken
                      100: branch 1 taken
    1065              105:       if (ImmediateClass)
    1066                5:         WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
    1067                 :     } else {
    1068                 :       ObjCMethodDecl *ImpMethodDecl =
    1069              105:         IMPDecl->getClassMethod((*I)->getSelector());
    1070                 :       ObjCMethodDecl *IntfMethodDecl =
    1071              105:         CDecl->getClassMethod((*I)->getSelector());
    1072              105:       WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
    1073                 :     }
    1074                 :   }
                      872: branch 1 taken
                      265: branch 2 taken
    1075             1137:   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
    1076                 :     // Check for any implementation of a methods declared in protocol.
                      179: branch 1 taken
                      872: branch 2 taken
    1077             1923:     for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
    1078              872:          E = I->protocol_end(); PI != E; ++PI)
    1079                 :       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
    1080                 :                                  IMPDecl,
    1081              179:                                  (*PI), IncompleteImpl, false);
                      299: branch 1 taken
                      573: branch 2 taken
    1082              872:     if (I->getSuperClass())
    1083                 :       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
    1084                 :                                  IMPDecl,
    1085              299:                                  I->getSuperClass(), IncompleteImpl, false);
    1086                 :   }
    1087             1137: }
    1088                 : 
    1089                 : /// CollectImmediateProperties - This routine collects all properties in
    1090                 : /// the class and its conforming protocols; but not those it its super class.
    1091                 : void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
    1092              709:                 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
                      573: branch 1 taken
                      136: branch 2 taken
    1093              709:   if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
                      276: branch 3 taken
                      573: branch 4 taken
    1094             1422:     for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
    1095              573:          E = IDecl->prop_end(); P != E; ++P) {
    1096              276:       ObjCPropertyDecl *Prop = (*P);
    1097              276:       PropMap[Prop->getIdentifier()] = Prop;
    1098                 :     }
    1099                 :     // scan through class's protocols.
                       54: branch 1 taken
                      573: branch 2 taken
    1100             1200:     for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
    1101              573:          E = IDecl->protocol_end(); PI != E; ++PI)
    1102               54:       CollectImmediateProperties((*PI), PropMap);
    1103                 :   }
                       65: branch 1 taken
                      644: branch 2 taken
    1104              709:   if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
                        6: branch 3 taken
                       65: branch 4 taken
    1105              136:     for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(),
    1106               65:          E = CATDecl->prop_end(); P != E; ++P) {
    1107                6:       ObjCPropertyDecl *Prop = (*P);
    1108                6:       PropMap[Prop->getIdentifier()] = Prop;
    1109                 :     }
    1110                 :     // scan through class's protocols.
                        3: branch 1 taken
                       65: branch 2 taken
    1111              133:     for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
    1112               65:          E = CATDecl->protocol_end(); PI != E; ++PI)
    1113                3:       CollectImmediateProperties((*PI), PropMap);
    1114                 :   }  
                       71: branch 1 taken
                      573: branch 2 taken
    1115              644:   else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
                       29: branch 3 taken
                       71: branch 4 taken
    1116              171:     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
    1117               71:          E = PDecl->prop_end(); P != E; ++P) {
    1118               29:       ObjCPropertyDecl *Prop = (*P);
    1119               29:       ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()];
                       26: branch 0 taken
                        3: branch 1 taken
    1120               29:       if (!PropEntry)
    1121               26:         PropEntry = Prop;
    1122                 :     }
    1123                 :     // scan through protocol's protocols.
                       14: branch 1 taken
                       71: branch 2 taken
    1124              156:     for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
    1125               71:          E = PDecl->protocol_end(); PI != E; ++PI)
    1126               14:       CollectImmediateProperties((*PI), PropMap);
    1127                 :   }
    1128              709: }
    1129                 : 
    1130                 : /// LookupPropertyDecl - Looks up a property in the current class and all
    1131                 : /// its protocols.
    1132                 : ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, 
    1133                6:                                      IdentifierInfo *II) {
                        6: branch 0 taken
                        0: branch 1 not taken
    1134                6:   if (const ObjCInterfaceDecl *IDecl = 
    1135                6:         dyn_cast<ObjCInterfaceDecl>(CDecl)) {
                        9: branch 3 taken
                        0: branch 4 not taken
    1136               15:     for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
    1137                6:          E = IDecl->prop_end(); P != E; ++P) {
    1138                9:       ObjCPropertyDecl *Prop = (*P);
                        6: branch 1 taken
                        3: branch 2 taken
    1139                9:       if (Prop->getIdentifier() == II)
    1140                6:         return Prop;
    1141                 :     }
    1142                 :     // scan through class's protocols.
                        0: branch 1 not taken
                        0: branch 2 not taken
    1143                0:     for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
    1144                0:          E = IDecl->protocol_end(); PI != E; ++PI) {
    1145                0:       ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
                        0: branch 0 not taken
                        0: branch 1 not taken
    1146                0:       if (Prop)
    1147                0:         return Prop;
    1148                 :     }
    1149                 :   }
                        0: branch 0 not taken
                        0: branch 1 not taken
    1150                0:   else if (const ObjCProtocolDecl *PDecl = 
    1151                0:             dyn_cast<ObjCProtocolDecl>(CDecl)) {
                        0: branch 3 not taken
                        0: branch 4 not taken
    1152                0:     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
    1153                0:          E = PDecl->prop_end(); P != E; ++P) {
    1154                0:       ObjCPropertyDecl *Prop = (*P);
                        0: branch 1 not taken
                        0: branch 2 not taken
    1155                0:       if (Prop->getIdentifier() == II)
    1156                0:         return Prop;
    1157                 :     }
    1158                 :     // scan through protocol's protocols.
                        0: branch 1 not taken
                        0: branch 2 not taken
    1159                0:     for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
    1160                0:          E = PDecl->protocol_end(); PI != E; ++PI) {
    1161                0:       ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
                        0: branch 0 not taken
                        0: branch 1 not taken
    1162                0:       if (Prop)
    1163                0:         return Prop;
    1164                 :     }
    1165                 :   }
    1166                0:   return 0;
    1167                 : }
    1168                 : 
    1169                 : 
    1170                 : void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
    1171                 :                                       ObjCContainerDecl *CDecl,
    1172              638:                                       const llvm::DenseSet<Selector>& InsMap) {
    1173              638:   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
    1174              638:   CollectImmediateProperties(CDecl, PropMap);
                      527: branch 1 taken
                      111: branch 2 taken
    1175              638:   if (PropMap.empty())
    1176              527:     return;
    1177                 :   
    1178              111:   llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
                      252: branch 2 taken
                      111: branch 3 taken
    1179              363:   for (ObjCImplDecl::propimpl_iterator
    1180              111:        I = IMPDecl->propimpl_begin(),
    1181              111:        EI = IMPDecl->propimpl_end(); I != EI; ++I)
    1182              252:     PropImplMap.insert((*I)->getPropertyDecl());
    1183                 :   
                      308: branch 3 taken
                      111: branch 4 taken
    1184              419:   for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 
    1185              111:        P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
    1186              308:     ObjCPropertyDecl *Prop = P->second;
    1187                 :     // Is there a matching propery synthesize/dynamic?
                      307: branch 1 taken
                        1: branch 2 taken
                      297: branch 4 taken
                       10: branch 5 taken
                      245: branch 7 taken
                       52: branch 8 taken
                      256: branch 9 taken
                       52: branch 10 taken
    1188              308:     if (Prop->isInvalidDecl() ||
    1189                 :         Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
    1190                 :         PropImplMap.count(Prop))
    1191              256:       continue;
                        8: branch 0 taken
                       44: branch 1 taken
    1192               52:     if (LangOpts.ObjCNonFragileABI2) {
    1193                 :       ActOnPropertyImplDecl(IMPDecl->getLocation(),
    1194                 :                             SourceLocation(),
    1195                 :                             true, DeclPtrTy::make(IMPDecl), 
    1196                 :                             Prop->getIdentifier(),
    1197                8:                             Prop->getIdentifier());
    1198                8:       continue;
    1199                 :     }
                       32: branch 2 taken
                       12: branch 3 taken
    1200               44:     if (!InsMap.count(Prop->getGetterName())) {
    1201                 :       Diag(Prop->getLocation(),
    1202                 :            isa<ObjCCategoryDecl>(CDecl) ? 
    1203                 :             diag::warn_setter_getter_impl_required_in_category : 
    1204                 :             diag::warn_setter_getter_impl_required)
                        2: branch 4 taken
                       30: branch 5 taken
    1205               32:       << Prop->getDeclName() << Prop->getGetterName();
    1206                 :       Diag(IMPDecl->getLocation(),
    1207               32:            diag::note_property_impl_required);
    1208                 :     }
    1209                 :     
                       42: branch 1 taken
                        2: branch 2 taken
                       33: branch 5 taken
                        9: branch 6 taken
                       33: branch 7 taken
                       11: branch 8 taken
    1210               44:     if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) {
    1211                 :       Diag(Prop->getLocation(),
    1212                 :            isa<ObjCCategoryDecl>(CDecl) ? 
    1213                 :            diag::warn_setter_getter_impl_required_in_category :
    1214                 :            diag::warn_setter_getter_impl_required)
                        4: branch 4 taken
                       29: branch 5 taken
    1215               33:       << Prop->getDeclName() << Prop->getSetterName();
    1216                 :       Diag(IMPDecl->getLocation(),
    1217               33:            diag::note_property_impl_required);
    1218                 :     }    
                      111: branch 2 taken
                      527: branch 3 taken
    1219              111:   }
    1220                 : }
    1221                 : 
    1222                 : void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
    1223                 :                                      ObjCContainerDecl* CDecl,
    1224              659:                                      bool IncompleteImpl) {
    1225              659:   llvm::DenseSet<Selector> InsMap;
    1226                 :   // Check and see if instance methods in class interface have been
    1227                 :   // implemented in the implementation class.
                      824: branch 2 taken
                      659: branch 3 taken
    1228             1483:   for (ObjCImplementationDecl::instmeth_iterator
    1229              659:          I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I)
    1230              824:     InsMap.insert((*I)->getSelector());
    1231                 : 
    1232                 :   // Check and see if properties declared in the interface have either 1)
    1233                 :   // an implementation or 2) there is a @synthesize/@dynamic implementation
    1234                 :   // of the property in the @implementation.
                      573: branch 1 taken
                       86: branch 2 taken
    1235              659:   if (isa<ObjCInterfaceDecl>(CDecl))
    1236              573:     DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);
    1237                 :       
    1238              659:   llvm::DenseSet<Selector> ClsMap;
                      177: branch 2 taken
                      659: branch 3 taken
    1239              836:   for (ObjCImplementationDecl::classmeth_iterator
    1240              659:        I = IMPDecl->classmeth_begin(),
    1241              659:        E = IMPDecl->classmeth_end(); I != E; ++I)
    1242              177:     ClsMap.insert((*I)->getSelector());
    1243                 : 
    1244                 :   // Check for type conflict of methods declared in a class/protocol and
    1245                 :   // its implementation; if any.
    1246              659:   llvm::DenseSet<Selector> InsMapSeen, ClsMapSeen;
    1247                 :   MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
    1248                 :                              IMPDecl, CDecl,
    1249              659:                              IncompleteImpl, true);
    1250                 : 
    1251                 :   // Check the protocol list for unimplemented methods in the @implementation
    1252                 :   // class.
    1253                 :   // Check and see if class methods in class interface have been
    1254                 :   // implemented in the implementation class.
    1255                 : 
                      573: branch 1 taken
                       86: branch 2 taken
    1256              659:   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
                       54: branch 1 taken
                      573: branch 2 taken
    1257             1200:     for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
    1258              573:          E = I->protocol_end(); PI != E; ++PI)
    1259                 :       CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
    1260               54:                               InsMap, ClsMap, I);
    1261                 :     // Check class extensions (unnamed categories)
                       37: branch 2 taken
                      552: branch 3 taken
    1262              589:     for (ObjCCategoryDecl *Categories = I->getCategoryList();
    1263                 :          Categories; Categories = Categories->getNextClassCategory()) {
                       21: branch 1 taken
                       16: branch 2 taken
    1264               37:       if (!Categories->getIdentifier()) {
    1265               21:         ImplMethodsVsClassMethods(IMPDecl, Categories, IncompleteImpl);
    1266               21:         break;
    1267                 :       }
    1268                 :     }
                       86: branch 1 taken
                        0: branch 2 not taken
    1269               86:   } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
    1270                 :     // For extended class, unimplemented methods in its protocols will
    1271                 :     // be reported in the primary class.
                       65: branch 1 taken
                       21: branch 2 taken
    1272               86:     if (C->getIdentifier()) {
                        3: branch 1 taken
                       65: branch 2 taken
    1273              133:       for (ObjCCategoryDecl::protocol_iterator PI = C->protocol_begin(),
    1274               65:            E = C->protocol_end(); PI != E; ++PI)
    1275                 :         CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
    1276                3:                                 InsMap, ClsMap, C->getClassInterface());
    1277                 :       // Report unimplemented properties in the category as well.
    1278                 :       // When reporting on missing setter/getters, do not report when
    1279                 :       // setter/getter is implemented in category's primary class 
    1280                 :       // implementation.
                       65: branch 1 taken
                        0: branch 2 not taken
    1281               65:       if (ObjCInterfaceDecl *ID = C->getClassInterface())
                       41: branch 1 taken
                       24: branch 2 taken
    1282               65:         if (ObjCImplDecl *IMP = ID->getImplementation()) {
                       48: branch 2 taken
                       41: branch 3 taken
    1283               89:           for (ObjCImplementationDecl::instmeth_iterator
    1284               41:                I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
    1285               48:             InsMap.insert((*I)->getSelector());
    1286                 :         }
    1287               65:       DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);      
    1288                 :     } 
    1289                 :   } else
    1290                0:     assert(false && "invalid ObjCContainerDecl type.");
    1291              659: }
    1292                 : 
    1293                 : void
    1294                 : Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
    1295              573:                                        ObjCContainerDecl* IDecl) {
    1296                 :   // Rules apply in non-GC mode only
                       39: branch 2 taken
                      534: branch 3 taken
    1297              573:   if (getLangOptions().getGCMode() != LangOptions::NonGC)
    1298               39:     return;
                      258: branch 3 taken
                      534: branch 4 taken
    1299             1326:   for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(),
    1300              534:        E = IDecl->prop_end();
    1301                 :        I != E; ++I) {
    1302              258:     ObjCPropertyDecl *Property = (*I);
    1303              258:     unsigned Attributes = Property->getPropertyAttributes();
    1304                 :     // We only care about readwrite atomic property.
                      205: branch 0 taken
                       53: branch 1 taken
                       29: branch 2 taken
                      176: branch 3 taken
    1305              258:     if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) ||
    1306                 :         !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite))
    1307               82:       continue;
                      141: branch 0 taken
                       35: branch 1 taken
    1308              176:     if (const ObjCPropertyImplDecl *PIDecl
    1309              176:          = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) {
                       41: branch 1 taken
                      100: branch 2 taken
    1310              141:       if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
    1311               41:         continue;
    1312                 :       ObjCMethodDecl *GetterMethod =
    1313              100:         IMPDecl->getInstanceMethod(Property->getGetterName());
    1314                 :       ObjCMethodDecl *SetterMethod = 
    1315              100:         IMPDecl->getInstanceMethod(Property->getSetterName());
                       12: branch 0 taken
                       88: branch 1 taken
                        7: branch 2 taken
                        5: branch 3 taken
                       88: branch 4 taken
                        7: branch 5 taken
                        6: branch 6 taken
                       82: branch 7 taken
    1316              100:       if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) {
    1317                 :         SourceLocation MethodLoc = 
    1318                 :           (GetterMethod ? GetterMethod->getLocation() 
                        5: branch 0 taken
                        6: branch 1 taken
    1319               11:                         : SetterMethod->getLocation());
    1320                 :         Diag(MethodLoc, diag::warn_atomic_property_rule)
    1321               11:           << Property->getIdentifier();
    1322               11:         Diag(Property->getLocation(), diag::note_property_declare);
    1323                 :       }
    1324                 :     }
    1325                 :   }
    1326                 : }
    1327                 : 
    1328                 : /// ActOnForwardClassDeclaration -
    1329                 : Action::DeclPtrTy
    1330                 : Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
    1331                 :                                    IdentifierInfo **IdentList,
    1332                 :                                    SourceLocation *IdentLocs,
    1333              389:                                    unsigned NumElts) {
    1334              389:   llvm::SmallVector<ObjCInterfaceDecl*, 32> Interfaces;
    1335                 : 
                     1256: branch 0 taken
                      389: branch 1 taken
    1336             1645:   for (unsigned i = 0; i != NumElts; ++i) {
    1337                 :     // Check for another declaration kind with the same name.
    1338                 :     NamedDecl *PrevDecl
    1339             1256:       = LookupSingleName(TUScope, IdentList[i], LookupOrdinaryName);
                      182: branch 0 taken
                     1074: branch 1 taken
                        0: branch 3 not taken
                      182: branch 4 taken
                        0: branch 5 not taken
                     1256: branch 6 taken
    1340             1256:     if (PrevDecl && PrevDecl->isTemplateParameter()) {
    1341                 :       // Maybe we will complain about the shadowed template parameter.
    1342                0:       DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);
    1343                 :       // Just pretend that we didn't see the previous declaration.
    1344                0:       PrevDecl = 0;
    1345                 :     }
    1346                 : 
                      182: branch 0 taken
                     1074: branch 1 taken
                        3: branch 3 taken
                      179: branch 4 taken
                        3: branch 5 taken
                     1253: branch 6 taken
    1347             1256:     if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
    1348                 :       // GCC apparently allows the following idiom:
    1349                 :       //
    1350                 :       // typedef NSObject < XCElementTogglerP > XCElementToggler;
    1351                 :       // @class XCElementToggler;
    1352                 :       //
    1353                 :       // FIXME: Make an extension?
    1354                3:       TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
                        3: branch 0 taken
                        0: branch 1 not taken
                        1: branch 4 taken
                        2: branch 5 taken
                        1: branch 6 taken
                        2: branch 7 taken
    1355                3:       if (!TDD || !isa<ObjCInterfaceType>(TDD->getUnderlyingType())) {
    1356                1:         Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
    1357                1:         Diag(PrevDecl->getLocation(), diag::note_previous_definition);
                        2: branch 0 taken
                        0: branch 1 not taken
    1358                2:       } else if (TDD) {
    1359                 :         // a forward class declaration matching a typedef name of a class refers
    1360                 :         // to the underlying class.
                        2: branch 0 taken
                        0: branch 1 not taken
    1361                2:         if (ObjCInterfaceType * OI =
    1362                2:               dyn_cast<ObjCInterfaceType>(TDD->getUnderlyingType()))
    1363                2:           PrevDecl = OI->getDecl();
    1364                 :       }
    1365                 :     }
    1366             1256:     ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
                     1075: branch 0 taken
                      181: branch 1 taken
    1367             1256:     if (!IDecl) {  // Not already seen?  Make a forward decl.
    1368                 :       IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
    1369             1075:                                         IdentList[i], IdentLocs[i], true);
    1370                 :       
    1371                 :       // Push the ObjCInterfaceDecl on the scope chain but do *not* add it to
    1372                 :       // the current DeclContext.  This prevents clients that walk DeclContext
    1373                 :       // from seeing the imaginary ObjCInterfaceDecl until it is actually
    1374                 :       // declared later (if at all).  We also take care to explicitly make
    1375                 :       // sure this declaration is visible for name lookup.
    1376             1075:       PushOnScopeChains(IDecl, TUScope, false);
    1377             1075:       CurContext->makeDeclVisibleInContext(IDecl, true);
    1378                 :     }
    1379                 : 
    1380             1256:     Interfaces.push_back(IDecl);
    1381                 :   }
    1382                 : 
                        0: branch 1 not taken
                      389: branch 2 taken
    1383              389:   assert(Interfaces.size() == NumElts);
    1384                 :   ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
    1385                 :                                                Interfaces.data(), IdentLocs,
    1386              389:                                                Interfaces.size());
    1387              389:   CurContext->addDecl(CDecl);
    1388              389:   CheckObjCDeclScope(CDecl);
    1389              389:   return DeclPtrTy::make(CDecl);
    1390                 : }
    1391                 : 
    1392                 : 
    1393                 : /// MatchTwoMethodDeclarations - Checks that two methods have matching type and
    1394                 : /// returns true, or false, accordingly.
    1395                 : /// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
    1396                 : bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
    1397                 :                                       const ObjCMethodDecl *PrevMethod,
    1398              967:                                       bool matchBasedOnSizeAndAlignment) {
    1399              967:   QualType T1 = Context.getCanonicalType(Method->getResultType());
    1400              967:   QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
    1401                 : 
                      101: branch 1 taken
                      866: branch 2 taken
    1402              967:   if (T1 != T2) {
    1403                 :     // The result types are different.
                       94: branch 0 taken
                        7: branch 1 taken
    1404              101:     if (!matchBasedOnSizeAndAlignment)
    1405               94:       return false;
    1406                 :     // Incomplete types don't have a size and alignment.
                        7: branch 2 taken
                        0: branch 3 not taken
                        3: branch 6 taken
                        4: branch 7 taken
                        3: branch 8 taken
                        4: branch 9 taken
    1407                7:     if (T1->isIncompleteType() || T2->isIncompleteType())
    1408                3:       return false;
    1409                 :     // Check is based on size and alignment.
                        2: branch 3 taken
                        2: branch 4 taken
    1410                4:     if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
    1411                2:       return false;
    1412                 :   }
    1413                 : 
    1414              868:   ObjCMethodDecl::param_iterator ParamI = Method->param_begin(),
    1415              868:        E = Method->param_end();
    1416              868:   ObjCMethodDecl::param_iterator PrevI = PrevMethod->param_begin();
    1417                 : 
                      361: branch 0 taken
                      823: branch 1 taken
    1418             1184:   for (; ParamI != E; ++ParamI, ++PrevI) {
                      361: branch 1 taken
                        0: branch 2 not taken
    1419              361:     assert(PrevI != PrevMethod->param_end() && "Param mismatch");
    1420              361:     T1 = Context.getCanonicalType((*ParamI)->getType());
    1421              361:     T2 = Context.getCanonicalType((*PrevI)->getType());
                       51: branch 1 taken
                      310: branch 2 taken
    1422              361:     if (T1 != T2) {
    1423                 :       // The result types are different.
                       43: branch 0 taken
                        8: branch 1 taken
    1424               51:       if (!matchBasedOnSizeAndAlignment)
    1425               43:         return false;
    1426                 :       // Incomplete types don't have a size and alignment.
                        8: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        8: branch 7 taken
                        0: branch 8 not taken
                        8: branch 9 taken
    1427                8:       if (T1->isIncompleteType() || T2->isIncompleteType())
    1428                0:         return false;
    1429                 :       // Check is based on size and alignment.
                        2: branch 3 taken
                        6: branch 4 taken
    1430                8:       if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
    1431                2:         return false;
    1432                 :     }
    1433                 :   }
    1434              823:   return true;
    1435                 : }
    1436                 : 
    1437                 : /// \brief Read the contents of the instance and factory method pools
    1438                 : /// for a given selector from external storage.
    1439                 : ///
    1440                 : /// This routine should only be called once, when neither the instance
    1441                 : /// nor the factory method pool has an entry for this selector.
    1442                 : Sema::MethodPool::iterator Sema::ReadMethodPool(Selector Sel,
    1443                1:                                                 bool isInstance) {
                        0: branch 0 not taken
                        1: branch 1 taken
    1444                1:   assert(ExternalSource && "We need an external AST source");
    1445                 :   assert(InstanceMethodPool.find(Sel) == InstanceMethodPool.end() &&
                        1: branch 4 taken
                        0: branch 5 not taken
    1446                1:          "Selector data already loaded into the instance method pool");
    1447                 :   assert(FactoryMethodPool.find(Sel) == FactoryMethodPool.end() &&
                        1: branch 4 taken
                        0: branch 5 not taken
    1448                1:          "Selector data already loaded into the factory method pool");
    1449                 : 
    1450                 :   // Read the method list from the external source.
    1451                 :   std::pair<ObjCMethodList, ObjCMethodList> Methods
    1452                1:     = ExternalSource->ReadMethodPool(Sel);
    1453                 : 
                        1: branch 0 taken
                        0: branch 1 not taken
    1454                1:   if (isInstance) {
                        0: branch 0 not taken
                        1: branch 1 taken
    1455                1:     if (Methods.second.Method)
    1456                0:       FactoryMethodPool[Sel] = Methods.second;
    1457                1:     return InstanceMethodPool.insert(std::make_pair(Sel, Methods.first)).first;
    1458                 :   }
    1459                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
    1460                0:   if (Methods.first.Method)
    1461                0:     InstanceMethodPool[Sel] = Methods.first;
    1462                 : 
    1463                0:   return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first;
    1464                 : }
    1465                 : 
    1466             3344: void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
    1467                 :   llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
    1468             3344:     = InstanceMethodPool.find(Method->getSelector());
                     2580: branch 3 taken
                      764: branch 4 taken
    1469             3344:   if (Pos == InstanceMethodPool.end()) {
                        0: branch 0 not taken
                     2580: branch 1 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                     2580: branch 7 taken
    1470             2580:     if (ExternalSource && !FactoryMethodPool.count(Method->getSelector()))
    1471                0:       Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/true);
    1472                 :     else
    1473                 :       Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(),
    1474             2580:                                                      ObjCMethodList())).first;
    1475                 :   }
    1476                 : 
    1477             3344:   ObjCMethodList &Entry = Pos->second;
                     2580: branch 0 taken
                      764: branch 1 taken
    1478             3344:   if (Entry.Method == 0) {
    1479                 :     // Haven't seen a method with this selector name yet - add it.
    1480             2580:     Entry.Method = Method;
    1481             2580:     Entry.Next = 0;
    1482             2580:     return;
    1483                 :   }
    1484                 : 
    1485                 :   // We've seen a method with this name, see if we have already seen this type
    1486                 :   // signature.
                      801: branch 0 taken
                       72: branch 1 taken
    1487              873:   for (ObjCMethodList *List = &Entry; List; List = List->Next)
                      692: branch 1 taken
                      109: branch 2 taken
    1488              801:     if (MatchTwoMethodDeclarations(Method, List->Method))
    1489              692:       return;
    1490                 : 
    1491                 :   // We have a new signature for an existing method - add it.
    1492                 :   // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
    1493               72:   Entry.Next = new ObjCMethodList(Method, Entry.Next);
    1494                 : }
    1495                 : 
    1496                 : // FIXME: Finish implementing -Wno-strict-selector-match.
    1497                 : ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
    1498                 :                                                        SourceRange R,
    1499              534:                                                        bool warn) {
    1500                 :   llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
    1501              534:     = InstanceMethodPool.find(Sel);
                       78: branch 3 taken
                      456: branch 4 taken
    1502              534:   if (Pos == InstanceMethodPool.end()) {
                        1: branch 0 taken
                       77: branch 1 taken
                        1: branch 3 taken
                        0: branch 4 not taken
                        1: branch 5 taken
                       77: branch 6 taken
    1503               78:     if (ExternalSource && !FactoryMethodPool.count(Sel))
    1504                1:       Pos = ReadMethodPool(Sel, /*isInstance=*/true);
    1505                 :     else
    1506               77:       return 0;
    1507                 :   }
    1508                 : 
    1509              457:   ObjCMethodList &MethList = Pos->second;
    1510              457:   bool issueWarning = false;
    1511                 : 
                      457: branch 0 taken
                        0: branch 1 not taken
                       13: branch 2 taken
                      444: branch 3 taken
    1512              457:   if (MethList.Method && MethList.Next) {
                       15: branch 0 taken
                       13: branch 1 taken
    1513               28:     for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
    1514                 :       // This checks if the methods differ by size & alignment.
                        7: branch 1 taken
                        8: branch 2 taken
    1515               15:       if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
    1516                7:         issueWarning = warn;
    1517                 :   }
                        6: branch 0 taken
                      451: branch 1 taken
                        6: branch 2 taken
                        0: branch 3 not taken
                        6: branch 4 taken
                        0: branch 5 not taken
    1518              457:   if (issueWarning && (MethList.Method && MethList.Next)) {
    1519                6:     Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
    1520                 :     Diag(MethList.Method->getLocStart(), diag::note_using)
    1521                6:       << MethList.Method->getSourceRange();
                        8: branch 0 taken
                        6: branch 1 taken
    1522               14:     for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
    1523                 :       Diag(Next->Method->getLocStart(), diag::note_also_found)
    1524                8:         << Next->Method->getSourceRange();
    1525                 :   }
    1526              457:   return MethList.Method;
    1527                 : }
    1528                 : 
    1529              579: void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
    1530                 :   llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
    1531              579:     = FactoryMethodPool.find(Method->getSelector());
                      451: branch 3 taken
                      128: branch 4 taken
    1532              579:   if (Pos == FactoryMethodPool.end()) {
                        0: branch 0 not taken
                      451: branch 1 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                      451: branch 7 taken
    1533              451:     if (ExternalSource && !InstanceMethodPool.count(Method->getSelector()))
    1534                0:       Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/false);
    1535                 :     else
    1536                 :       Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(),
    1537              451:                                                     ObjCMethodList())).first;
    1538                 :   }
    1539                 : 
    1540              579:   ObjCMethodList &FirstMethod = Pos->second;
                      451: branch 0 taken
                      128: branch 1 taken
    1541              579:   if (!FirstMethod.Method) {
    1542                 :     // Haven't seen a method with this selector name yet - add it.
    1543              451:     FirstMethod.Method = Method;
    1544              451:     FirstMethod.Next = 0;
    1545                 :   } else {
    1546                 :     // We've seen a method with this name, now check the type signature(s).
    1547              128:     bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
    1548                 : 
                       19: branch 0 taken
                      113: branch 1 taken
                        4: branch 2 taken
                       15: branch 3 taken
    1549              132:     for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
    1550                 :          Next = Next->Next)
    1551                4:       match = MatchTwoMethodDeclarations(Method, Next->Method);
    1552                 : 
                       15: branch 0 taken
                      113: branch 1 taken
    1553              128:     if (!match) {
    1554                 :       // We have a new signature for an existing method - add it.
    1555                 :       // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
    1556               15:       struct ObjCMethodList *OMI = new ObjCMethodList(Method, FirstMethod.Next);
    1557               15:       FirstMethod.Next = OMI;
    1558                 :     }
    1559                 :   }
    1560              579: }
    1561                 : 
    1562                 : ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
    1563               74:                                                       SourceRange R) {
    1564                 :   llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
    1565               74:     = FactoryMethodPool.find(Sel);
                       55: branch 3 taken
                       19: branch 4 taken
    1566               74:   if (Pos == FactoryMethodPool.end()) {
                        0: branch 0 not taken
                       55: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                       55: branch 6 taken
    1567               55:     if (ExternalSource && !InstanceMethodPool.count(Sel))
    1568                0:       Pos = ReadMethodPool(Sel, /*isInstance=*/false);
    1569                 :     else
    1570               55:       return 0;
    1571                 :   }
    1572                 : 
    1573               19:   ObjCMethodList &MethList = Pos->second;
    1574               19:   bool issueWarning = false;
    1575                 : 
                       19: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                       19: branch 3 taken
    1576               19:   if (MethList.Method && MethList.Next) {
                        0: branch 0 not taken
                        0: branch 1 not taken
    1577                0:     for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
    1578                 :       // This checks if the methods differ by size & alignment.
                        0: branch 1 not taken
                        0: branch 2 not taken
    1579                0:       if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
    1580                0:         issueWarning = true;
    1581                 :   }
                        0: branch 0 not taken
                       19: branch 1 taken
                       19: branch 2 taken
                       19: branch 3 taken
                       19: branch 4 taken
                       19: branch 5 taken
    1582               19:   if (issueWarning && (MethList.Method && MethList.Next)) {
    1583                0:     Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
    1584                 :     Diag(MethList.Method->getLocStart(), diag::note_using)
    1585                0:       << MethList.Method->getSourceRange();
                        0: branch 0 not taken
                        0: branch 1 not taken
    1586                0:     for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
    1587                 :       Diag(Next->Method->getLocStart(), diag::note_also_found)
    1588                0:         << Next->Method->getSourceRange();
    1589                 :   }
    1590               19:   return MethList.Method;
    1591                 : }
    1592                 : 
    1593                 : /// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods
    1594                 : /// have the property type and issue diagnostics if they don't.
    1595                 : /// Also synthesize a getter/setter method if none exist (and update the
    1596                 : /// appropriate lookup tables. FIXME: Should reconsider if adding synthesized
    1597                 : /// methods is the "right" thing to do.
    1598                 : void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
    1599              480:                                ObjCContainerDecl *CD) {
    1600                 :   ObjCMethodDecl *GetterMethod, *SetterMethod;
    1601                 : 
    1602              480:   GetterMethod = CD->getInstanceMethod(property->getGetterName());
    1603              480:   SetterMethod = CD->getInstanceMethod(property->getSetterName());
    1604                 :   DiagnosePropertyAccessorMismatch(property, GetterMethod,
    1605              480:                                    property->getLocation());
    1606                 : 
                        8: branch 0 taken
                      472: branch 1 taken
    1607              480:   if (SetterMethod) {
    1608                 :     ObjCPropertyDecl::PropertyAttributeKind CAttr = 
    1609                8:       property->getPropertyAttributes();
                        6: branch 0 taken
                        2: branch 1 taken
                        0: branch 5 not taken
                        6: branch 6 taken
                        0: branch 7 not taken
                        8: branch 8 taken
    1610                8:     if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) &&
    1611                 :         Context.getCanonicalType(SetterMethod->getResultType()) != 
    1612                 :           Context.VoidTy)
    1613                0:       Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
                        8: branch 1 taken
                        0: branch 2 not taken
                        0: branch 7 not taken
                        8: branch 8 taken
                        0: branch 9 not taken
                        8: branch 10 taken
    1614                8:     if (SetterMethod->param_size() != 1 ||
    1615                 :         ((*SetterMethod->param_begin())->getType() != property->getType())) {
    1616                 :       Diag(property->getLocation(),
    1617                 :            diag::warn_accessor_property_type_mismatch)
    1618                 :         << property->getDeclName()
    1619                0:         << SetterMethod->getSelector();
    1620                0:       Diag(SetterMethod->getLocation(), diag::note_declared_at);
    1621                 :     }
    1622                 :   }
    1623                 : 
    1624                 :   // Synthesize getter/setter methods if none exist.
    1625                 :   // Find the default getter and if one not found, add one.
    1626                 :   // FIXME: The synthesized property we set here is misleading. We almost always
    1627                 :   // synthesize these methods unless the user explicitly provided prototypes
    1628                 :   // (which is odd, but allowed). Sema should be typechecking that the
    1629                 :   // declarations jive in that situation (which it is not currently).
                      439: branch 0 taken
                       41: branch 1 taken
    1630              480:   if (!GetterMethod) {
    1631                 :     // No instance method of same name as property getter name was found.
    1632                 :     // Declare a getter method and add it to the list of methods
    1633                 :     // for this class.
    1634                 :     GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
    1635                 :                              property->getLocation(), property->getGetterName(),
    1636                 :                              property->getType(), CD, true, false, true,
    1637                 :                              (property->getPropertyImplementation() ==
    1638                 :                               ObjCPropertyDecl::Optional) ?
    1639                 :                              ObjCMethodDecl::Optional :
                        9: branch 1 taken
                      430: branch 2 taken
                      439: branch 3 taken
                        0: branch 4 not taken
    1640              439:                              ObjCMethodDecl::Required);
    1641              439:     CD->addDecl(GetterMethod);
    1642                 :   } else
    1643                 :     // A user declared getter will be synthesize when @synthesize of
    1644                 :     // the property with the same name is seen in the @implementation
    1645               41:     GetterMethod->setSynthesized(true);
    1646              480:   property->setGetterMethodDecl(GetterMethod);
    1647                 : 
    1648                 :   // Skip setter if property is read-only.
                      376: branch 1 taken
                      104: branch 2 taken
    1649              480:   if (!property->isReadOnly()) {
    1650                 :     // Find the default setter and if one not found, add one.
                      370: branch 0 taken
                        6: branch 1 taken
    1651              376:     if (!SetterMethod) {
    1652                 :       // No instance method of same name as property setter name was found.
    1653                 :       // Declare a setter method and add it to the list of methods
    1654                 :       // for this class.
    1655                 :       SetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
    1656                 :                                property->getLocation(),
    1657                 :                                property->getSetterName(),
    1658                 :                                Context.VoidTy, CD, true, false, true,
    1659                 :                                (property->getPropertyImplementation() ==
    1660                 :                                 ObjCPropertyDecl::Optional) ?
    1661                 :                                ObjCMethodDecl::Optional :
                        9: branch 1 taken
                      361: branch 2 taken
                      370: branch 3 taken
                        0: branch 4 not taken
    1662              370:                                ObjCMethodDecl::Required);
    1663                 :       // Invent the arguments for the setter. We don't bother making a
    1664                 :       // nice name for the argument.
    1665                 :       ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
    1666                 :                                                   property->getLocation(),
    1667                 :                                                   property->getIdentifier(),
    1668                 :                                                   property->getType(),
    1669                 :                                                   /*TInfo=*/0,
    1670                 :                                                   VarDecl::None,
                      370: branch 3 taken
                        0: branch 4 not taken
    1671              370:                                                   0);
    1672              370:       SetterMethod->setMethodParams(Context, &Argument, 1);
    1673              370:       CD->addDecl(SetterMethod);
    1674                 :     } else
    1675                 :       // A user declared setter will be synthesize when @synthesize of
    1676                 :       // the property with the same name is seen in the @implementation
    1677                6:       SetterMethod->setSynthesized(true);
    1678              376:     property->setSetterMethodDecl(SetterMethod);
    1679                 :   }
    1680                 :   // Add any synthesized methods to the global pool. This allows us to
    1681                 :   // handle the following, which is supported by GCC (and part of the design).
    1682                 :   //
    1683                 :   // @interface Foo
    1684                 :   // @property double bar;
    1685                 :   // @end
    1686                 :   //
    1687                 :   // void thisIsUnfortunate() {
    1688                 :   //   id foo;
    1689                 :   //   double bar = [foo bar];
    1690                 :   // }
    1691                 :   //
                      480: branch 0 taken
                        0: branch 1 not taken
    1692              480:   if (GetterMethod)
    1693              480:     AddInstanceMethodToGlobalPool(GetterMethod);
                      378: branch 0 taken
                      102: branch 1 taken
    1694              480:   if (SetterMethod)
    1695              378:     AddInstanceMethodToGlobalPool(SetterMethod);
    1696              480: }
    1697                 : 
    1698                 : /// CompareMethodParamsInBaseAndSuper - This routine compares methods with
    1699                 : /// identical selector names in current and its super classes and issues
    1700                 : /// a warning if any of their argument types are incompatible.
    1701                 : void Sema::CompareMethodParamsInBaseAndSuper(Decl *ClassDecl,
    1702                 :                                              ObjCMethodDecl *Method,
    1703             2152:                                              bool IsInstance)  {
    1704             2152:   ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ClassDecl);
                     1365: branch 0 taken
                      787: branch 1 taken
    1705             2152:   if (ID == 0) return;
    1706                 : 
                      765: branch 1 taken
                     1359: branch 2 taken
    1707             2883:   while (ObjCInterfaceDecl *SD = ID->getSuperClass()) {
    1708                 :     ObjCMethodDecl *SuperMethodDecl =
    1709              765:         SD->lookupMethod(Method->getSelector(), IsInstance);
                      740: branch 0 taken
                       25: branch 1 taken
    1710              765:     if (SuperMethodDecl == 0) {
    1711              740:       ID = SD;
    1712              740:       continue;
    1713                 :     }
    1714               25:     ObjCMethodDecl::param_iterator ParamI = Method->param_begin(),
    1715               25:       E = Method->param_end();
    1716               25:     ObjCMethodDecl::param_iterator PrevI = SuperMethodDecl->param_begin();
                       18: branch 0 taken
                       19: branch 1 taken
    1717               37:     for (; ParamI != E; ++ParamI, ++PrevI) {
    1718                 :       // Number of parameters are the same and is guaranteed by selector match.
                       18: branch 1 taken
                        0: branch 2 not taken
    1719               18:       assert(PrevI != SuperMethodDecl->param_end() && "Param mismatch");
    1720               18:       QualType T1 = Context.getCanonicalType((*ParamI)->getType());
    1721               18:       QualType T2 = Context.getCanonicalType((*PrevI)->getType());
    1722                 :       // If type of arguement of method in this class does not match its
    1723                 :       // respective argument type in the super class method, issue warning;
                        6: branch 1 taken
                       12: branch 2 taken
    1724               18:       if (!Context.typesAreCompatible(T1, T2)) {
    1725                 :         Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)
    1726                6:           << T1 << T2;
    1727                6:         Diag(SuperMethodDecl->getLocation(), diag::note_previous_declaration);
    1728                6:         return;
    1729                 :       }
    1730                 :     }
    1731               19:     ID = SD;
    1732                 :   }
    1733                 : }
    1734                 : 
    1735                 : // Note: For class/category implemenations, allMethods/allProperties is
    1736                 : // always null.
    1737                 : void Sema::ActOnAtEnd(SourceRange AtEnd,
    1738                 :                       DeclPtrTy classDecl,
    1739                 :                       DeclPtrTy *allMethods, unsigned allNum,
    1740                 :                       DeclPtrTy *allProperties, unsigned pNum,
    1741             3039:                       DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
    1742             3039:   Decl *ClassDecl = classDecl.getAs<Decl>();
    1743                 : 
    1744                 :   // FIXME: If we don't have a ClassDecl, we have an error. We should consider
    1745                 :   // always passing in a decl. If the decl has an error, isInvalidDecl()
    1746                 :   // should be true.
                        0: branch 0 not taken
                     3039: branch 1 taken
    1747             3039:   if (!ClassDecl)
    1748                0:     return;
    1749                 :   
    1750                 :   bool isInterfaceDeclKind =
    1751                 :         isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
                     1485: branch 1 taken
                     1554: branch 2 taken
                     1300: branch 4 taken
                      185: branch 5 taken
                      659: branch 7 taken
                      641: branch 8 taken
    1752             3039:          || isa<ObjCProtocolDecl>(ClassDecl);
    1753             3039:   bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
    1754                 : 
                      641: branch 0 taken
                     2398: branch 1 taken
                       15: branch 3 taken
                      626: branch 4 taken
                       15: branch 5 taken
                     3024: branch 6 taken
    1755             3039:   if (!isInterfaceDeclKind && AtEnd.isInvalid()) {
    1756                 :     // FIXME: This is wrong.  We shouldn't be pretending that there is
    1757                 :     //  an '@end' in the declaration.
    1758               15:     SourceLocation L = ClassDecl->getLocation();
    1759               15:     AtEnd.setBegin(L);
    1760               15:     AtEnd.setEnd(L);
    1761               15:     Diag(L, diag::warn_missing_atend);
    1762                 :   }
    1763                 :   
    1764             3039:   DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
    1765                 : 
    1766                 :   // FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
    1767             3039:   llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
    1768             3039:   llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
    1769                 : 
                     2162: branch 0 taken
                     3039: branch 1 taken
    1770             5201:   for (unsigned i = 0; i < allNum; i++ ) {
    1771                 :     ObjCMethodDecl *Method =
    1772             2162:       cast_or_null<ObjCMethodDecl>(allMethods[i].getAs<Decl>());
    1773                 : 
                     2159: branch 0 taken
                        3: branch 1 taken
    1774             2162:     if (!Method) continue;  // Already issued a diagnostic.
                     1756: branch 1 taken
                      403: branch 2 taken
    1775             2159:     if (Method->isInstanceMethod()) {
    1776                 :       /// Check for instance method of the same name with incompatible types
    1777             1756:       const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
    1778                 :       bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
                       13: branch 0 taken
                     1743: branch 1 taken
    1779             1756:                               : false;
                     1756: branch 0 taken
                        0: branch 1 not taken
                       13: branch 2 taken
                     1743: branch 3 taken
                        8: branch 4 taken
                        5: branch 5 taken
                        0: branch 6 not taken
                     1751: branch 7 taken
                     1751: branch 8 taken
                     1751: branch 9 taken
    1780             1761:       if ((isInterfaceDeclKind && PrevMethod && !match)
    1781                 :           || (checkIdenticalMethods && match)) {
    1782                 :           Diag(Method->getLocation(), diag::err_duplicate_method_decl)
    1783                5:             << Method->getDeclName();
    1784                5:           Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
    1785                 :       } else {
    1786             1751:         DC->addDecl(Method);
    1787             1751:         InsMap[Method->getSelector()] = Method;
    1788                 :         /// The following allows us to typecheck messages to "id".
    1789             1751:         AddInstanceMethodToGlobalPool(Method);
    1790                 :         // verify that the instance method conforms to the same definition of
    1791                 :         // parent methods if it shadows one.
    1792             1751:         CompareMethodParamsInBaseAndSuper(ClassDecl, Method, true);
    1793                 :       }
    1794                 :     } else {
    1795                 :       /// Check for class method of the same name with incompatible types
    1796              403:       const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
    1797                 :       bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
                        2: branch 0 taken
                      401: branch 1 taken
    1798              403:                               : false;
                      403: branch 0 taken
                        0: branch 1 not taken
                        2: branch 2 taken
                      401: branch 3 taken
                        0: branch 4 not taken
                        2: branch 5 taken
                        0: branch 6 not taken
                      401: branch 7 taken
                      401: branch 8 taken
                      401: branch 9 taken
    1799              405:       if ((isInterfaceDeclKind && PrevMethod && !match)
    1800                 :           || (checkIdenticalMethods && match)) {
    1801                 :         Diag(Method->getLocation(), diag::err_duplicate_method_decl)
    1802                2:           << Method->getDeclName();
    1803                2:         Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
    1804                 :       } else {
    1805              401:         DC->addDecl(Method);
    1806              401:         ClsMap[Method->getSelector()] = Method;
    1807                 :         /// The following allows us to typecheck messages to "Class".
    1808              401:         AddFactoryMethodToGlobalPool(Method);
    1809                 :         // verify that the class method conforms to the same definition of
    1810                 :         // parent methods if it shadows one.
    1811              401:         CompareMethodParamsInBaseAndSuper(ClassDecl, Method, false);
    1812                 :       }
    1813                 :     }
    1814                 :   }
                     1554: branch 1 taken
                     1485: branch 2 taken
    1815             3039:   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
    1816                 :     // Compares properties declared in this class to those of its
    1817                 :     // super class.
    1818             1554:     ComparePropertiesInBaseAndSuper(I);
    1819             1554:     CompareProperties(I, DeclPtrTy::make(I));
                      185: branch 1 taken
                     1300: branch 2 taken
    1820             1485:   } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
    1821                 :     // Categories are used to extend the class by declaring new methods.
    1822                 :     // By the same token, they are also used to add new properties. No
    1823                 :     // need to compare the added property to those in the class.
    1824                 : 
    1825                 :     // Compare protocol properties with those in category
    1826              185:     CompareProperties(C, DeclPtrTy::make(C));
                       29: branch 1 taken
                      156: branch 2 taken
    1827              185:     if (C->getIdentifier() == 0)
    1828               29:       DiagnoseClassExtensionDupMethods(C, C->getClassInterface());
    1829                 :   }
                     3039: branch 1 taken
                        0: branch 2 not taken
    1830             3039:   if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
    1831                 :     // ProcessPropertyDecl is responsible for diagnosing conflicts with any
    1832                 :     // user-defined setter/getter. It also synthesizes setter/getter methods
    1833                 :     // and adds them to the DeclContext and global method pools.
                      433: branch 3 taken
                     3039: branch 4 taken
    1834             6511:     for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
    1835             3039:                                           E = CDecl->prop_end();
    1836                 :          I != E; ++I)
    1837              433:       ProcessPropertyDecl(*I, CDecl);
    1838             3039:     CDecl->setAtEndRange(AtEnd);
    1839                 :   }
                      573: branch 1 taken
                     2466: branch 2 taken
    1840             3039:   if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
    1841              573:     IC->setAtEndRange(AtEnd);
                      573: branch 1 taken
                        0: branch 2 not taken
    1842              573:     if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
    1843              573:       ImplMethodsVsClassMethods(IC, IDecl);
    1844              573:       AtomicPropertySetterGetterRules(IC, IDecl);
    1845                 :     }
                       68: branch 0 taken
                     2398: branch 1 taken
    1846             2466:   } else if (ObjCCategoryImplDecl* CatImplClass =
    1847             2466:                                    dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
    1848               68:     CatImplClass->setAtEndRange(AtEnd);
    1849                 : 
    1850                 :     // Find category interface decl and then check that all methods declared
    1851                 :     // in this interface are implemented in the category @implementation.
                       65: branch 1 taken
                        3: branch 2 taken
    1852               68:     if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {
                       67: branch 2 taken
                        0: branch 3 not taken
    1853               67:       for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
    1854                 :            Categories; Categories = Categories->getNextClassCategory()) {
                       65: branch 2 taken
                        2: branch 3 taken
    1855               67:         if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
    1856               65:           ImplMethodsVsClassMethods(CatImplClass, Categories);
    1857               65:           break;
    1858                 :         }
    1859                 :       }
    1860                 :     }
    1861                 :   }
                     2398: branch 0 taken
                      641: branch 1 taken
    1862             3039:   if (isInterfaceDeclKind) {
    1863                 :     // Reject invalid vardecls.
                       13: branch 0 taken
                     2398: branch 1 taken
    1864             2411:     for (unsigned i = 0; i != tuvNum; i++) {
    1865               13:       DeclGroupRef DG = allTUVars[i].getAsVal<DeclGroupRef>();
                       12: branch 2 taken
                       13: branch 3 taken
    1866               25:       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
                        7: branch 1 taken
                        5: branch 2 taken
    1867               12:         if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
                        5: branch 1 taken
                        2: branch 2 taken
    1868                7:           if (!VDecl->hasExternalStorage())
    1869                5:             Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);
    1870                 :         }
    1871                 :     }
    1872             3039:   }
    1873                 : }
    1874                 : 
    1875                 : 
    1876                 : /// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
    1877                 : /// objective-c's type qualifier from the parser version of the same info.
    1878                 : static Decl::ObjCDeclQualifier
    1879             4857: CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
    1880             4857:   Decl::ObjCDeclQualifier ret = Decl::OBJC_TQ_None;
                        2: branch 0 taken
                     4855: branch 1 taken
    1881             4857:   if (PQTVal & ObjCDeclSpec::DQ_In)
    1882                2:     ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_In);
                        2: branch 0 taken
                     4855: branch 1 taken
    1883             4857:   if (PQTVal & ObjCDeclSpec::DQ_Inout)
    1884                2:     ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Inout);
                        4: branch 0 taken
                     4853: branch 1 taken
    1885             4857:   if (PQTVal & ObjCDeclSpec::DQ_Out)
    1886                4:     ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Out);
                        7: branch 0 taken
                     4850: branch 1 taken
    1887             4857:   if (PQTVal & ObjCDeclSpec::DQ_Bycopy)
    1888                7:     ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Bycopy);
                        2: branch 0 taken
                     4855: branch 1 taken
    1889             4857:   if (PQTVal & ObjCDeclSpec::DQ_Byref)
    1890                2:     ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Byref);
                       30: branch 0 taken
                     4827: branch 1 taken
    1891             4857:   if (PQTVal & ObjCDeclSpec::DQ_Oneway)
    1892               30:     ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Oneway);
    1893                 : 
    1894             4857:   return ret;
    1895                 : }
    1896                 : 
    1897                 : Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
    1898                 :     SourceLocation MethodLoc, SourceLocation EndLoc,
    1899                 :     tok::TokenKind MethodType, DeclPtrTy classDecl,
    1900                 :     ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
    1901                 :     Selector Sel,
    1902                 :     // optional arguments. The number of types/arguments is obtained
    1903                 :     // from the Sel.getNumArgs().
    1904                 :     ObjCArgInfo *ArgInfo,
    1905                 :     llvm::SmallVectorImpl<Declarator> &Cdecls,
    1906                 :     AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
    1907             3078:     bool isVariadic) {
    1908             3078:   Decl *ClassDecl = classDecl.getAs<Decl>();
    1909                 : 
    1910                 :   // Make sure we can establish a context for the method.
                        4: branch 0 taken
                     3074: branch 1 taken
    1911             3078:   if (!ClassDecl) {
    1912                4:     Diag(MethodLoc, diag::error_missing_method_context);
    1913                4:     FunctionLabelMap.clear();
    1914                4:     return DeclPtrTy();
    1915                 :   }
    1916             3074:   QualType resultDeclType;
    1917                 : 
                     2866: branch 0 taken
                      208: branch 1 taken
    1918             3074:   if (ReturnType) {
    1919             2866:     resultDeclType = GetTypeFromParser(ReturnType);
    1920                 : 
    1921                 :     // Methods cannot return interface types. All ObjC objects are
    1922                 :     // passed by reference.
                        2: branch 2 taken
                     2864: branch 3 taken
    1923             2866:     if (resultDeclType->isObjCInterfaceType()) {
    1924                 :       Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
    1925                2:         << 0 << resultDeclType;
    1926                2:       return DeclPtrTy();
    1927                 :     }
    1928                 :   } else // get the type for "id".
    1929              208:     resultDeclType = Context.getObjCIdType();
    1930                 : 
    1931                 :   ObjCMethodDecl* ObjCMethod =
    1932                 :     ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
    1933                 :                            cast<DeclContext>(ClassDecl),
    1934                 :                            MethodType == tok::minus, isVariadic,
    1935                 :                            false,
    1936                 :                            MethodDeclKind == tok::objc_optional ?
    1937                 :                            ObjCMethodDecl::Optional :
                       22: branch 0 taken
                     3050: branch 1 taken
    1938             3072:                            ObjCMethodDecl::Required);
    1939                 : 
    1940             3072:   llvm::SmallVector<ParmVarDecl*, 16> Params;
    1941                 : 
                     1785: branch 1 taken
                     3072: branch 2 taken
    1942             4857:   for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
    1943             1785:     QualType ArgType;
    1944                 :     TypeSourceInfo *DI;
    1945                 : 
                       22: branch 0 taken
                     1763: branch 1 taken
    1946             1785:     if (ArgInfo[i].Type == 0) {
    1947               22:       ArgType = Context.getObjCIdType();
    1948               22:       DI = 0;
    1949                 :     } else {
    1950             1763:       ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI);
    1951                 :       // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
    1952             1763:       ArgType = adjustParameterType(ArgType);
    1953                 :     }
    1954                 : 
    1955                 :     ParmVarDecl* Param
    1956                 :       = ParmVarDecl::Create(Context, ObjCMethod, ArgInfo[i].NameLoc,
    1957                 :                             ArgInfo[i].Name, ArgType, DI,
                     1785: branch 0 taken
                        0: branch 1 not taken
    1958             1785:                             VarDecl::None, 0);
    1959                 : 
                        2: branch 2 taken
                     1783: branch 3 taken
    1960             1785:     if (ArgType->isObjCInterfaceType()) {
    1961                 :       Diag(ArgInfo[i].NameLoc,
    1962                 :            diag::err_object_cannot_be_passed_returned_by_value)
    1963                2:         << 1 << ArgType;
    1964                2:       Param->setInvalidDecl();
    1965                 :     }
    1966                 : 
    1967                 :     Param->setObjCDeclQualifier(
    1968             1785:       CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
    1969                 : 
    1970                 :     // Apply the attributes to the parameter.
    1971             1785:     ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
    1972                 : 
    1973             1785:     Params.push_back(Param);
    1974                 :   }
    1975                 : 
    1976             3072:   ObjCMethod->setMethodParams(Context, Params.data(), Sel.getNumArgs());
    1977                 :   ObjCMethod->setObjCDeclQualifier(
    1978             3072:     CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
    1979             3072:   const ObjCMethodDecl *PrevMethod = 0;
    1980                 : 
                       55: branch 0 taken
                     3017: branch 1 taken
    1981             3072:   if (AttrList)
    1982               55:     ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
    1983                 : 
    1984             3072:   const ObjCMethodDecl *InterfaceMD = 0;
    1985                 : 
    1986                 :   // For implementations (which can be very "coarse grain"), we add the
    1987                 :   // method now. This allows the AST to implement lookup methods that work
    1988                 :   // incrementally (without waiting until we parse the @end). It also allows
    1989                 :   // us to flag multiple declaration errors as they occur.
                      856: branch 0 taken
                     2216: branch 1 taken
    1990             3072:   if (ObjCImplementationDecl *ImpDecl =
    1991             3072:         dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
                      692: branch 0 taken
                      164: branch 1 taken
    1992              856:     if (MethodType == tok::minus) {
    1993              692:       PrevMethod = ImpDecl->getInstanceMethod(Sel);
    1994              692:       ImpDecl->addInstanceMethod(ObjCMethod);
    1995                 :     } else {
    1996              164:       PrevMethod = ImpDecl->getClassMethod(Sel);
    1997              164:       ImpDecl->addClassMethod(ObjCMethod);
    1998                 :     }
    1999                 :     InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
    2000              856:                                                    MethodType == tok::minus);
                        3: branch 0 taken
                      853: branch 1 taken
    2001              856:     if (AttrList)
    2002                3:       Diag(EndLoc, diag::warn_attribute_method_def);
                       57: branch 0 taken
                     2159: branch 1 taken
    2003             2216:   } else if (ObjCCategoryImplDecl *CatImpDecl =
    2004             2216:              dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
                       43: branch 0 taken
                       14: branch 1 taken
    2005               57:     if (MethodType == tok::minus) {
    2006               43:       PrevMethod = CatImpDecl->getInstanceMethod(Sel);
    2007               43:       CatImpDecl->addInstanceMethod(ObjCMethod);
    2008                 :     } else {
    2009               14:       PrevMethod = CatImpDecl->getClassMethod(Sel);
    2010               14:       CatImpDecl->addClassMethod(ObjCMethod);
    2011                 :     }
                        0: branch 0 not taken
                       57: branch 1 taken
    2012               57:     if (AttrList)
    2013                0:       Diag(EndLoc, diag::warn_attribute_method_def);
    2014                 :   }
                        1: branch 0 taken
                     3071: branch 1 taken
    2015             3072:   if (PrevMethod) {
    2016                 :     // You can never have two method definitions with the same name.
    2017                 :     Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)
    2018                1:       << ObjCMethod->getDeclName();
    2019                1:     Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
    2020                 :   }
    2021                 : 
    2022                 :   // If the interface declared this method, and it was deprecated there,
    2023                 :   // mark it deprecated here.
                      513: branch 0 taken
                     2559: branch 1 taken
                        4: branch 3 taken
                      509: branch 4 taken
                        4: branch 5 taken
                     3068: branch 6 taken
    2024             3072:   if (InterfaceMD && InterfaceMD->hasAttr<DeprecatedAttr>())
                        4: branch 1 taken
                        0: branch 2 not taken
    2025                4:     ObjCMethod->addAttr(::new (Context) DeprecatedAttr());
    2026                 : 
    2027             3072:   return DeclPtrTy::make(ObjCMethod);
    2028                 : }
    2029                 : 
    2030                 : void Sema::CheckObjCPropertyAttributes(QualType PropertyTy,
    2031                 :                                        SourceLocation Loc,
    2032              483:                                        unsigned &Attributes) {
    2033                 :   // FIXME: Improve the reported location.
    2034                 : 
    2035                 :   // readonly and readwrite/assign/retain/copy conflict.
                      107: branch 0 taken
                      376: branch 1 taken
                       13: branch 2 taken
                       94: branch 3 taken
    2036              483:   if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
    2037                 :       (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
    2038                 :                      ObjCDeclSpec::DQ_PR_assign |
    2039                 :                      ObjCDeclSpec::DQ_PR_copy |
    2040                 :                      ObjCDeclSpec::DQ_PR_retain))) {
    2041                 :     const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ?
    2042                 :                           "readwrite" :
    2043                 :                          (Attributes & ObjCDeclSpec::DQ_PR_assign) ?
    2044                 :                           "assign" :
    2045                 :                          (Attributes & ObjCDeclSpec::DQ_PR_copy) ?
                       11: branch 0 taken
                        2: branch 1 taken
                        9: branch 2 taken
                        2: branch 3 taken
                        4: branch 4 taken
                        5: branch 5 taken
    2046               13:                           "copy" : "retain";
    2047                 : 
    2048                 :     Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ?
    2049                 :                  diag::err_objc_property_attr_mutually_exclusive :
    2050                 :                  diag::warn_objc_property_attr_mutually_exclusive)
                        2: branch 0 taken
                       11: branch 1 taken
    2051               13:       << "readonly" << which;
    2052                 :   }
    2053                 : 
    2054                 :   // Check for copy or retain on non-object types.
                      103: branch 0 taken
                      380: branch 1 taken
                        7: branch 4 taken
                       96: branch 5 taken
                        5: branch 8 taken
                        2: branch 9 taken
                        3: branch 11 taken
                        2: branch 12 taken
                        3: branch 13 taken
                      480: branch 14 taken
    2055              483:   if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) &&
    2056                 :       !PropertyTy->isObjCObjectPointerType() &&
    2057                 :       !PropertyTy->isBlockPointerType() &&
    2058                 :       !Context.isObjCNSObjectType(PropertyTy)) {
    2059                 :     Diag(Loc, diag::err_objc_property_requires_object)
                        2: branch 0 taken
                        1: branch 1 taken
    2060                3:       << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain");
    2061                3:     Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain);
    2062                 :   }
    2063                 : 
    2064                 :   // Check for more than one of { assign, copy, retain }.
                       78: branch 0 taken
                      405: branch 1 taken
    2065              483:   if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
                        3: branch 0 taken
                       75: branch 1 taken
    2066               78:     if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
    2067                 :       Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
    2068                3:         << "assign" << "copy";
    2069                3:       Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
    2070                 :     }
                        3: branch 0 taken
                       75: branch 1 taken
    2071               78:     if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
    2072                 :       Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
    2073                3:         << "assign" << "retain";
    2074                3:       Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
    2075                 :     }
                       47: branch 0 taken
                      358: branch 1 taken
    2076              405:   } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
                        2: branch 0 taken
                       45: branch 1 taken
    2077               47:     if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
    2078                 :       Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
    2079                2:         << "copy" << "retain";
    2080                2:       Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
    2081                 :     }
    2082                 :   }
    2083                 : 
    2084                 :   // Warn if user supplied no assignment attribute, property is
    2085                 :   // readwrite, and this is an object type.
                      310: branch 0 taken
                      173: branch 1 taken
                      214: branch 2 taken
                       96: branch 3 taken
                       17: branch 6 taken
                      197: branch 7 taken
                       17: branch 8 taken
                      466: branch 9 taken
    2086              483:   if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
    2087                 :                       ObjCDeclSpec::DQ_PR_retain)) &&
    2088                 :       !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
    2089                 :       PropertyTy->isObjCObjectPointerType()) {
    2090                 :     // Skip this warning in gc-only mode.
                       17: branch 2 taken
                        0: branch 3 not taken
    2091               17:     if (getLangOptions().getGCMode() != LangOptions::GCOnly)
    2092               17:       Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
    2093                 : 
    2094                 :     // If non-gc code warn that this is likely inappropriate.
                       10: branch 2 taken
                        7: branch 3 taken
    2095               17:     if (getLangOptions().getGCMode() == LangOptions::NonGC)
    2096               10:       Diag(Loc, diag::warn_objc_property_default_assign_on_object);
    2097                 : 
    2098                 :     // FIXME: Implement warning dependent on NSCopying being
    2099                 :     // implemented. See also:
    2100                 :     // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
    2101                 :     // (please trim this list while you are at it).
    2102                 :   }
    2103                 : 
                      436: branch 0 taken
                       47: branch 1 taken
                        2: branch 4 taken
                      434: branch 5 taken
                        1: branch 8 taken
                        1: branch 9 taken
                        1: branch 10 taken
                      482: branch 11 taken
    2104              483:   if (!(Attributes & ObjCDeclSpec::DQ_PR_copy)
    2105                 :       && getLangOptions().getGCMode() == LangOptions::GCOnly
    2106                 :       && PropertyTy->isBlockPointerType())
    2107                1:     Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
    2108              483: }
    2109                 : 
    2110                 : Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
    2111                 :                                     FieldDeclarator &FD,
    2112                 :                                     ObjCDeclSpec &ODS,
    2113                 :                                     Selector GetterSel,
    2114                 :                                     Selector SetterSel,
    2115                 :                                     DeclPtrTy ClassCategory,
    2116                 :                                     bool *isOverridingProperty,
    2117              484:                                     tok::ObjCKeywordKind MethodImplKind) {
    2118              484:   unsigned Attributes = ODS.getPropertyAttributes();
    2119                 :   bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
    2120                 :                       // default is readwrite!
                      420: branch 0 taken
                       64: branch 1 taken
                      315: branch 2 taken
                      105: branch 3 taken
    2121              484:                       !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
    2122                 :   // property is defaulted to 'assign' if it is readwrite and is
    2123                 :   // not retain or copy
    2124                 :   bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
    2125                 :                    (isReadWrite &&
    2126                 :                     !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
                      405: branch 0 taken
                       79: branch 1 taken
                      302: branch 2 taken
                      103: branch 3 taken
                      256: branch 4 taken
                       46: branch 5 taken
                      213: branch 6 taken
                       43: branch 7 taken
    2127              484:                     !(Attributes & ObjCDeclSpec::DQ_PR_copy)));
    2128              484:   QualType T = GetTypeForDeclarator(FD.D, S);
                        1: branch 2 taken
                      483: branch 3 taken
    2129              484:   if (T->isReferenceType()) {
    2130                1:     Diag(AtLoc, diag::error_reference_property);
    2131                1:     return DeclPtrTy();
    2132                 :   }
    2133              483:   Decl *ClassDecl = ClassCategory.getAs<Decl>();
    2134              483:   ObjCInterfaceDecl *CCPrimary = 0; // continuation class's primary class
    2135                 :   // May modify Attributes.
    2136              483:   CheckObjCPropertyAttributes(T, AtLoc, Attributes);
                       61: branch 1 taken
                      422: branch 2 taken
    2137              483:   if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
                       47: branch 1 taken
                       14: branch 2 taken
    2138               61:     if (!CDecl->getIdentifier()) {
    2139                 :       // This is a continuation class. property requires special
    2140                 :       // handling.
                       47: branch 1 taken
                        0: branch 2 not taken
    2141               47:       if ((CCPrimary = CDecl->getClassInterface())) {
    2142                 :         // Find the property in continuation class's primary class only.
    2143               47:         IdentifierInfo *PropertyId = FD.D.getIdentifier();
                       36: branch 0 taken
                       11: branch 1 taken
    2144               47:         if (ObjCPropertyDecl *PIDecl = 
    2145               47:               CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId)) {
    2146                 :           // property 'PIDecl's readonly attribute will be over-ridden
    2147                 :           // with continuation class's readwrite property attribute!
    2148               36:           unsigned PIkind = PIDecl->getPropertyAttributes();
                       35: branch 0 taken
                        1: branch 1 taken
                       33: branch 2 taken
                        2: branch 3 taken
    2149               69:           if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
    2150                 :             unsigned retainCopyNonatomic = 
    2151                 :               (ObjCPropertyDecl::OBJC_PR_retain |
    2152                 :                ObjCPropertyDecl::OBJC_PR_copy |
    2153               33:                ObjCPropertyDecl::OBJC_PR_nonatomic);
                        1: branch 0 taken
                       32: branch 1 taken
    2154               33:             if ((Attributes & retainCopyNonatomic) !=
    2155                 :                 (PIkind & retainCopyNonatomic)) {
    2156                1:               Diag(AtLoc, diag::warn_property_attr_mismatch);
    2157                1:               Diag(PIDecl->getLocation(), diag::note_property_declare);
    2158                 :             }
    2159               33:             DeclContext *DC = dyn_cast<DeclContext>(CCPrimary);
                        0: branch 0 not taken
                       33: branch 1 taken
    2160               33:             assert(DC && "ClassDecl is not a DeclContext");
    2161                 :             DeclContext::lookup_result Found = 
    2162               33:               DC->lookup(PIDecl->getDeclName());
    2163               33:             bool PropertyInPrimaryClass = false;
                       55: branch 0 taken
                        2: branch 1 taken
    2164               57:             for (; Found.first != Found.second; ++Found.first)
                       31: branch 1 taken
                       24: branch 2 taken
    2165               55:               if (isa<ObjCPropertyDecl>(*Found.first)) {
    2166               31:                 PropertyInPrimaryClass = true;
    2167               31:                 break;
    2168                 :               }
                        2: branch 0 taken
                       31: branch 1 taken
    2169               33:             if (!PropertyInPrimaryClass) {
    2170                 :               // Protocol is not in the primary class. Must build one for it.
    2171                2:               ObjCDeclSpec ProtocolPropertyODS;
    2172                 :               // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind and
    2173                 :               // ObjCPropertyDecl::PropertyAttributeKind have identical values.
    2174                 :               // Should consolidate both into one enum type.
    2175                 :               ProtocolPropertyODS.setPropertyAttributes(
    2176                2:                 (ObjCDeclSpec::ObjCPropertyAttributeKind)PIkind);
    2177                 :               DeclPtrTy ProtocolPtrTy = 
    2178                 :                 ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS, 
    2179                 :                               PIDecl->getGetterName(), 
    2180                 :                               PIDecl->getSetterName(), 
    2181                 :                               DeclPtrTy::make(CCPrimary), isOverridingProperty, 
    2182                2:                               MethodImplKind);
    2183                2:               PIDecl = ProtocolPtrTy.getAs<ObjCPropertyDecl>();
    2184                 :             }
    2185               33:             PIDecl->makeitReadWriteAttribute();
                        0: branch 0 not taken
                       33: branch 1 taken
    2186               33:             if (Attributes & ObjCDeclSpec::DQ_PR_retain)
    2187                0:               PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
                        3: branch 0 taken
                       30: branch 1 taken
    2188               33:             if (Attributes & ObjCDeclSpec::DQ_PR_copy)
    2189                3:               PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
    2190               33:             PIDecl->setSetterName(SetterSel);
    2191                 :           } else {
    2192                 :             Diag(AtLoc, diag::err_use_continuation_class)
    2193                3:               << CCPrimary->getDeclName();
    2194                3:             Diag(PIDecl->getLocation(), diag::note_property_declare);
    2195                 :           }
    2196               36:           *isOverridingProperty = true;
    2197                 :           // Make sure setter decl is synthesized, and added to primary
    2198                 :           // class's list.
    2199               36:           ProcessPropertyDecl(PIDecl, CCPrimary);
    2200               36:           return DeclPtrTy();
    2201                 :         }
    2202                 :         // No matching property found in the primary class. Just fall thru
    2203                 :         // and add property to continuation class's primary class.
    2204               11:         ClassDecl = CCPrimary;
    2205                 :       } else {
    2206                0:         Diag(CDecl->getLocation(), diag::err_continuation_class);
    2207                0:         *isOverridingProperty = true;
    2208                0:         return DeclPtrTy();
    2209                 :       }
    2210                 :     }
    2211                 : 
    2212                 :   // Issue a warning if property is 'assign' as default and its object, which is
    2213                 :   // gc'able conforms to NSCopying protocol
                       22: branch 2 taken
                      425: branch 3 taken
                       20: branch 4 taken
                        2: branch 5 taken
                       11: branch 6 taken
                        9: branch 7 taken
                       11: branch 8 taken
                      436: branch 9 taken
    2214              447:   if (getLangOptions().getGCMode() != LangOptions::NonGC &&
    2215                 :       isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign))
                        7: branch 2 taken
                        4: branch 3 taken
    2216               11:       if (T->isObjCObjectPointerType()) {
    2217                7:         QualType InterfaceTy = T->getPointeeType();
                        4: branch 0 taken
                        3: branch 1 taken
    2218                7:         if (const ObjCInterfaceType *OIT =
    2219                7:               InterfaceTy->getAs<ObjCInterfaceType>()) {
    2220                4:         ObjCInterfaceDecl *IDecl = OIT->getDecl();
                        4: branch 0 taken
                        0: branch 1 not taken
    2221                4:         if (IDecl)
                        1: branch 0 taken
                        3: branch 1 taken
    2222                4:           if (ObjCProtocolDecl* PNSCopying =
    2223                4:                 LookupProtocol(&Context.Idents.get("NSCopying")))
                        1: branch 1 taken
                        0: branch 2 not taken
    2224                1:             if (IDecl->ClassImplementsProtocol(PNSCopying, true))
    2225                 :               Diag(AtLoc, diag::warn_implements_nscopying)
    2226                1:                 << FD.D.getIdentifier();
    2227                 :         }
    2228                 :       }
                        1: branch 2 taken
                      446: branch 3 taken
    2229              447:   if (T->isObjCInterfaceType())
    2230                1:     Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object);
    2231                 : 
    2232              447:   DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
                        0: branch 0 not taken
                      447: branch 1 taken
    2233              447:   assert(DC && "ClassDecl is not a DeclContext");
    2234                 :   ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC,
    2235                 :                                                      FD.D.getIdentifierLoc(),
    2236                 :                                                      FD.D.getIdentifier(), 
    2237              447:                                                      AtLoc, T);
    2238              447:   DeclContext::lookup_result Found = DC->lookup(PDecl->getDeclName());
                      112: branch 0 taken
                      335: branch 1 taken
                        1: branch 3 taken
                      111: branch 4 taken
                        1: branch 5 taken
                      446: branch 6 taken
    2239              447:   if (Found.first != Found.second && isa<ObjCPropertyDecl>(*Found.first)) {
    2240                1:     Diag(PDecl->getLocation(), diag::err_duplicate_property);
    2241                1:     Diag((*Found.first)->getLocation(), diag::note_property_declare);
    2242                1:     PDecl->setInvalidDecl();
    2243                 :   }
    2244                 :   else
    2245              446:     DC->addDecl(PDecl);
    2246                 : 
                      444: branch 2 taken
                        3: branch 3 taken
                        1: branch 6 taken
                      443: branch 7 taken
                        4: branch 8 taken
                      443: branch 9 taken
    2247              447:   if (T->isArrayType() || T->isFunctionType()) {
    2248                4:     Diag(AtLoc, diag::err_property_type) << T;
    2249                4:     PDecl->setInvalidDecl();
    2250                 :   }
    2251                 : 
    2252              447:   ProcessDeclAttributes(S, PDecl, FD.D);
    2253                 : 
    2254                 :   // Regardless of setter/getter attribute, we save the default getter/setter
    2255                 :   // selector names in anticipation of declaration of setter/getter methods.
    2256              447:   PDecl->setGetterName(GetterSel);
    2257              447:   PDecl->setSetterName(SetterSel);
    2258                 : 
                      106: branch 0 taken
                      341: branch 1 taken
    2259              447:   if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
    2260              106:     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
    2261                 : 
                       16: branch 0 taken
                      431: branch 1 taken
    2262              447:   if (Attributes & ObjCDeclSpec::DQ_PR_getter)
    2263               16:     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
    2264                 : 
                       17: branch 0 taken
                      430: branch 1 taken
    2265              447:   if (Attributes & ObjCDeclSpec::DQ_PR_setter)
    2266               17:     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
    2267                 : 
                      343: branch 0 taken
                      104: branch 1 taken
    2268              447:   if (isReadWrite)
    2269              343:     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
    2270                 : 
                       48: branch 0 taken
                      399: branch 1 taken
    2271              447:   if (Attributes & ObjCDeclSpec::DQ_PR_retain)
    2272               48:     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
    2273                 : 
                       42: branch 0 taken
                      405: branch 1 taken
    2274              447:   if (Attributes & ObjCDeclSpec::DQ_PR_copy)
    2275               42:     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
    2276                 : 
                      261: branch 0 taken
                      186: branch 1 taken
    2277              447:   if (isAssign)
    2278              261:     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
    2279                 : 
                       66: branch 0 taken
                      381: branch 1 taken
    2280              447:   if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
    2281               66:     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
    2282                 : 
                        3: branch 0 taken
                      444: branch 1 taken
    2283              447:   if (MethodImplKind == tok::objc_required)
    2284                3:     PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
                       11: branch 0 taken
                      433: branch 1 taken
    2285              444:   else if (MethodImplKind == tok::objc_optional)
    2286               11:     PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
    2287                 :   // A case of continuation class adding a new property in the class. This
    2288                 :   // is not what it was meant for. However, gcc supports it and so should we.
    2289                 :   // Make sure setter/getters are declared here.
                       11: branch 0 taken
                      436: branch 1 taken
    2290              447:   if (CCPrimary)
    2291               11:     ProcessPropertyDecl(PDecl, CCPrimary);
    2292                 : 
    2293              447:   return DeclPtrTy::make(PDecl);
    2294                 : }
    2295                 : 
    2296                 : ObjCIvarDecl* 
    2297                 : Sema::SynthesizeNewPropertyIvar(ObjCInterfaceDecl *IDecl,
    2298                6:                                 IdentifierInfo *NameII) {
    2299                6:   ObjCIvarDecl *Ivar = 0;
    2300                6:   ObjCPropertyDecl *Prop = LookupPropertyDecl(IDecl, NameII);
                        6: branch 0 taken
                        0: branch 1 not taken
                        6: branch 3 taken
                        0: branch 4 not taken
                        6: branch 5 taken
                        0: branch 6 not taken
    2301                6:   if (Prop && !Prop->isInvalidDecl()) {
    2302                6:     DeclContext *EnclosingContext = cast_or_null<DeclContext>(IDecl);
    2303                6:     QualType PropType = Context.getCanonicalType(Prop->getType());
    2304                 :     assert(EnclosingContext &&
                        0: branch 0 not taken
                        6: branch 1 taken
    2305                6:            "null DeclContext for synthesized ivar - SynthesizeNewPropertyIvar");
    2306                 :     Ivar = ObjCIvarDecl::Create(Context, EnclosingContext, 
    2307                 :                                               Prop->getLocation(),
    2308                 :                                               NameII, PropType, /*Dinfo=*/0,
    2309                 :                                               ObjCIvarDecl::Public,
    2310                6:                                               (Expr *)0);
                        6: branch 0 taken
                        0: branch 1 not taken
    2311                6:     Ivar->setLexicalDeclContext(IDecl);
    2312                6:     IDecl->addDecl(Ivar);
    2313                6:     Prop->setPropertyIvarDecl(Ivar);
    2314                 :   }
    2315                6:   return Ivar;
    2316                 : }
    2317                 : 
    2318                 : /// ActOnPropertyImplDecl - This routine performs semantic checks and
    2319                 : /// builds the AST node for a property implementation declaration; declared
    2320                 : /// as @synthesize or @dynamic.
    2321                 : ///
    2322                 : Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
    2323                 :                                             SourceLocation PropertyLoc,
    2324                 :                                             bool Synthesize,
    2325                 :                                             DeclPtrTy ClassCatImpDecl,
    2326                 :                                             IdentifierInfo *PropertyId,
    2327              297:                                             IdentifierInfo *PropertyIvar) {
    2328              297:   Decl *ClassImpDecl = ClassCatImpDecl.getAs<Decl>();
    2329                 :   // Make sure we have a context for the property implementation declaration.
                        0: branch 0 not taken
                      297: branch 1 taken
    2330              297:   if (!ClassImpDecl) {
    2331                0:     Diag(AtLoc, diag::error_missing_property_context);
    2332                0:     return DeclPtrTy();
    2333                 :   }
    2334              297:   ObjCPropertyDecl *property = 0;
    2335              297:   ObjCInterfaceDecl* IDecl = 0;
    2336                 :   // Find the class or category class where this property must have
    2337                 :   // a declaration.
    2338              297:   ObjCImplementationDecl *IC = 0;
    2339              297:   ObjCCategoryImplDecl* CatImplClass = 0;
                      291: branch 1 taken
                        6: branch 2 taken
    2340              297:   if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
    2341              291:     IDecl = IC->getClassInterface();
    2342                 :     // We always synthesize an interface for an implementation
    2343                 :     // without an interface decl. So, IDecl is always non-zero.
    2344                 :     assert(IDecl &&
                        0: branch 0 not taken
                      291: branch 1 taken
    2345              291:            "ActOnPropertyImplDecl - @implementation without @interface");
    2346                 : 
    2347                 :     // Look for this property declaration in the @implementation's @interface
    2348              291:     property = IDecl->FindPropertyDeclaration(PropertyId);
                        2: branch 0 taken
                      289: branch 1 taken
    2349              291:     if (!property) {
    2350                2:       Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
    2351                2:       return DeclPtrTy();
    2352                 :     }
                        2: branch 0 taken
                      287: branch 1 taken
    2353              289:     if (const ObjCCategoryDecl *CD = 
    2354              289:         dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
                        2: branch 1 taken
                        0: branch 2 not taken
    2355                2:       if (CD->getIdentifier()) {
    2356                2:         Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName();
    2357                2:         Diag(property->getLocation(), diag::note_property_declare);
    2358                2:         return DeclPtrTy();
    2359                 :       }
    2360                 :     }
                        6: branch 1 taken
                        0: branch 2 not taken
    2361                6:   } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
                        2: branch 0 taken
                        4: branch 1 taken
    2362                6:     if (Synthesize) {
    2363                2:       Diag(AtLoc, diag::error_synthesize_category_decl);
    2364                2:       return DeclPtrTy();
    2365                 :     }
    2366                4:     IDecl = CatImplClass->getClassInterface();
                        1: branch 0 taken
                        3: branch 1 taken
    2367                4:     if (!IDecl) {
    2368                1:       Diag(AtLoc, diag::error_missing_property_interface);
    2369                1:       return DeclPtrTy();
    2370                 :     }
    2371                 :     ObjCCategoryDecl *Category =
    2372                3:       IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
    2373                 : 
    2374                 :     // If category for this implementation not found, it is an error which
    2375                 :     // has already been reported eralier.
                        0: branch 0 not taken
                        3: branch 1 taken
    2376                3:     if (!Category)
    2377                0:       return DeclPtrTy();
    2378                 :     // Look for this property declaration in @implementation's category
    2379                3:     property = Category->FindPropertyDeclaration(PropertyId);
                        1: branch 0 taken
                        2: branch 1 taken
    2380                3:     if (!property) {
    2381                 :       Diag(PropertyLoc, diag::error_bad_category_property_decl)
    2382                1:         << Category->getDeclName();
    2383                1:       return DeclPtrTy();
    2384                 :     }
    2385                 :   } else {
    2386                0:     Diag(AtLoc, diag::error_bad_property_context);
    2387                0:     return DeclPtrTy();
    2388                 :   }
    2389              289:   ObjCIvarDecl *Ivar = 0;
    2390                 :   // Check that we have a valid, previously declared ivar for @synthesize
                      213: branch 0 taken
                       76: branch 1 taken
    2391              289:   if (Synthesize) {
    2392                 :     // @synthesize
                      115: branch 0 taken
                       98: branch 1 taken
    2393              213:     if (!PropertyIvar)
    2394              115:       PropertyIvar = PropertyId;
    2395              213:     QualType PropType = Context.getCanonicalType(property->getType());
    2396                 :     // Check that this is a previously declared 'ivar' in 'IDecl' interface
    2397                 :     ObjCInterfaceDecl *ClassDeclared;
    2398              213:     Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
                       35: branch 0 taken
                      178: branch 1 taken
    2399              213:     if (!Ivar) {
    2400               35:       DeclContext *EnclosingContext = cast_or_null<DeclContext>(IDecl);
    2401                 :       assert(EnclosingContext &&
                        0: branch 0 not taken
                       35: branch 1 taken
    2402               35:              "null DeclContext for synthesized ivar - ActOnPropertyImplDecl");
    2403                 :       Ivar = ObjCIvarDecl::Create(Context, EnclosingContext, PropertyLoc,
    2404                 :                                   PropertyIvar, PropType, /*Dinfo=*/0,
    2405                 :                                   ObjCIvarDecl::Public,
    2406               35:                                   (Expr *)0);
                       35: branch 0 taken
                        0: branch 1 not taken
    2407               35:       Ivar->setLexicalDeclContext(IDecl);
    2408               35:       IDecl->addDecl(Ivar);
    2409               35:       property->setPropertyIvarDecl(Ivar);
                        7: branch 1 taken
                       28: branch 2 taken
    2410               35:       if (!getLangOptions().ObjCNonFragileABI)
    2411                7:         Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
    2412                 :         // Note! I deliberately want it to fall thru so, we have a
    2413                 :         // a property implementation and to avoid future warnings.
                       14: branch 1 taken
                      164: branch 2 taken
                        1: branch 3 taken
                       13: branch 4 taken
                        1: branch 5 taken
                      177: branch 6 taken
    2414              178:     } else if (getLangOptions().ObjCNonFragileABI &&
    2415                 :                ClassDeclared != IDecl) {
    2416                 :       Diag(PropertyLoc, diag::error_ivar_in_superclass_use)
    2417                 :         << property->getDeclName() << Ivar->getDeclName()
    2418                1:         << ClassDeclared->getDeclName();
    2419                 :       Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
    2420                1:         << Ivar << Ivar->getNameAsCString();
    2421                 :       // Note! I deliberately want it to fall thru so more errors are caught.
    2422                 :     }
    2423              213:     QualType IvarType = Context.getCanonicalType(Ivar->getType());
    2424                 : 
    2425                 :     // Check that type of property and its ivar are type compatible.
                       18: branch 1 taken
                      195: branch 2 taken
    2426              213:     if (PropType != IvarType) {
                        1: branch 1 taken
                       17: branch 2 taken
    2427               18:       if (CheckAssignmentConstraints(PropType, IvarType) != Compatible) {
    2428                 :         Diag(PropertyLoc, diag::error_property_ivar_type)
    2429                1:           << property->getDeclName() << Ivar->getDeclName();
    2430                 :         // Note! I deliberately want it to fall thru so, we have a
    2431                 :         // a property implementation and to avoid future warnings.
    2432                 :       }
    2433                 : 
    2434                 :       // FIXME! Rules for properties are somewhat different that those
    2435                 :       // for assignments. Use a new routine to consolidate all cases;
    2436                 :       // specifically for property redeclarations as well as for ivars.
    2437               18:       QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType();
    2438               18:       QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
                       14: branch 1 taken
                        4: branch 2 taken
                        1: branch 5 taken
                       13: branch 6 taken
                        1: branch 7 taken
                       17: branch 8 taken
    2439               18:       if (lhsType != rhsType &&
    2440                 :           lhsType->isArithmeticType()) {
    2441                 :         Diag(PropertyLoc, diag::error_property_ivar_type)
    2442                1:         << property->getDeclName() << Ivar->getDeclName();
    2443                 :         // Fall thru - see previous comment
    2444                 :       }
    2445                 :       // __weak is explicit. So it works on Canonical type.
                        2: branch 1 taken
                       16: branch 2 taken
                        2: branch 4 taken
                        0: branch 5 not taken
                        1: branch 8 taken
                        1: branch 9 taken
                        1: branch 10 taken
                       17: branch 11 taken
    2446               18:       if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
    2447                 :           getLangOptions().getGCMode() != LangOptions::NonGC) {
    2448                 :         Diag(PropertyLoc, diag::error_weak_property)
    2449                1:         << property->getDeclName() << Ivar->getDeclName();
    2450                 :         // Fall thru - see previous comment
    2451                 :       }
                        1: branch 3 taken
                       17: branch 4 taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        3: branch 9 taken
                       14: branch 10 taken
                        2: branch 13 taken
                        1: branch 14 taken
                        2: branch 15 taken
                       16: branch 16 taken
    2452               18:       if ((property->getType()->isObjCObjectPointerType() ||
    2453                 :            PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() &&
    2454                 :            getLangOptions().getGCMode() != LangOptions::NonGC) {
    2455                 :         Diag(PropertyLoc, diag::error_strong_property)
    2456                2:         << property->getDeclName() << Ivar->getDeclName();
    2457                 :         // Fall thru - see previous comment
    2458                 :       }
    2459                 :     }
                        0: branch 0 not taken
                       76: branch 1 taken
    2460               76:   } else if (PropertyIvar)
    2461                 :       // @dynamic
    2462                0:       Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
                        0: branch 0 not taken
                      289: branch 1 taken
    2463              289:   assert (property && "ActOnPropertyImplDecl - property declaration missing");
    2464                 :   ObjCPropertyImplDecl *PIDecl =
    2465                 :     ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc,
    2466                 :                                  property,
    2467                 :                                  (Synthesize ?
    2468                 :                                   ObjCPropertyImplDecl::Synthesize
    2469                 :                                   : ObjCPropertyImplDecl::Dynamic),
                      213: branch 0 taken
                       76: branch 1 taken
    2470              289:                                  Ivar);
                      287: branch 0 taken
                        2: branch 1 taken
    2471              289:   if (IC) {
                      213: branch 0 taken
                       74: branch 1 taken
    2472              287:     if (Synthesize)
                        2: branch 0 taken
                      211: branch 1 taken
    2473              213:       if (ObjCPropertyImplDecl *PPIDecl =
    2474              213:           IC->FindPropertyImplIvarDecl(PropertyIvar)) {
    2475                 :         Diag(PropertyLoc, diag::error_duplicate_ivar_use)
    2476                 :           << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
    2477                2:           << PropertyIvar;
    2478                2:         Diag(PPIDecl->getLocation(), diag::note_previous_use);
    2479                 :       }
    2480                 : 
                        2: branch 0 taken
                      285: branch 1 taken
    2481              287:     if (ObjCPropertyImplDecl *PPIDecl
    2482              287:           = IC->FindPropertyImplDecl(PropertyId)) {
    2483                2:       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
    2484                2:       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
    2485                2:       return DeclPtrTy();
    2486                 :     }
    2487              285:     IC->addPropertyImplementation(PIDecl);
    2488                 :   } else {
                        0: branch 0 not taken
                        2: branch 1 taken
    2489                2:     if (Synthesize)
                        0: branch 0 not taken
                        0: branch 1 not taken
    2490                0:       if (ObjCPropertyImplDecl *PPIDecl =
    2491                0:           CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
    2492                 :         Diag(PropertyLoc, diag::error_duplicate_ivar_use)
    2493                 :           << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
    2494                0:           << PropertyIvar;
    2495                0:         Diag(PPIDecl->getLocation(), diag::note_previous_use);
    2496                 :       }
    2497                 : 
                        0: branch 0 not taken
                        2: branch 1 taken
    2498                2:     if (ObjCPropertyImplDecl *PPIDecl =
    2499                2:           CatImplClass->FindPropertyImplDecl(PropertyId)) {
    2500                0:       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
    2501                0:       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
    2502                0:       return DeclPtrTy();
    2503                 :     }
    2504                2:     CatImplClass->addPropertyImplementation(PIDecl);
    2505                 :   }
    2506                 : 
    2507              287:   return DeclPtrTy::make(PIDecl);
    2508                 : }
    2509                 : 
    2510             3494: bool Sema::CheckObjCDeclScope(Decl *D) {
                     3486: branch 2 taken
                        8: branch 3 taken
    2511             3494:   if (isa<TranslationUnitDecl>(CurContext->getLookupContext()))
    2512             3486:     return false;
    2513                 : 
    2514                8:   Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
    2515                8:   D->setInvalidDecl();
    2516                 : 
    2517                8:   return true;
    2518                 : }
    2519                 : 
    2520                 : /// Called whenever @defs(ClassName) is encountered in the source.  Inserts the
    2521                 : /// instance variables of ClassName into Decls.
    2522                 : void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
    2523                 :                      IdentifierInfo *ClassName,
    2524                8:                      llvm::SmallVectorImpl<DeclPtrTy> &Decls) {
    2525                 :   // Check that ClassName is a valid class
    2526                8:   ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName);
                        0: branch 0 not taken
                        8: branch 1 taken
    2527                8:   if (!Class) {
    2528                0:     Diag(DeclStart, diag::err_undef_interface) << ClassName;
    2529                0:     return;
    2530                 :   }
                        1: branch 0 taken
                        7: branch 1 taken
    2531                8:   if (LangOpts.ObjCNonFragileABI) {
    2532                1:     Diag(DeclStart, diag::err_atdef_nonfragile_interface);
    2533                1:     return;
    2534                 :   }
    2535                 : 
    2536                 :   // Collect the instance variables
    2537                7:   llvm::SmallVector<FieldDecl*, 32> RecFields;
    2538                7:   Context.CollectObjCIvars(Class, RecFields);
    2539                 :   // For each ivar, create a fresh ObjCAtDefsFieldDecl.
                       21: branch 1 taken
                        7: branch 2 taken
    2540               28:   for (unsigned i = 0; i < RecFields.size(); i++) {
    2541               21:     FieldDecl* ID = RecFields[i];
    2542               21:     RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>());
    2543                 :     Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, ID->getLocation(),
    2544                 :                                            ID->getIdentifier(), ID->getType(),
                       21: branch 4 taken
                        0: branch 5 not taken
    2545               21:                                            ID->getBitWidth());
    2546               21:     Decls.push_back(Sema::DeclPtrTy::make(FD));
    2547                 :   }
    2548                 : 
    2549                 :   // Introduce all of these fields into the appropriate scope.
                       21: branch 2 taken
                        7: branch 3 taken
    2550               28:   for (llvm::SmallVectorImpl<DeclPtrTy>::iterator D = Decls.begin();
    2551                 :        D != Decls.end(); ++D) {
    2552               21:     FieldDecl *FD = cast<FieldDecl>(D->getAs<Decl>());
                        0: branch 1 not taken
                       21: branch 2 taken
    2553               21:     if (getLangOptions().CPlusPlus)
    2554                0:       PushOnScopeChains(cast<FieldDecl>(FD), S);
                       21: branch 2 taken
                        0: branch 3 not taken
    2555               21:     else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
    2556               21:       Record->addDecl(FD);
    2557                7:   }
    2558                 : }
    2559                 : 

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