[cfe-commits] r44925 - in /cfe/trunk: Sema/SemaDecl.cpp Sema/SemaDeclObjC.cpp clang.xcodeproj/project.pbxproj

Chris Lattner sabre at nondot.org
Tue Dec 11 23:09:47 PST 2007


Author: lattner
Date: Wed Dec 12 01:09:47 2007
New Revision: 44925

URL: http://llvm.org/viewvc/llvm-project?rev=44925&view=rev
Log:
split objc pieces of SemaDecl.cpp out into SemaDeclObjC.cpp

Added:
    cfe/trunk/Sema/SemaDeclObjC.cpp
Modified:
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/clang.xcodeproj/project.pbxproj

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=44925&r1=44924&r2=44925&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Wed Dec 12 01:09:47 2007
@@ -15,7 +15,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Builtins.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
 #include "clang/Parse/DeclSpec.h"
@@ -25,7 +24,6 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/DenseSet.h"
-#include "clang/Lex/Preprocessor.h"
 using namespace clang;
 
 Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
@@ -210,7 +208,7 @@
   
   // Allow multiple definitions for ObjC built-in typedefs.
   // FIXME: Verify the underlying types are equivalent!
-  if (PP.getLangOptions().ObjC1 && isBuiltinObjcType(New))
+  if (getLangOptions().ObjC1 && isBuiltinObjcType(New))
     return Old;
     
   // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
@@ -1050,45 +1048,6 @@
   return D;
 }
 
-/// ObjcActOnStartOfMethodDef - This routine sets up parameters; invisible
-/// and user declared, in the method definition's AST.
-void Sema::ObjcActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
-  assert(CurFunctionDecl == 0 && "Method parsing confused");
-  ObjcMethodDecl *MDecl = dyn_cast<ObjcMethodDecl>(static_cast<Decl *>(D));
-  assert(MDecl != 0 && "Not a method declarator!");
-  
-  // Allow all of Sema to see that we are entering a method definition.
-  CurMethodDecl = MDecl;
-
-  // Create Decl objects for each parameter, entrring them in the scope for
-  // binding to their use.
-  struct DeclaratorChunk::ParamInfo PI;
-
-  // Insert the invisible arguments, self and _cmd!
-  PI.Ident = &Context.Idents.get("self");
-  PI.IdentLoc = SourceLocation(); // synthesized vars have a null location.
-  PI.InvalidType = false;
-  if (MDecl->isInstance()) {
-    QualType selfTy = Context.getObjcInterfaceType(MDecl->getClassInterface());
-    selfTy = Context.getPointerType(selfTy);
-    PI.TypeInfo = selfTy.getAsOpaquePtr();
-  } else
-    PI.TypeInfo = Context.getObjcIdType().getAsOpaquePtr();
-  CurMethodDecl->setSelfDecl(ActOnParamDeclarator(PI, FnBodyScope));
-  
-  PI.Ident = &Context.Idents.get("_cmd");
-  PI.TypeInfo = Context.getObjcSelType().getAsOpaquePtr();
-  ActOnParamDeclarator(PI, FnBodyScope);
-  
-  for (int i = 0; i <  MDecl->getNumParams(); i++) {
-    ParmVarDecl *PDecl = MDecl->getParamDecl(i);
-    PI.Ident = PDecl->getIdentifier();
-    PI.IdentLoc = PDecl->getLocation(); // user vars have a real location.
-    PI.TypeInfo = PDecl->getType().getAsOpaquePtr();
-    ActOnParamDeclarator(PI, FnBodyScope);
-  }
-}
-
 /// ImplicitlyDefineFunction - An undeclared identifier was used in a function
 /// call, forming a call to an implicitly defined function (per C99 6.5.1p2).
 ScopedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, 
@@ -1135,550 +1094,6 @@
   return NewTD;
 }
 
-Sema::DeclTy *Sema::ActOnStartClassInterface(
-                    SourceLocation AtInterfaceLoc,
-                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
-                    IdentifierInfo *SuperName, SourceLocation SuperLoc,
-                    IdentifierInfo **ProtocolNames, unsigned NumProtocols,
-                    SourceLocation EndProtoLoc, AttributeList *AttrList) {
-  assert(ClassName && "Missing class identifier");
-  
-  // Check for another declaration kind with the same name.
-  ScopedDecl *PrevDecl = LookupInterfaceDecl(ClassName);
-  if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
-    Diag(ClassLoc, diag::err_redefinition_different_kind,
-         ClassName->getName());
-    Diag(PrevDecl->getLocation(), diag::err_previous_definition);
-  }
-  
-  ObjcInterfaceDecl* IDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl);
-  if (IDecl) {
-    // Class already seen. Is it a forward declaration?
-    if (!IDecl->isForwardDecl())
-      Diag(AtInterfaceLoc, diag::err_duplicate_class_def, IDecl->getName());
-    else {
-      IDecl->setLocation(AtInterfaceLoc);
-      IDecl->setForwardDecl(false);
-      IDecl->AllocIntfRefProtocols(NumProtocols);
-    }
-  }
-  else {
-    IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, NumProtocols, ClassName);
-  
-    // Chain & install the interface decl into the identifier.
-    IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
-    ClassName->setFETokenInfo(IDecl);
-    
-    // Remember that this needs to be removed when the scope is popped.
-    TUScope->AddDecl(IDecl);
-  }
-  
-  if (SuperName) {
-    ObjcInterfaceDecl* SuperClassEntry = 0;
-    // Check if a different kind of symbol declared in this scope.
-    PrevDecl = LookupInterfaceDecl(SuperName);
-    if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
-      Diag(SuperLoc, diag::err_redefinition_different_kind,
-           SuperName->getName());
-      Diag(PrevDecl->getLocation(), diag::err_previous_definition);
-    }
-    else {
-      // Check that super class is previously defined
-      SuperClassEntry = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl); 
-                              
-      if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) {
-        Diag(AtInterfaceLoc, diag::err_undef_superclass, 
-             SuperClassEntry ? SuperClassEntry->getName() 
-                             : SuperName->getName(),
-             ClassName->getName()); 
-      }
-    }
-    IDecl->setSuperClass(SuperClassEntry);
-    IDecl->setLocEnd(SuperLoc);
-  } else { // we have a root class.
-    IDecl->setLocEnd(ClassLoc);
-  }
-  
-  /// Check then save referenced protocols
-  if (NumProtocols) {
-    for (unsigned int i = 0; i != NumProtocols; i++) {
-      ObjcProtocolDecl* RefPDecl = ObjcProtocols[ProtocolNames[i]];
-      if (!RefPDecl || RefPDecl->isForwardDecl())
-        Diag(ClassLoc, diag::warn_undef_protocolref,
-             ProtocolNames[i]->getName(),
-             ClassName->getName());
-      IDecl->setIntfRefProtocols((int)i, RefPDecl);
-    }
-    IDecl->setLocEnd(EndProtoLoc);
-  }
-  return IDecl;
-}
-
-/// ActOnCompatiblityAlias - this action is called after complete parsing of
-/// @compaatibility_alias declaration. It sets up the alias relationships.
-Sema::DeclTy *Sema::ActOnCompatiblityAlias(
-                      SourceLocation AtCompatibilityAliasLoc,
-                      IdentifierInfo *AliasName,  SourceLocation AliasLocation,
-                      IdentifierInfo *ClassName, SourceLocation ClassLocation) {
-  // Look for previous declaration of alias name
-  ScopedDecl *ADecl = LookupScopedDecl(AliasName, Decl::IDNS_Ordinary,
-                                       AliasLocation, TUScope);
-  if (ADecl) {
-    if (isa<ObjcCompatibleAliasDecl>(ADecl)) {
-      Diag(AliasLocation, diag::warn_previous_alias_decl);
-      Diag(ADecl->getLocation(), diag::warn_previous_declaration);
-    }
-    else {
-      Diag(AliasLocation, diag::err_conflicting_aliasing_type,
-           AliasName->getName());
-      Diag(ADecl->getLocation(), diag::err_previous_declaration);
-    }
-    return 0;
-  }
-  // Check for class declaration
-  ScopedDecl *CDecl = LookupScopedDecl(ClassName, Decl::IDNS_Ordinary,
-                                       ClassLocation, TUScope);
-  if (!CDecl || !isa<ObjcInterfaceDecl>(CDecl)) {
-    Diag(ClassLocation, diag::warn_undef_interface,
-         ClassName->getName());
-    if (CDecl)
-      Diag(CDecl->getLocation(), diag::warn_previous_declaration);
-    return 0;
-  }
-  // Everything checked out, instantiate a new alias declaration ast
-  ObjcCompatibleAliasDecl *AliasDecl = 
-    new ObjcCompatibleAliasDecl(AtCompatibilityAliasLoc, 
-                                AliasName,
-                                dyn_cast<ObjcInterfaceDecl>(CDecl));
-    
-  // Chain & install the interface decl into the identifier.
-  AliasDecl->setNext(AliasName->getFETokenInfo<ScopedDecl>());
-  AliasName->setFETokenInfo(AliasDecl);
-  return AliasDecl;
-}
-
-Sema::DeclTy *Sema::ActOnStartProtocolInterface(
-                SourceLocation AtProtoInterfaceLoc,
-                IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
-                IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs,
-                SourceLocation EndProtoLoc) {
-  assert(ProtocolName && "Missing protocol identifier");
-  ObjcProtocolDecl *PDecl = ObjcProtocols[ProtocolName];
-  if (PDecl) {
-    // Protocol already seen. Better be a forward protocol declaration
-    if (!PDecl->isForwardDecl())
-      Diag(ProtocolLoc, diag::err_duplicate_protocol_def, 
-           ProtocolName->getName());
-    else {
-      PDecl->setForwardDecl(false);
-      PDecl->AllocReferencedProtocols(NumProtoRefs);
-    }
-  }
-  else {
-    PDecl = new ObjcProtocolDecl(AtProtoInterfaceLoc, NumProtoRefs, 
-                                 ProtocolName);
-    ObjcProtocols[ProtocolName] = PDecl;
-  }    
-  
-  if (NumProtoRefs) {
-    /// Check then save referenced protocols
-    for (unsigned int i = 0; i != NumProtoRefs; i++) {
-      ObjcProtocolDecl* RefPDecl = ObjcProtocols[ProtoRefNames[i]];
-      if (!RefPDecl || RefPDecl->isForwardDecl())
-        Diag(ProtocolLoc, diag::warn_undef_protocolref,
-             ProtoRefNames[i]->getName(),
-             ProtocolName->getName());
-      PDecl->setReferencedProtocols((int)i, RefPDecl);
-    }
-    PDecl->setLocEnd(EndProtoLoc);
-  }
-  return PDecl;
-}
-
-/// FindProtocolDeclaration - This routine looks up protocols and
-/// issuer error if they are not declared. It returns list of protocol
-/// declarations in its 'Protocols' argument.
-void
-Sema::FindProtocolDeclaration(SourceLocation TypeLoc,
-                              IdentifierInfo **ProtocolId,
-                              unsigned NumProtocols,
-                              llvm::SmallVector<DeclTy *,8> &Protocols) {
-  for (unsigned i = 0; i != NumProtocols; ++i) {
-    ObjcProtocolDecl *PDecl = ObjcProtocols[ProtocolId[i]];
-    if (!PDecl)
-      Diag(TypeLoc, diag::err_undeclared_protocol, 
-           ProtocolId[i]->getName());
-    else
-      Protocols.push_back(PDecl); 
-  }
-}
-
-/// ActOnForwardProtocolDeclaration - 
-Action::DeclTy *
-Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
-        IdentifierInfo **IdentList, unsigned NumElts) {
-  llvm::SmallVector<ObjcProtocolDecl*, 32> Protocols;
-  
-  for (unsigned i = 0; i != NumElts; ++i) {
-    IdentifierInfo *P = IdentList[i];
-    ObjcProtocolDecl *PDecl = ObjcProtocols[P];
-    if (!PDecl)  { // Not already seen?
-      // FIXME: Pass in the location of the identifier!
-      PDecl = new ObjcProtocolDecl(AtProtocolLoc, 0, P, true);
-      ObjcProtocols[P] = PDecl;
-    }
-    
-    Protocols.push_back(PDecl);
-  }
-  return new ObjcForwardProtocolDecl(AtProtocolLoc,
-                                     &Protocols[0], Protocols.size());
-}
-
-Sema::DeclTy *Sema::ActOnStartCategoryInterface(
-                      SourceLocation AtInterfaceLoc,
-                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
-                      IdentifierInfo *CategoryName, SourceLocation CategoryLoc,
-                      IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs,
-                      SourceLocation EndProtoLoc) {
-  ObjcInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
-  
-  /// Check that class of this category is already completely declared.
-  if (!IDecl || IDecl->isForwardDecl()) {
-    Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
-    return 0;
-  }
-  ObjcCategoryDecl *CDecl = new ObjcCategoryDecl(AtInterfaceLoc, NumProtoRefs,
-                                                 CategoryName);
-  CDecl->setClassInterface(IDecl);
-  /// Check for duplicate interface declaration for this category
-  ObjcCategoryDecl *CDeclChain;
-  for (CDeclChain = IDecl->getCategoryList(); CDeclChain;
-       CDeclChain = CDeclChain->getNextClassCategory()) {
-    if (CDeclChain->getIdentifier() == CategoryName) {
-      Diag(CategoryLoc, diag::err_dup_category_def, ClassName->getName(),
-           CategoryName->getName());
-      break;
-    }
-  }
-  if (!CDeclChain)
-    CDecl->insertNextClassCategory();
-
-  if (NumProtoRefs) {
-    /// Check then save referenced protocols
-    for (unsigned int i = 0; i != NumProtoRefs; i++) {
-      ObjcProtocolDecl* RefPDecl = ObjcProtocols[ProtoRefNames[i]];
-      if (!RefPDecl || RefPDecl->isForwardDecl()) {
-        Diag(CategoryLoc, diag::warn_undef_protocolref,
-             ProtoRefNames[i]->getName(),
-             CategoryName->getName());
-      }
-      CDecl->setCatReferencedProtocols((int)i, RefPDecl);
-    }
-    CDecl->setLocEnd(EndProtoLoc);
-  }
-  return CDecl;
-}
-
-/// ActOnStartCategoryImplementation - Perform semantic checks on the
-/// category implementation declaration and build an ObjcCategoryImplDecl
-/// object.
-Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
-                      SourceLocation AtCatImplLoc,
-                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
-                      IdentifierInfo *CatName, SourceLocation CatLoc) {
-  ObjcInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
-  ObjcCategoryImplDecl *CDecl = new ObjcCategoryImplDecl(AtCatImplLoc, 
-                                                         CatName, IDecl);
-  /// Check that class of this category is already completely declared.
-  if (!IDecl || IDecl->isForwardDecl())
-    Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
-
-  /// TODO: Check that CatName, category name, is not used in another
-  // implementation.
-  return CDecl;
-}
-
-Sema::DeclTy *Sema::ActOnStartClassImplementation(
-                      SourceLocation AtClassImplLoc,
-                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
-                      IdentifierInfo *SuperClassname, 
-                      SourceLocation SuperClassLoc) {
-  ObjcInterfaceDecl* IDecl = 0;
-  // Check for another declaration kind with the same name.
-  ScopedDecl *PrevDecl = LookupInterfaceDecl(ClassName);
-  if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
-    Diag(ClassLoc, diag::err_redefinition_different_kind,
-         ClassName->getName());
-    Diag(PrevDecl->getLocation(), diag::err_previous_definition);
-  }
-  else {
-    // Is there an interface declaration of this class; if not, warn!
-    IDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl); 
-    if (!IDecl)
-      Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName());
-  }
-  
-  // Check that super class name is valid class name
-  ObjcInterfaceDecl* SDecl = 0;
-  if (SuperClassname) {
-    // Check if a different kind of symbol declared in this scope.
-    PrevDecl = LookupInterfaceDecl(SuperClassname);
-    if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
-      Diag(SuperClassLoc, diag::err_redefinition_different_kind,
-           SuperClassname->getName());
-      Diag(PrevDecl->getLocation(), diag::err_previous_definition);
-    }
-    else {
-      SDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl); 
-      if (!SDecl)
-        Diag(SuperClassLoc, diag::err_undef_superclass, 
-             SuperClassname->getName(), ClassName->getName());
-      else if (IDecl && IDecl->getSuperClass() != SDecl) {
-        // This implementation and its interface do not have the same
-        // super class.
-        Diag(SuperClassLoc, diag::err_conflicting_super_class, 
-             SDecl->getName());
-        Diag(SDecl->getLocation(), diag::err_previous_definition);
-      }
-    }
-  }
-  
-  if (!IDecl) {
-    // Legacy case of @implementation with no corresponding @interface.
-    // Build, chain & install the interface decl into the identifier.
-    IDecl = new ObjcInterfaceDecl(AtClassImplLoc, 0, ClassName, 
-				  false, true);
-    IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
-    ClassName->setFETokenInfo(IDecl);
-    IDecl->setSuperClass(SDecl);
-    IDecl->setLocEnd(ClassLoc);
-    
-    // Remember that this needs to be removed when the scope is popped.
-    TUScope->AddDecl(IDecl);
-  }
-  
-  ObjcImplementationDecl* IMPDecl = 
-  new ObjcImplementationDecl(AtClassImplLoc, ClassName, IDecl, SDecl);
-  
-  // Check that there is no duplicate implementation of this class.
-  if (ObjcImplementations[ClassName])
-    Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName());
-  else // add it to the list.
-    ObjcImplementations[ClassName] = IMPDecl;
-  return IMPDecl;
-}
-
-void Sema::CheckImplementationIvars(ObjcImplementationDecl *ImpDecl,
-                                    ObjcIvarDecl **ivars, unsigned numIvars,
-                                    SourceLocation RBrace) {
-  assert(ImpDecl && "missing implementation decl");
-  ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(ImpDecl->getIdentifier());
-  if (!IDecl)
-    return;
-  /// Check case of non-existing @interface decl.
-  /// (legacy objective-c @implementation decl without an @interface decl).
-  /// Add implementations's ivar to the synthesize class's ivar list.
-  if (IDecl->ImplicitInterfaceDecl()) {
-    IDecl->addInstanceVariablesToClass(ivars, numIvars, RBrace);
-    return;
-  }
-  // If implementation has empty ivar list, just return.
-  if (numIvars == 0)
-    return;
-  
-  assert(ivars && "missing @implementation ivars");
-  
-  // Check interface's Ivar list against those in the implementation.
-  // names and types must match.
-  //
-  ObjcIvarDecl** IntfIvars = IDecl->getInstanceVariables();
-  int IntfNumIvars = IDecl->getNumInstanceVariables();
-  unsigned j = 0;
-  bool err = false;
-  while (numIvars > 0 && IntfNumIvars > 0) {
-    ObjcIvarDecl* ImplIvar = ivars[j];
-    ObjcIvarDecl* ClsIvar = IntfIvars[j++];
-    assert (ImplIvar && "missing implementation ivar");
-    assert (ClsIvar && "missing class ivar");
-    if (ImplIvar->getCanonicalType() != ClsIvar->getCanonicalType()) {
-      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type,
-           ImplIvar->getIdentifier()->getName());
-      Diag(ClsIvar->getLocation(), diag::err_previous_definition,
-           ClsIvar->getIdentifier()->getName());
-    }
-    // TODO: Two mismatched (unequal width) Ivar bitfields should be diagnosed 
-    // as error.
-    else if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
-      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name,
-           ImplIvar->getIdentifier()->getName());
-      Diag(ClsIvar->getLocation(), diag::err_previous_definition,
-           ClsIvar->getIdentifier()->getName());
-      err = true;
-      break;
-    }
-    --numIvars;
-    --IntfNumIvars;
-  }
-  if (!err && (numIvars > 0 || IntfNumIvars > 0))
-    Diag(numIvars > 0 ? ivars[j]->getLocation() : IntfIvars[j]->getLocation(), 
-         diag::err_inconsistant_ivar);
-      
-}
-
-/// CheckProtocolMethodDefs - This routine checks unimpletented methods
-/// Declared in protocol, and those referenced by it.
-void Sema::CheckProtocolMethodDefs(ObjcProtocolDecl *PDecl,
-                                   bool& IncompleteImpl,
-             const llvm::DenseSet<Selector> &InsMap,
-             const llvm::DenseSet<Selector> &ClsMap) {
-  // check unimplemented instance methods.
-  ObjcMethodDecl** methods = PDecl->getInstanceMethods();
-  for (int j = 0; j < PDecl->getNumInstanceMethods(); j++) {
-    if (!InsMap.count(methods[j]->getSelector()) && 
-        methods[j]->getImplementationControl() != ObjcMethodDecl::Optional) {
-      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-           methods[j]->getSelector().getName());
-      IncompleteImpl = true;
-    }
-  }
-  // check unimplemented class methods
-  methods = PDecl->getClassMethods();
-  for (int j = 0; j < PDecl->getNumClassMethods(); j++)
-    if (!ClsMap.count(methods[j]->getSelector()) &&
-        methods[j]->getImplementationControl() != ObjcMethodDecl::Optional) {
-      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-           methods[j]->getSelector().getName());
-      IncompleteImpl = true;
-    }
-  
-  // Check on this protocols's referenced protocols, recursively
-  ObjcProtocolDecl** RefPDecl = PDecl->getReferencedProtocols();
-  for (int i = 0; i < PDecl->getNumReferencedProtocols(); i++)
-    CheckProtocolMethodDefs(RefPDecl[i], IncompleteImpl, InsMap, ClsMap);
-}
-
-void Sema::ImplMethodsVsClassMethods(ObjcImplementationDecl* IMPDecl, 
-                                     ObjcInterfaceDecl* IDecl) {
-  llvm::DenseSet<Selector> InsMap;
-  // Check and see if instance methods in class interface have been
-  // implemented in the implementation class.
-  ObjcMethodDecl *const*methods = IMPDecl->getInstanceMethods();
-  for (int i=0; i < IMPDecl->getNumInstanceMethods(); i++) 
-    InsMap.insert(methods[i]->getSelector());
-  
-  bool IncompleteImpl = false;
-  methods = IDecl->getInstanceMethods();
-  for (int j = 0; j < IDecl->getNumInstanceMethods(); j++)
-    if (!InsMap.count(methods[j]->getSelector())) {
-      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-           methods[j]->getSelector().getName());
-      IncompleteImpl = true;
-    }
-  llvm::DenseSet<Selector> ClsMap;
-  // Check and see if class methods in class interface have been
-  // implemented in the implementation class.
-  methods = IMPDecl->getClassMethods();
-  for (int i=0; i < IMPDecl->getNumClassMethods(); i++)
-    ClsMap.insert(methods[i]->getSelector());
-  
-  methods = IDecl->getClassMethods();
-  for (int j = 0; j < IDecl->getNumClassMethods(); j++)
-    if (!ClsMap.count(methods[j]->getSelector())) {
-      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-           methods[j]->getSelector().getName());
-      IncompleteImpl = true;
-    }
-  
-  // Check the protocol list for unimplemented methods in the @implementation
-  // class.
-  ObjcProtocolDecl** protocols = IDecl->getReferencedProtocols();
-  for (int i = 0; i < IDecl->getNumIntfRefProtocols(); i++)
-    CheckProtocolMethodDefs(protocols[i], IncompleteImpl, InsMap, ClsMap);
-
-  if (IncompleteImpl)
-    Diag(IMPDecl->getLocation(), diag::warn_incomplete_impl_class, 
-         IMPDecl->getName());
-}
-
-/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
-/// category interface is implemented in the category @implementation.
-void Sema::ImplCategoryMethodsVsIntfMethods(ObjcCategoryImplDecl *CatImplDecl,
-                                            ObjcCategoryDecl *CatClassDecl) {
-  llvm::DenseSet<Selector> InsMap;
-  // Check and see if instance methods in category interface have been
-  // implemented in its implementation class.
-  ObjcMethodDecl *const*methods = CatImplDecl->getInstanceMethods();
-  for (int i=0; i < CatImplDecl->getNumInstanceMethods(); i++)
-    InsMap.insert(methods[i]->getSelector());
-  
-  bool IncompleteImpl = false;
-  methods = CatClassDecl->getInstanceMethods();
-  for (int j = 0; j < CatClassDecl->getNumInstanceMethods(); j++)
-    if (!InsMap.count(methods[j]->getSelector())) {
-      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-           methods[j]->getSelector().getName());
-      IncompleteImpl = true;
-    }
-  llvm::DenseSet<Selector> ClsMap;
-  // Check and see if class methods in category interface have been
-  // implemented in its implementation class.
-  methods = CatImplDecl->getClassMethods();
-  for (int i=0; i < CatImplDecl->getNumClassMethods(); i++)
-    ClsMap.insert(methods[i]->getSelector());
-  
-  methods = CatClassDecl->getClassMethods();
-  for (int j = 0; j < CatClassDecl->getNumClassMethods(); j++)
-    if (!ClsMap.count(methods[j]->getSelector())) {
-      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-           methods[j]->getSelector().getName());
-      IncompleteImpl = true;
-    }
-  
-  // Check the protocol list for unimplemented methods in the @implementation
-  // class.
-  ObjcProtocolDecl** protocols = CatClassDecl->getReferencedProtocols();
-  for (int i = 0; i < CatClassDecl->getNumReferencedProtocols(); i++) {
-    ObjcProtocolDecl* PDecl = protocols[i];
-    CheckProtocolMethodDefs(PDecl, IncompleteImpl, InsMap, ClsMap);
-  }
-  if (IncompleteImpl)
-    Diag(CatImplDecl->getLocation(), diag::warn_incomplete_impl_category, 
-         CatClassDecl->getName());
-}
-
-/// ActOnForwardClassDeclaration - 
-Action::DeclTy *
-Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
-                                   IdentifierInfo **IdentList, unsigned NumElts) 
-{
-  llvm::SmallVector<ObjcInterfaceDecl*, 32> Interfaces;
-  
-  for (unsigned i = 0; i != NumElts; ++i) {
-    // Check for another declaration kind with the same name.
-    ScopedDecl *PrevDecl = LookupInterfaceDecl(IdentList[i]);
-    if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
-      Diag(AtClassLoc, diag::err_redefinition_different_kind,
-           IdentList[i]->getName());
-      Diag(PrevDecl->getLocation(), diag::err_previous_definition);
-    }
-    ObjcInterfaceDecl *IDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl); 
-    if (!IDecl) {  // Not already seen?  Make a forward decl.
-      IDecl = new ObjcInterfaceDecl(AtClassLoc, 0, IdentList[i], true);
-      // Chain & install the interface decl into the identifier.
-      IDecl->setNext(IdentList[i]->getFETokenInfo<ScopedDecl>());
-      IdentList[i]->setFETokenInfo(IDecl);
-
-      // Remember that this needs to be removed when the scope is popped.
-      TUScope->AddDecl(IDecl);
-    }
-
-    Interfaces.push_back(IDecl);
-  }
-  
-  return new ObjcClassDecl(AtClassLoc, &Interfaces[0], Interfaces.size());
-}
-
-
 /// ActOnTag - This is invoked when we see 'struct foo' or 'struct {'.  In the
 /// former case, Name will be non-null.  In the later case, Name will be null.
 /// TagType indicates what kind of tag this is. TK indicates whether this is a
@@ -2007,316 +1422,6 @@
   }
 }
 
-/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
-/// returns true, or false, accordingly.
-/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
-bool Sema:: MatchTwoMethodDeclarations(const ObjcMethodDecl *Method, 
-                                       const ObjcMethodDecl *PrevMethod) {
-  if (Method->getResultType().getCanonicalType() !=
-      PrevMethod->getResultType().getCanonicalType())
-    return false;
-  for (int i = 0; i < Method->getNumParams(); i++) {
-    ParmVarDecl *ParamDecl = Method->getParamDecl(i);
-    ParmVarDecl *PrevParamDecl = PrevMethod->getParamDecl(i);
-    if (ParamDecl->getCanonicalType() != PrevParamDecl->getCanonicalType())
-      return false;
-  }
-  return true;
-}
-
-void Sema::AddInstanceMethodToGlobalPool(ObjcMethodDecl *Method) {
-  ObjcMethodList &FirstMethod = InstanceMethodPool[Method->getSelector()];
-  if (!FirstMethod.Method) {
-    // Haven't seen a method with this selector name yet - add it.
-    FirstMethod.Method = Method;
-    FirstMethod.Next = 0;
-  } else {
-    // We've seen a method with this name, now check the type signature(s).
-    bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
-    
-    for (ObjcMethodList *Next = FirstMethod.Next; !match && Next; 
-         Next = Next->Next)
-      match = MatchTwoMethodDeclarations(Method, Next->Method);
-      
-    if (!match) {
-      // We have a new signature for an existing method - add it.
-      // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
-      struct ObjcMethodList *OMI = new ObjcMethodList(Method, FirstMethod.Next);
-      FirstMethod.Next = OMI;
-    }
-  }
-}
-
-void Sema::AddFactoryMethodToGlobalPool(ObjcMethodDecl *Method) {
-  ObjcMethodList &FirstMethod = FactoryMethodPool[Method->getSelector()];
-  if (!FirstMethod.Method) {
-    // Haven't seen a method with this selector name yet - add it.
-    FirstMethod.Method = Method;
-    FirstMethod.Next = 0;
-  } else {
-    // We've seen a method with this name, now check the type signature(s).
-    bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
-    
-    for (ObjcMethodList *Next = FirstMethod.Next; !match && Next; 
-         Next = Next->Next)
-      match = MatchTwoMethodDeclarations(Method, Next->Method);
-      
-    if (!match) {
-      // We have a new signature for an existing method - add it.
-      // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
-      struct ObjcMethodList *OMI = new ObjcMethodList(Method, FirstMethod.Next);
-      FirstMethod.Next = OMI;
-    }
-  }
-}
-
-void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
-                      DeclTy **allMethods, unsigned allNum,
-                      DeclTy **allProperties, unsigned pNum) {
-  Decl *ClassDecl = static_cast<Decl *>(classDecl);
-
-  // FIXME: If we don't have a ClassDecl, we have an error. I (snaroff) would
-  // prefer we always pass in a decl. If the decl has an error, isInvalidDecl()
-  // should be true.
-  if (!ClassDecl)
-    return;
-    
-  llvm::SmallVector<ObjcMethodDecl*, 32> insMethods;
-  llvm::SmallVector<ObjcMethodDecl*, 16> clsMethods;
-  
-  llvm::DenseMap<Selector, const ObjcMethodDecl*> InsMap;
-  llvm::DenseMap<Selector, const ObjcMethodDecl*> ClsMap;
-  
-  bool isInterfaceDeclKind = 
-        (isa<ObjcInterfaceDecl>(ClassDecl) || isa<ObjcCategoryDecl>(ClassDecl)
-         || isa<ObjcProtocolDecl>(ClassDecl));
-  bool checkIdenticalMethods = isa<ObjcImplementationDecl>(ClassDecl);
-  
-  // TODO: property declaration in category and protocols.
-  if (pNum != 0 && isa<ObjcInterfaceDecl>(ClassDecl)) {
-    ObjcPropertyDecl **properties = new ObjcPropertyDecl*[pNum];
-    memcpy(properties, allProperties, pNum*sizeof(ObjcPropertyDecl*));
-    dyn_cast<ObjcInterfaceDecl>(ClassDecl)->setPropertyDecls(properties);
-    dyn_cast<ObjcInterfaceDecl>(ClassDecl)->setNumPropertyDecl(pNum);
-  }
-  
-  for (unsigned i = 0; i < allNum; i++ ) {
-    ObjcMethodDecl *Method =
-      cast_or_null<ObjcMethodDecl>(static_cast<Decl*>(allMethods[i]));
-
-    if (!Method) continue;  // Already issued a diagnostic.
-    if (Method->isInstance()) {
-      /// Check for instance method of the same name with incompatible types
-      const ObjcMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
-      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 
-                              : false;
-      if (isInterfaceDeclKind && PrevMethod && !match 
-          || checkIdenticalMethods && match) {
-          Diag(Method->getLocation(), diag::error_duplicate_method_decl,
-               Method->getSelector().getName());
-          Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
-      } else {
-        insMethods.push_back(Method);
-        InsMap[Method->getSelector()] = Method;
-        /// The following allows us to typecheck messages to "id".
-        AddInstanceMethodToGlobalPool(Method);
-      }
-    }
-    else {
-      /// Check for class method of the same name with incompatible types
-      const ObjcMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
-      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 
-                              : false;
-      if (isInterfaceDeclKind && PrevMethod && !match 
-          || checkIdenticalMethods && match) {
-        Diag(Method->getLocation(), diag::error_duplicate_method_decl,
-             Method->getSelector().getName());
-        Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
-      } else {
-        clsMethods.push_back(Method);
-        ClsMap[Method->getSelector()] = Method;
-        /// The following allows us to typecheck messages to "id".
-        AddInstanceMethodToGlobalPool(Method);
-      }
-    }
-  }
-  
-  if (ObjcInterfaceDecl *I = dyn_cast<ObjcInterfaceDecl>(ClassDecl)) {
-    I->addMethods(&insMethods[0], insMethods.size(),
-                  &clsMethods[0], clsMethods.size(), AtEndLoc);
-  } else if (ObjcProtocolDecl *P = dyn_cast<ObjcProtocolDecl>(ClassDecl)) {
-    P->addMethods(&insMethods[0], insMethods.size(),
-                  &clsMethods[0], clsMethods.size(), AtEndLoc);
-  }
-  else if (ObjcCategoryDecl *C = dyn_cast<ObjcCategoryDecl>(ClassDecl)) {
-    C->addMethods(&insMethods[0], insMethods.size(),
-                  &clsMethods[0], clsMethods.size(), AtEndLoc);
-  }
-  else if (ObjcImplementationDecl *IC = 
-                dyn_cast<ObjcImplementationDecl>(ClassDecl)) {
-    IC->setLocEnd(AtEndLoc);
-    if (ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier()))
-      ImplMethodsVsClassMethods(IC, IDecl);
-  } else {
-    ObjcCategoryImplDecl* CatImplClass = cast<ObjcCategoryImplDecl>(ClassDecl);
-    CatImplClass->setLocEnd(AtEndLoc);
-    ObjcInterfaceDecl* IDecl = CatImplClass->getClassInterface();
-    // Find category interface decl and then check that all methods declared
-    // in this interface is implemented in the category @implementation.
-    if (IDecl) {
-      for (ObjcCategoryDecl *Categories = IDecl->getCategoryList();
-           Categories; Categories = Categories->getNextClassCategory()) {
-        if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
-          ImplCategoryMethodsVsIntfMethods(CatImplClass, Categories);
-          break;
-        }
-      }
-    }
-  }
-}
-
-/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
-/// objective-c's type qualifier from the parser version of the same info.
-static Decl::ObjcDeclQualifier 
-CvtQTToAstBitMask(ObjcDeclSpec::ObjcDeclQualifier PQTVal) {
-  Decl::ObjcDeclQualifier ret = Decl::OBJC_TQ_None;
-  if (PQTVal & ObjcDeclSpec::DQ_In)
-    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_In);
-  if (PQTVal & ObjcDeclSpec::DQ_Inout)
-    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Inout);
-  if (PQTVal & ObjcDeclSpec::DQ_Out)
-    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Out);
-  if (PQTVal & ObjcDeclSpec::DQ_Bycopy)
-    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Bycopy);
-  if (PQTVal & ObjcDeclSpec::DQ_Byref)
-    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Byref);
-  if (PQTVal & ObjcDeclSpec::DQ_Oneway)
-    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Oneway);
-
-  return ret;
-}
-
-Sema::DeclTy *Sema::ActOnMethodDeclaration(
-    SourceLocation MethodLoc, SourceLocation EndLoc,
-    tok::TokenKind MethodType, DeclTy *ClassDecl,
-    ObjcDeclSpec &ReturnQT, TypeTy *ReturnType,
-    Selector Sel,
-    // optional arguments. The number of types/arguments is obtained
-    // from the Sel.getNumArgs().
-    ObjcDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames,
-    AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
-    bool isVariadic) {
-  llvm::SmallVector<ParmVarDecl*, 16> Params;
-  
-  for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
-    // FIXME: arg->AttrList must be stored too!
-    QualType argType;
-    
-    if (ArgTypes[i])
-      argType = QualType::getFromOpaquePtr(ArgTypes[i]);
-    else
-      argType = Context.getObjcIdType();
-    ParmVarDecl* Param = new ParmVarDecl(SourceLocation(/*FIXME*/), ArgNames[i], 
-                                         argType, VarDecl::None, 0);
-    Param->setObjcDeclQualifier(
-      CvtQTToAstBitMask(ArgQT[i].getObjcDeclQualifier()));
-    Params.push_back(Param);
-  }
-  QualType resultDeclType;
-  
-  if (ReturnType)
-    resultDeclType = QualType::getFromOpaquePtr(ReturnType);
-  else // get the type for "id".
-    resultDeclType = Context.getObjcIdType();
-  
-  Decl *CDecl = static_cast<Decl*>(ClassDecl);
-  ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, EndLoc, Sel,
-                                      resultDeclType,
-                                      CDecl,
-                                      0, -1, AttrList, 
-                                      MethodType == tok::minus, isVariadic,
-                                      MethodDeclKind == tok::objc_optional ? 
-                                      ObjcMethodDecl::Optional : 
-                                      ObjcMethodDecl::Required);
-  ObjcMethod->setMethodParams(&Params[0], Sel.getNumArgs());
-  ObjcMethod->setObjcDeclQualifier(
-    CvtQTToAstBitMask(ReturnQT.getObjcDeclQualifier()));
-  const ObjcMethodDecl *PrevMethod = 0;
- 
-  // For implementations (which can be very "coarse grain"), we add the 
-  // method now. This allows the AST to implement lookup methods that work 
-  // incrementally (without waiting until we parse the @end). It also allows 
-  // us to flag multiple declaration errors as they occur.
-  if (ObjcImplementationDecl *ImpDecl = 
-        dyn_cast<ObjcImplementationDecl>(CDecl)) {
-    if (MethodType == tok::minus) {
-      PrevMethod = ImpDecl->lookupInstanceMethod(Sel);
-      ImpDecl->addInstanceMethod(ObjcMethod);
-    } else {
-      PrevMethod = ImpDecl->lookupClassMethod(Sel);
-      ImpDecl->addClassMethod(ObjcMethod);
-    }
-  } 
-  else if (ObjcCategoryImplDecl *CatImpDecl = 
-            dyn_cast<ObjcCategoryImplDecl>(CDecl)) {
-    if (MethodType == tok::minus) {
-      PrevMethod = CatImpDecl->lookupInstanceMethod(Sel);
-      CatImpDecl->addInstanceMethod(ObjcMethod);
-    } else {
-      PrevMethod = CatImpDecl->lookupClassMethod(Sel);
-      CatImpDecl->addClassMethod(ObjcMethod);
-    }
-  }
-  if (PrevMethod) {
-    // You can never have two method definitions with the same name.
-    Diag(ObjcMethod->getLocation(), diag::error_duplicate_method_decl,
-        ObjcMethod->getSelector().getName());
-    Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
-  } 
-  return ObjcMethod;
-}
-
-Sema::DeclTy *Sema::ActOnAddObjcProperties(SourceLocation AtLoc, 
-  DeclTy **allProperties, unsigned NumProperties, ObjcDeclSpec &DS) {
-  ObjcPropertyDecl *PDecl = new ObjcPropertyDecl(AtLoc);
-  
-  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readonly)
-    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readonly);
-  
-  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_getter) {
-    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_getter);
-    PDecl->setGetterName(DS.getGetterName());
-  }
-  
-  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_setter) {
-    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_setter);
-    PDecl->setSetterName(DS.getSetterName());
-  }
-  
-  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_assign)
-    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_assign);
-  
-  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readwrite)
-    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readwrite);
-  
-  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_retain)
-    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_retain);
-  
-  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_copy)
-    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_copy);
-  
-  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_nonatomic)
-    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_nonatomic);
-  
-  PDecl->setNumPropertyDecls(NumProperties);
-  if (NumProperties != 0) {
-    ObjcIvarDecl **properties = new ObjcIvarDecl*[NumProperties];
-    memcpy(properties, allProperties, NumProperties*sizeof(ObjcIvarDecl*));
-    PDecl->setPropertyDecls(properties);
-  }
-  return PDecl;
-}
-
 Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
                                       DeclTy *lastEnumConst,
                                       SourceLocation IdLoc, IdentifierInfo *Id,

Added: cfe/trunk/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDeclObjC.cpp?rev=44925&view=auto

==============================================================================
--- cfe/trunk/Sema/SemaDeclObjC.cpp (added)
+++ cfe/trunk/Sema/SemaDeclObjC.cpp Wed Dec 12 01:09:47 2007
@@ -0,0 +1,914 @@
+//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for Objective C declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Parse/Scope.h"
+
+using namespace clang;
+
+/// ObjcActOnStartOfMethodDef - This routine sets up parameters; invisible
+/// and user declared, in the method definition's AST.
+void Sema::ObjcActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
+  assert(CurFunctionDecl == 0 && "Method parsing confused");
+  ObjcMethodDecl *MDecl = dyn_cast<ObjcMethodDecl>(static_cast<Decl *>(D));
+  assert(MDecl != 0 && "Not a method declarator!");
+  
+  // Allow all of Sema to see that we are entering a method definition.
+  CurMethodDecl = MDecl;
+
+  // Create Decl objects for each parameter, entrring them in the scope for
+  // binding to their use.
+  struct DeclaratorChunk::ParamInfo PI;
+
+  // Insert the invisible arguments, self and _cmd!
+  PI.Ident = &Context.Idents.get("self");
+  PI.IdentLoc = SourceLocation(); // synthesized vars have a null location.
+  PI.InvalidType = false;
+  if (MDecl->isInstance()) {
+    QualType selfTy = Context.getObjcInterfaceType(MDecl->getClassInterface());
+    selfTy = Context.getPointerType(selfTy);
+    PI.TypeInfo = selfTy.getAsOpaquePtr();
+  } else
+    PI.TypeInfo = Context.getObjcIdType().getAsOpaquePtr();
+  CurMethodDecl->setSelfDecl(ActOnParamDeclarator(PI, FnBodyScope));
+  
+  PI.Ident = &Context.Idents.get("_cmd");
+  PI.TypeInfo = Context.getObjcSelType().getAsOpaquePtr();
+  ActOnParamDeclarator(PI, FnBodyScope);
+  
+  for (int i = 0; i <  MDecl->getNumParams(); i++) {
+    ParmVarDecl *PDecl = MDecl->getParamDecl(i);
+    PI.Ident = PDecl->getIdentifier();
+    PI.IdentLoc = PDecl->getLocation(); // user vars have a real location.
+    PI.TypeInfo = PDecl->getType().getAsOpaquePtr();
+    ActOnParamDeclarator(PI, FnBodyScope);
+  }
+}
+
+Sema::DeclTy *Sema::ActOnStartClassInterface(
+                    SourceLocation AtInterfaceLoc,
+                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                    IdentifierInfo *SuperName, SourceLocation SuperLoc,
+                    IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+                    SourceLocation EndProtoLoc, AttributeList *AttrList) {
+  assert(ClassName && "Missing class identifier");
+  
+  // Check for another declaration kind with the same name.
+  ScopedDecl *PrevDecl = LookupInterfaceDecl(ClassName);
+  if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
+    Diag(ClassLoc, diag::err_redefinition_different_kind,
+         ClassName->getName());
+    Diag(PrevDecl->getLocation(), diag::err_previous_definition);
+  }
+  
+  ObjcInterfaceDecl* IDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl);
+  if (IDecl) {
+    // Class already seen. Is it a forward declaration?
+    if (!IDecl->isForwardDecl())
+      Diag(AtInterfaceLoc, diag::err_duplicate_class_def, IDecl->getName());
+    else {
+      IDecl->setLocation(AtInterfaceLoc);
+      IDecl->setForwardDecl(false);
+      IDecl->AllocIntfRefProtocols(NumProtocols);
+    }
+  }
+  else {
+    IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, NumProtocols, ClassName);
+  
+    // Chain & install the interface decl into the identifier.
+    IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
+    ClassName->setFETokenInfo(IDecl);
+    
+    // Remember that this needs to be removed when the scope is popped.
+    TUScope->AddDecl(IDecl);
+  }
+  
+  if (SuperName) {
+    ObjcInterfaceDecl* SuperClassEntry = 0;
+    // Check if a different kind of symbol declared in this scope.
+    PrevDecl = LookupInterfaceDecl(SuperName);
+    if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
+      Diag(SuperLoc, diag::err_redefinition_different_kind,
+           SuperName->getName());
+      Diag(PrevDecl->getLocation(), diag::err_previous_definition);
+    }
+    else {
+      // Check that super class is previously defined
+      SuperClassEntry = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl); 
+                              
+      if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) {
+        Diag(AtInterfaceLoc, diag::err_undef_superclass, 
+             SuperClassEntry ? SuperClassEntry->getName() 
+                             : SuperName->getName(),
+             ClassName->getName()); 
+      }
+    }
+    IDecl->setSuperClass(SuperClassEntry);
+    IDecl->setLocEnd(SuperLoc);
+  } else { // we have a root class.
+    IDecl->setLocEnd(ClassLoc);
+  }
+  
+  /// Check then save referenced protocols
+  if (NumProtocols) {
+    for (unsigned int i = 0; i != NumProtocols; i++) {
+      ObjcProtocolDecl* RefPDecl = ObjcProtocols[ProtocolNames[i]];
+      if (!RefPDecl || RefPDecl->isForwardDecl())
+        Diag(ClassLoc, diag::warn_undef_protocolref,
+             ProtocolNames[i]->getName(),
+             ClassName->getName());
+      IDecl->setIntfRefProtocols((int)i, RefPDecl);
+    }
+    IDecl->setLocEnd(EndProtoLoc);
+  }
+  return IDecl;
+}
+
+/// ActOnCompatiblityAlias - this action is called after complete parsing of
+/// @compaatibility_alias declaration. It sets up the alias relationships.
+Sema::DeclTy *Sema::ActOnCompatiblityAlias(
+                      SourceLocation AtCompatibilityAliasLoc,
+                      IdentifierInfo *AliasName,  SourceLocation AliasLocation,
+                      IdentifierInfo *ClassName, SourceLocation ClassLocation) {
+  // Look for previous declaration of alias name
+  ScopedDecl *ADecl = LookupScopedDecl(AliasName, Decl::IDNS_Ordinary,
+                                       AliasLocation, TUScope);
+  if (ADecl) {
+    if (isa<ObjcCompatibleAliasDecl>(ADecl)) {
+      Diag(AliasLocation, diag::warn_previous_alias_decl);
+      Diag(ADecl->getLocation(), diag::warn_previous_declaration);
+    }
+    else {
+      Diag(AliasLocation, diag::err_conflicting_aliasing_type,
+           AliasName->getName());
+      Diag(ADecl->getLocation(), diag::err_previous_declaration);
+    }
+    return 0;
+  }
+  // Check for class declaration
+  ScopedDecl *CDecl = LookupScopedDecl(ClassName, Decl::IDNS_Ordinary,
+                                       ClassLocation, TUScope);
+  if (!CDecl || !isa<ObjcInterfaceDecl>(CDecl)) {
+    Diag(ClassLocation, diag::warn_undef_interface,
+         ClassName->getName());
+    if (CDecl)
+      Diag(CDecl->getLocation(), diag::warn_previous_declaration);
+    return 0;
+  }
+  // Everything checked out, instantiate a new alias declaration ast
+  ObjcCompatibleAliasDecl *AliasDecl = 
+    new ObjcCompatibleAliasDecl(AtCompatibilityAliasLoc, 
+                                AliasName,
+                                dyn_cast<ObjcInterfaceDecl>(CDecl));
+    
+  // Chain & install the interface decl into the identifier.
+  AliasDecl->setNext(AliasName->getFETokenInfo<ScopedDecl>());
+  AliasName->setFETokenInfo(AliasDecl);
+  return AliasDecl;
+}
+
+Sema::DeclTy *Sema::ActOnStartProtocolInterface(
+                SourceLocation AtProtoInterfaceLoc,
+                IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs,
+                SourceLocation EndProtoLoc) {
+  assert(ProtocolName && "Missing protocol identifier");
+  ObjcProtocolDecl *PDecl = ObjcProtocols[ProtocolName];
+  if (PDecl) {
+    // Protocol already seen. Better be a forward protocol declaration
+    if (!PDecl->isForwardDecl())
+      Diag(ProtocolLoc, diag::err_duplicate_protocol_def, 
+           ProtocolName->getName());
+    else {
+      PDecl->setForwardDecl(false);
+      PDecl->AllocReferencedProtocols(NumProtoRefs);
+    }
+  }
+  else {
+    PDecl = new ObjcProtocolDecl(AtProtoInterfaceLoc, NumProtoRefs, 
+                                 ProtocolName);
+    ObjcProtocols[ProtocolName] = PDecl;
+  }    
+  
+  if (NumProtoRefs) {
+    /// Check then save referenced protocols
+    for (unsigned int i = 0; i != NumProtoRefs; i++) {
+      ObjcProtocolDecl* RefPDecl = ObjcProtocols[ProtoRefNames[i]];
+      if (!RefPDecl || RefPDecl->isForwardDecl())
+        Diag(ProtocolLoc, diag::warn_undef_protocolref,
+             ProtoRefNames[i]->getName(),
+             ProtocolName->getName());
+      PDecl->setReferencedProtocols((int)i, RefPDecl);
+    }
+    PDecl->setLocEnd(EndProtoLoc);
+  }
+  return PDecl;
+}
+
+/// FindProtocolDeclaration - This routine looks up protocols and
+/// issuer error if they are not declared. It returns list of protocol
+/// declarations in its 'Protocols' argument.
+void
+Sema::FindProtocolDeclaration(SourceLocation TypeLoc,
+                              IdentifierInfo **ProtocolId,
+                              unsigned NumProtocols,
+                              llvm::SmallVector<DeclTy *,8> &Protocols) {
+  for (unsigned i = 0; i != NumProtocols; ++i) {
+    ObjcProtocolDecl *PDecl = ObjcProtocols[ProtocolId[i]];
+    if (!PDecl)
+      Diag(TypeLoc, diag::err_undeclared_protocol, 
+           ProtocolId[i]->getName());
+    else
+      Protocols.push_back(PDecl); 
+  }
+}
+
+/// ActOnForwardProtocolDeclaration - 
+Action::DeclTy *
+Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
+        IdentifierInfo **IdentList, unsigned NumElts) {
+  llvm::SmallVector<ObjcProtocolDecl*, 32> Protocols;
+  
+  for (unsigned i = 0; i != NumElts; ++i) {
+    IdentifierInfo *P = IdentList[i];
+    ObjcProtocolDecl *PDecl = ObjcProtocols[P];
+    if (!PDecl)  { // Not already seen?
+      // FIXME: Pass in the location of the identifier!
+      PDecl = new ObjcProtocolDecl(AtProtocolLoc, 0, P, true);
+      ObjcProtocols[P] = PDecl;
+    }
+    
+    Protocols.push_back(PDecl);
+  }
+  return new ObjcForwardProtocolDecl(AtProtocolLoc,
+                                     &Protocols[0], Protocols.size());
+}
+
+Sema::DeclTy *Sema::ActOnStartCategoryInterface(
+                      SourceLocation AtInterfaceLoc,
+                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                      IdentifierInfo *CategoryName, SourceLocation CategoryLoc,
+                      IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs,
+                      SourceLocation EndProtoLoc) {
+  ObjcInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
+  
+  /// Check that class of this category is already completely declared.
+  if (!IDecl || IDecl->isForwardDecl()) {
+    Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
+    return 0;
+  }
+  ObjcCategoryDecl *CDecl = new ObjcCategoryDecl(AtInterfaceLoc, NumProtoRefs,
+                                                 CategoryName);
+  CDecl->setClassInterface(IDecl);
+  /// Check for duplicate interface declaration for this category
+  ObjcCategoryDecl *CDeclChain;
+  for (CDeclChain = IDecl->getCategoryList(); CDeclChain;
+       CDeclChain = CDeclChain->getNextClassCategory()) {
+    if (CDeclChain->getIdentifier() == CategoryName) {
+      Diag(CategoryLoc, diag::err_dup_category_def, ClassName->getName(),
+           CategoryName->getName());
+      break;
+    }
+  }
+  if (!CDeclChain)
+    CDecl->insertNextClassCategory();
+
+  if (NumProtoRefs) {
+    /// Check then save referenced protocols
+    for (unsigned int i = 0; i != NumProtoRefs; i++) {
+      ObjcProtocolDecl* RefPDecl = ObjcProtocols[ProtoRefNames[i]];
+      if (!RefPDecl || RefPDecl->isForwardDecl()) {
+        Diag(CategoryLoc, diag::warn_undef_protocolref,
+             ProtoRefNames[i]->getName(),
+             CategoryName->getName());
+      }
+      CDecl->setCatReferencedProtocols((int)i, RefPDecl);
+    }
+    CDecl->setLocEnd(EndProtoLoc);
+  }
+  return CDecl;
+}
+
+/// ActOnStartCategoryImplementation - Perform semantic checks on the
+/// category implementation declaration and build an ObjcCategoryImplDecl
+/// object.
+Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
+                      SourceLocation AtCatImplLoc,
+                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                      IdentifierInfo *CatName, SourceLocation CatLoc) {
+  ObjcInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
+  ObjcCategoryImplDecl *CDecl = new ObjcCategoryImplDecl(AtCatImplLoc, 
+                                                         CatName, IDecl);
+  /// Check that class of this category is already completely declared.
+  if (!IDecl || IDecl->isForwardDecl())
+    Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
+
+  /// TODO: Check that CatName, category name, is not used in another
+  // implementation.
+  return CDecl;
+}
+
+Sema::DeclTy *Sema::ActOnStartClassImplementation(
+                      SourceLocation AtClassImplLoc,
+                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                      IdentifierInfo *SuperClassname, 
+                      SourceLocation SuperClassLoc) {
+  ObjcInterfaceDecl* IDecl = 0;
+  // Check for another declaration kind with the same name.
+  ScopedDecl *PrevDecl = LookupInterfaceDecl(ClassName);
+  if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
+    Diag(ClassLoc, diag::err_redefinition_different_kind,
+         ClassName->getName());
+    Diag(PrevDecl->getLocation(), diag::err_previous_definition);
+  }
+  else {
+    // Is there an interface declaration of this class; if not, warn!
+    IDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl); 
+    if (!IDecl)
+      Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName());
+  }
+  
+  // Check that super class name is valid class name
+  ObjcInterfaceDecl* SDecl = 0;
+  if (SuperClassname) {
+    // Check if a different kind of symbol declared in this scope.
+    PrevDecl = LookupInterfaceDecl(SuperClassname);
+    if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
+      Diag(SuperClassLoc, diag::err_redefinition_different_kind,
+           SuperClassname->getName());
+      Diag(PrevDecl->getLocation(), diag::err_previous_definition);
+    }
+    else {
+      SDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl); 
+      if (!SDecl)
+        Diag(SuperClassLoc, diag::err_undef_superclass, 
+             SuperClassname->getName(), ClassName->getName());
+      else if (IDecl && IDecl->getSuperClass() != SDecl) {
+        // This implementation and its interface do not have the same
+        // super class.
+        Diag(SuperClassLoc, diag::err_conflicting_super_class, 
+             SDecl->getName());
+        Diag(SDecl->getLocation(), diag::err_previous_definition);
+      }
+    }
+  }
+  
+  if (!IDecl) {
+    // Legacy case of @implementation with no corresponding @interface.
+    // Build, chain & install the interface decl into the identifier.
+    IDecl = new ObjcInterfaceDecl(AtClassImplLoc, 0, ClassName, 
+				  false, true);
+    IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
+    ClassName->setFETokenInfo(IDecl);
+    IDecl->setSuperClass(SDecl);
+    IDecl->setLocEnd(ClassLoc);
+    
+    // Remember that this needs to be removed when the scope is popped.
+    TUScope->AddDecl(IDecl);
+  }
+  
+  ObjcImplementationDecl* IMPDecl = 
+  new ObjcImplementationDecl(AtClassImplLoc, ClassName, IDecl, SDecl);
+  
+  // Check that there is no duplicate implementation of this class.
+  if (ObjcImplementations[ClassName])
+    Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName());
+  else // add it to the list.
+    ObjcImplementations[ClassName] = IMPDecl;
+  return IMPDecl;
+}
+
+void Sema::CheckImplementationIvars(ObjcImplementationDecl *ImpDecl,
+                                    ObjcIvarDecl **ivars, unsigned numIvars,
+                                    SourceLocation RBrace) {
+  assert(ImpDecl && "missing implementation decl");
+  ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(ImpDecl->getIdentifier());
+  if (!IDecl)
+    return;
+  /// Check case of non-existing @interface decl.
+  /// (legacy objective-c @implementation decl without an @interface decl).
+  /// Add implementations's ivar to the synthesize class's ivar list.
+  if (IDecl->ImplicitInterfaceDecl()) {
+    IDecl->addInstanceVariablesToClass(ivars, numIvars, RBrace);
+    return;
+  }
+  // If implementation has empty ivar list, just return.
+  if (numIvars == 0)
+    return;
+  
+  assert(ivars && "missing @implementation ivars");
+  
+  // Check interface's Ivar list against those in the implementation.
+  // names and types must match.
+  //
+  ObjcIvarDecl** IntfIvars = IDecl->getInstanceVariables();
+  int IntfNumIvars = IDecl->getNumInstanceVariables();
+  unsigned j = 0;
+  bool err = false;
+  while (numIvars > 0 && IntfNumIvars > 0) {
+    ObjcIvarDecl* ImplIvar = ivars[j];
+    ObjcIvarDecl* ClsIvar = IntfIvars[j++];
+    assert (ImplIvar && "missing implementation ivar");
+    assert (ClsIvar && "missing class ivar");
+    if (ImplIvar->getCanonicalType() != ClsIvar->getCanonicalType()) {
+      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type,
+           ImplIvar->getIdentifier()->getName());
+      Diag(ClsIvar->getLocation(), diag::err_previous_definition,
+           ClsIvar->getIdentifier()->getName());
+    }
+    // TODO: Two mismatched (unequal width) Ivar bitfields should be diagnosed 
+    // as error.
+    else if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
+      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name,
+           ImplIvar->getIdentifier()->getName());
+      Diag(ClsIvar->getLocation(), diag::err_previous_definition,
+           ClsIvar->getIdentifier()->getName());
+      err = true;
+      break;
+    }
+    --numIvars;
+    --IntfNumIvars;
+  }
+  if (!err && (numIvars > 0 || IntfNumIvars > 0))
+    Diag(numIvars > 0 ? ivars[j]->getLocation() : IntfIvars[j]->getLocation(), 
+         diag::err_inconsistant_ivar);
+      
+}
+
+/// CheckProtocolMethodDefs - This routine checks unimpletented methods
+/// Declared in protocol, and those referenced by it.
+void Sema::CheckProtocolMethodDefs(ObjcProtocolDecl *PDecl,
+                                   bool& IncompleteImpl,
+             const llvm::DenseSet<Selector> &InsMap,
+             const llvm::DenseSet<Selector> &ClsMap) {
+  // check unimplemented instance methods.
+  ObjcMethodDecl** methods = PDecl->getInstanceMethods();
+  for (int j = 0; j < PDecl->getNumInstanceMethods(); j++) {
+    if (!InsMap.count(methods[j]->getSelector()) && 
+        methods[j]->getImplementationControl() != ObjcMethodDecl::Optional) {
+      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+           methods[j]->getSelector().getName());
+      IncompleteImpl = true;
+    }
+  }
+  // check unimplemented class methods
+  methods = PDecl->getClassMethods();
+  for (int j = 0; j < PDecl->getNumClassMethods(); j++)
+    if (!ClsMap.count(methods[j]->getSelector()) &&
+        methods[j]->getImplementationControl() != ObjcMethodDecl::Optional) {
+      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+           methods[j]->getSelector().getName());
+      IncompleteImpl = true;
+    }
+  
+  // Check on this protocols's referenced protocols, recursively
+  ObjcProtocolDecl** RefPDecl = PDecl->getReferencedProtocols();
+  for (int i = 0; i < PDecl->getNumReferencedProtocols(); i++)
+    CheckProtocolMethodDefs(RefPDecl[i], IncompleteImpl, InsMap, ClsMap);
+}
+
+void Sema::ImplMethodsVsClassMethods(ObjcImplementationDecl* IMPDecl, 
+                                     ObjcInterfaceDecl* IDecl) {
+  llvm::DenseSet<Selector> InsMap;
+  // Check and see if instance methods in class interface have been
+  // implemented in the implementation class.
+  ObjcMethodDecl *const*methods = IMPDecl->getInstanceMethods();
+  for (int i=0; i < IMPDecl->getNumInstanceMethods(); i++) 
+    InsMap.insert(methods[i]->getSelector());
+  
+  bool IncompleteImpl = false;
+  methods = IDecl->getInstanceMethods();
+  for (int j = 0; j < IDecl->getNumInstanceMethods(); j++)
+    if (!InsMap.count(methods[j]->getSelector())) {
+      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+           methods[j]->getSelector().getName());
+      IncompleteImpl = true;
+    }
+  llvm::DenseSet<Selector> ClsMap;
+  // Check and see if class methods in class interface have been
+  // implemented in the implementation class.
+  methods = IMPDecl->getClassMethods();
+  for (int i=0; i < IMPDecl->getNumClassMethods(); i++)
+    ClsMap.insert(methods[i]->getSelector());
+  
+  methods = IDecl->getClassMethods();
+  for (int j = 0; j < IDecl->getNumClassMethods(); j++)
+    if (!ClsMap.count(methods[j]->getSelector())) {
+      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+           methods[j]->getSelector().getName());
+      IncompleteImpl = true;
+    }
+  
+  // Check the protocol list for unimplemented methods in the @implementation
+  // class.
+  ObjcProtocolDecl** protocols = IDecl->getReferencedProtocols();
+  for (int i = 0; i < IDecl->getNumIntfRefProtocols(); i++)
+    CheckProtocolMethodDefs(protocols[i], IncompleteImpl, InsMap, ClsMap);
+
+  if (IncompleteImpl)
+    Diag(IMPDecl->getLocation(), diag::warn_incomplete_impl_class, 
+         IMPDecl->getName());
+}
+
+/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
+/// category interface is implemented in the category @implementation.
+void Sema::ImplCategoryMethodsVsIntfMethods(ObjcCategoryImplDecl *CatImplDecl,
+                                            ObjcCategoryDecl *CatClassDecl) {
+  llvm::DenseSet<Selector> InsMap;
+  // Check and see if instance methods in category interface have been
+  // implemented in its implementation class.
+  ObjcMethodDecl *const*methods = CatImplDecl->getInstanceMethods();
+  for (int i=0; i < CatImplDecl->getNumInstanceMethods(); i++)
+    InsMap.insert(methods[i]->getSelector());
+  
+  bool IncompleteImpl = false;
+  methods = CatClassDecl->getInstanceMethods();
+  for (int j = 0; j < CatClassDecl->getNumInstanceMethods(); j++)
+    if (!InsMap.count(methods[j]->getSelector())) {
+      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+           methods[j]->getSelector().getName());
+      IncompleteImpl = true;
+    }
+  llvm::DenseSet<Selector> ClsMap;
+  // Check and see if class methods in category interface have been
+  // implemented in its implementation class.
+  methods = CatImplDecl->getClassMethods();
+  for (int i=0; i < CatImplDecl->getNumClassMethods(); i++)
+    ClsMap.insert(methods[i]->getSelector());
+  
+  methods = CatClassDecl->getClassMethods();
+  for (int j = 0; j < CatClassDecl->getNumClassMethods(); j++)
+    if (!ClsMap.count(methods[j]->getSelector())) {
+      Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+           methods[j]->getSelector().getName());
+      IncompleteImpl = true;
+    }
+  
+  // Check the protocol list for unimplemented methods in the @implementation
+  // class.
+  ObjcProtocolDecl** protocols = CatClassDecl->getReferencedProtocols();
+  for (int i = 0; i < CatClassDecl->getNumReferencedProtocols(); i++) {
+    ObjcProtocolDecl* PDecl = protocols[i];
+    CheckProtocolMethodDefs(PDecl, IncompleteImpl, InsMap, ClsMap);
+  }
+  if (IncompleteImpl)
+    Diag(CatImplDecl->getLocation(), diag::warn_incomplete_impl_category, 
+         CatClassDecl->getName());
+}
+
+/// ActOnForwardClassDeclaration - 
+Action::DeclTy *
+Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
+                                   IdentifierInfo **IdentList, unsigned NumElts) 
+{
+  llvm::SmallVector<ObjcInterfaceDecl*, 32> Interfaces;
+  
+  for (unsigned i = 0; i != NumElts; ++i) {
+    // Check for another declaration kind with the same name.
+    ScopedDecl *PrevDecl = LookupInterfaceDecl(IdentList[i]);
+    if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
+      Diag(AtClassLoc, diag::err_redefinition_different_kind,
+           IdentList[i]->getName());
+      Diag(PrevDecl->getLocation(), diag::err_previous_definition);
+    }
+    ObjcInterfaceDecl *IDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl); 
+    if (!IDecl) {  // Not already seen?  Make a forward decl.
+      IDecl = new ObjcInterfaceDecl(AtClassLoc, 0, IdentList[i], true);
+      // Chain & install the interface decl into the identifier.
+      IDecl->setNext(IdentList[i]->getFETokenInfo<ScopedDecl>());
+      IdentList[i]->setFETokenInfo(IDecl);
+
+      // Remember that this needs to be removed when the scope is popped.
+      TUScope->AddDecl(IDecl);
+    }
+
+    Interfaces.push_back(IDecl);
+  }
+  
+  return new ObjcClassDecl(AtClassLoc, &Interfaces[0], Interfaces.size());
+}
+
+
+/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
+/// returns true, or false, accordingly.
+/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
+bool Sema::MatchTwoMethodDeclarations(const ObjcMethodDecl *Method, 
+                                      const ObjcMethodDecl *PrevMethod) {
+  if (Method->getResultType().getCanonicalType() !=
+      PrevMethod->getResultType().getCanonicalType())
+    return false;
+  for (int i = 0; i < Method->getNumParams(); i++) {
+    ParmVarDecl *ParamDecl = Method->getParamDecl(i);
+    ParmVarDecl *PrevParamDecl = PrevMethod->getParamDecl(i);
+    if (ParamDecl->getCanonicalType() != PrevParamDecl->getCanonicalType())
+      return false;
+  }
+  return true;
+}
+
+void Sema::AddInstanceMethodToGlobalPool(ObjcMethodDecl *Method) {
+  ObjcMethodList &FirstMethod = InstanceMethodPool[Method->getSelector()];
+  if (!FirstMethod.Method) {
+    // Haven't seen a method with this selector name yet - add it.
+    FirstMethod.Method = Method;
+    FirstMethod.Next = 0;
+  } else {
+    // We've seen a method with this name, now check the type signature(s).
+    bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
+    
+    for (ObjcMethodList *Next = FirstMethod.Next; !match && Next; 
+         Next = Next->Next)
+      match = MatchTwoMethodDeclarations(Method, Next->Method);
+      
+    if (!match) {
+      // We have a new signature for an existing method - add it.
+      // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
+      struct ObjcMethodList *OMI = new ObjcMethodList(Method, FirstMethod.Next);
+      FirstMethod.Next = OMI;
+    }
+  }
+}
+
+void Sema::AddFactoryMethodToGlobalPool(ObjcMethodDecl *Method) {
+  ObjcMethodList &FirstMethod = FactoryMethodPool[Method->getSelector()];
+  if (!FirstMethod.Method) {
+    // Haven't seen a method with this selector name yet - add it.
+    FirstMethod.Method = Method;
+    FirstMethod.Next = 0;
+  } else {
+    // We've seen a method with this name, now check the type signature(s).
+    bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
+    
+    for (ObjcMethodList *Next = FirstMethod.Next; !match && Next; 
+         Next = Next->Next)
+      match = MatchTwoMethodDeclarations(Method, Next->Method);
+      
+    if (!match) {
+      // We have a new signature for an existing method - add it.
+      // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
+      struct ObjcMethodList *OMI = new ObjcMethodList(Method, FirstMethod.Next);
+      FirstMethod.Next = OMI;
+    }
+  }
+}
+
+void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
+                      DeclTy **allMethods, unsigned allNum,
+                      DeclTy **allProperties, unsigned pNum) {
+  Decl *ClassDecl = static_cast<Decl *>(classDecl);
+
+  // FIXME: If we don't have a ClassDecl, we have an error. I (snaroff) would
+  // prefer we always pass in a decl. If the decl has an error, isInvalidDecl()
+  // should be true.
+  if (!ClassDecl)
+    return;
+    
+  llvm::SmallVector<ObjcMethodDecl*, 32> insMethods;
+  llvm::SmallVector<ObjcMethodDecl*, 16> clsMethods;
+  
+  llvm::DenseMap<Selector, const ObjcMethodDecl*> InsMap;
+  llvm::DenseMap<Selector, const ObjcMethodDecl*> ClsMap;
+  
+  bool isInterfaceDeclKind = 
+        (isa<ObjcInterfaceDecl>(ClassDecl) || isa<ObjcCategoryDecl>(ClassDecl)
+         || isa<ObjcProtocolDecl>(ClassDecl));
+  bool checkIdenticalMethods = isa<ObjcImplementationDecl>(ClassDecl);
+  
+  // TODO: property declaration in category and protocols.
+  if (pNum != 0 && isa<ObjcInterfaceDecl>(ClassDecl)) {
+    ObjcPropertyDecl **properties = new ObjcPropertyDecl*[pNum];
+    memcpy(properties, allProperties, pNum*sizeof(ObjcPropertyDecl*));
+    dyn_cast<ObjcInterfaceDecl>(ClassDecl)->setPropertyDecls(properties);
+    dyn_cast<ObjcInterfaceDecl>(ClassDecl)->setNumPropertyDecl(pNum);
+  }
+  
+  for (unsigned i = 0; i < allNum; i++ ) {
+    ObjcMethodDecl *Method =
+      cast_or_null<ObjcMethodDecl>(static_cast<Decl*>(allMethods[i]));
+
+    if (!Method) continue;  // Already issued a diagnostic.
+    if (Method->isInstance()) {
+      /// Check for instance method of the same name with incompatible types
+      const ObjcMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
+      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 
+                              : false;
+      if (isInterfaceDeclKind && PrevMethod && !match 
+          || checkIdenticalMethods && match) {
+          Diag(Method->getLocation(), diag::error_duplicate_method_decl,
+               Method->getSelector().getName());
+          Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
+      } else {
+        insMethods.push_back(Method);
+        InsMap[Method->getSelector()] = Method;
+        /// The following allows us to typecheck messages to "id".
+        AddInstanceMethodToGlobalPool(Method);
+      }
+    }
+    else {
+      /// Check for class method of the same name with incompatible types
+      const ObjcMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
+      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 
+                              : false;
+      if (isInterfaceDeclKind && PrevMethod && !match 
+          || checkIdenticalMethods && match) {
+        Diag(Method->getLocation(), diag::error_duplicate_method_decl,
+             Method->getSelector().getName());
+        Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
+      } else {
+        clsMethods.push_back(Method);
+        ClsMap[Method->getSelector()] = Method;
+        /// The following allows us to typecheck messages to "id".
+        AddInstanceMethodToGlobalPool(Method);
+      }
+    }
+  }
+  
+  if (ObjcInterfaceDecl *I = dyn_cast<ObjcInterfaceDecl>(ClassDecl)) {
+    I->addMethods(&insMethods[0], insMethods.size(),
+                  &clsMethods[0], clsMethods.size(), AtEndLoc);
+  } else if (ObjcProtocolDecl *P = dyn_cast<ObjcProtocolDecl>(ClassDecl)) {
+    P->addMethods(&insMethods[0], insMethods.size(),
+                  &clsMethods[0], clsMethods.size(), AtEndLoc);
+  }
+  else if (ObjcCategoryDecl *C = dyn_cast<ObjcCategoryDecl>(ClassDecl)) {
+    C->addMethods(&insMethods[0], insMethods.size(),
+                  &clsMethods[0], clsMethods.size(), AtEndLoc);
+  }
+  else if (ObjcImplementationDecl *IC = 
+                dyn_cast<ObjcImplementationDecl>(ClassDecl)) {
+    IC->setLocEnd(AtEndLoc);
+    if (ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier()))
+      ImplMethodsVsClassMethods(IC, IDecl);
+  } else {
+    ObjcCategoryImplDecl* CatImplClass = cast<ObjcCategoryImplDecl>(ClassDecl);
+    CatImplClass->setLocEnd(AtEndLoc);
+    ObjcInterfaceDecl* IDecl = CatImplClass->getClassInterface();
+    // Find category interface decl and then check that all methods declared
+    // in this interface is implemented in the category @implementation.
+    if (IDecl) {
+      for (ObjcCategoryDecl *Categories = IDecl->getCategoryList();
+           Categories; Categories = Categories->getNextClassCategory()) {
+        if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
+          ImplCategoryMethodsVsIntfMethods(CatImplClass, Categories);
+          break;
+        }
+      }
+    }
+  }
+}
+
+
+/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
+/// objective-c's type qualifier from the parser version of the same info.
+static Decl::ObjcDeclQualifier 
+CvtQTToAstBitMask(ObjcDeclSpec::ObjcDeclQualifier PQTVal) {
+  Decl::ObjcDeclQualifier ret = Decl::OBJC_TQ_None;
+  if (PQTVal & ObjcDeclSpec::DQ_In)
+    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_In);
+  if (PQTVal & ObjcDeclSpec::DQ_Inout)
+    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Inout);
+  if (PQTVal & ObjcDeclSpec::DQ_Out)
+    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Out);
+  if (PQTVal & ObjcDeclSpec::DQ_Bycopy)
+    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Bycopy);
+  if (PQTVal & ObjcDeclSpec::DQ_Byref)
+    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Byref);
+  if (PQTVal & ObjcDeclSpec::DQ_Oneway)
+    ret = (Decl::ObjcDeclQualifier)(ret | Decl::OBJC_TQ_Oneway);
+
+  return ret;
+}
+
+Sema::DeclTy *Sema::ActOnMethodDeclaration(
+    SourceLocation MethodLoc, SourceLocation EndLoc,
+    tok::TokenKind MethodType, DeclTy *ClassDecl,
+    ObjcDeclSpec &ReturnQT, TypeTy *ReturnType,
+    Selector Sel,
+    // optional arguments. The number of types/arguments is obtained
+    // from the Sel.getNumArgs().
+    ObjcDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames,
+    AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
+    bool isVariadic) {
+  llvm::SmallVector<ParmVarDecl*, 16> Params;
+  
+  for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
+    // FIXME: arg->AttrList must be stored too!
+    QualType argType;
+    
+    if (ArgTypes[i])
+      argType = QualType::getFromOpaquePtr(ArgTypes[i]);
+    else
+      argType = Context.getObjcIdType();
+    ParmVarDecl* Param = new ParmVarDecl(SourceLocation(/*FIXME*/), ArgNames[i], 
+                                         argType, VarDecl::None, 0);
+    Param->setObjcDeclQualifier(
+      CvtQTToAstBitMask(ArgQT[i].getObjcDeclQualifier()));
+    Params.push_back(Param);
+  }
+  QualType resultDeclType;
+  
+  if (ReturnType)
+    resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+  else // get the type for "id".
+    resultDeclType = Context.getObjcIdType();
+  
+  Decl *CDecl = static_cast<Decl*>(ClassDecl);
+  ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, EndLoc, Sel,
+                                      resultDeclType,
+                                      CDecl,
+                                      0, -1, AttrList, 
+                                      MethodType == tok::minus, isVariadic,
+                                      MethodDeclKind == tok::objc_optional ? 
+                                      ObjcMethodDecl::Optional : 
+                                      ObjcMethodDecl::Required);
+  ObjcMethod->setMethodParams(&Params[0], Sel.getNumArgs());
+  ObjcMethod->setObjcDeclQualifier(
+    CvtQTToAstBitMask(ReturnQT.getObjcDeclQualifier()));
+  const ObjcMethodDecl *PrevMethod = 0;
+ 
+  // For implementations (which can be very "coarse grain"), we add the 
+  // method now. This allows the AST to implement lookup methods that work 
+  // incrementally (without waiting until we parse the @end). It also allows 
+  // us to flag multiple declaration errors as they occur.
+  if (ObjcImplementationDecl *ImpDecl = 
+        dyn_cast<ObjcImplementationDecl>(CDecl)) {
+    if (MethodType == tok::minus) {
+      PrevMethod = ImpDecl->lookupInstanceMethod(Sel);
+      ImpDecl->addInstanceMethod(ObjcMethod);
+    } else {
+      PrevMethod = ImpDecl->lookupClassMethod(Sel);
+      ImpDecl->addClassMethod(ObjcMethod);
+    }
+  } 
+  else if (ObjcCategoryImplDecl *CatImpDecl = 
+            dyn_cast<ObjcCategoryImplDecl>(CDecl)) {
+    if (MethodType == tok::minus) {
+      PrevMethod = CatImpDecl->lookupInstanceMethod(Sel);
+      CatImpDecl->addInstanceMethod(ObjcMethod);
+    } else {
+      PrevMethod = CatImpDecl->lookupClassMethod(Sel);
+      CatImpDecl->addClassMethod(ObjcMethod);
+    }
+  }
+  if (PrevMethod) {
+    // You can never have two method definitions with the same name.
+    Diag(ObjcMethod->getLocation(), diag::error_duplicate_method_decl,
+        ObjcMethod->getSelector().getName());
+    Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
+  } 
+  return ObjcMethod;
+}
+
+Sema::DeclTy *Sema::ActOnAddObjcProperties(SourceLocation AtLoc, 
+  DeclTy **allProperties, unsigned NumProperties, ObjcDeclSpec &DS) {
+  ObjcPropertyDecl *PDecl = new ObjcPropertyDecl(AtLoc);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readonly)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readonly);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_getter) {
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_getter);
+    PDecl->setGetterName(DS.getGetterName());
+  }
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_setter) {
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_setter);
+    PDecl->setSetterName(DS.getSetterName());
+  }
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_assign)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_assign);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readwrite)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readwrite);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_retain)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_retain);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_copy)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_copy);
+  
+  if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_nonatomic)
+    PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_nonatomic);
+  
+  PDecl->setNumPropertyDecls(NumProperties);
+  if (NumProperties != 0) {
+    ObjcIvarDecl **properties = new ObjcIvarDecl*[NumProperties];
+    memcpy(properties, allProperties, NumProperties*sizeof(ObjcIvarDecl*));
+    PDecl->setPropertyDecls(properties);
+  }
+  return PDecl;
+}
+

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=44925&r1=44924&r2=44925&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Wed Dec 12 01:09:47 2007
@@ -82,6 +82,7 @@
 		DE67E7280C02109800F66BC5 /* ASTStreamer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE67E7270C02109800F66BC5 /* ASTStreamer.h */; };
 		DE6951C70C4D1F5D00A5826B /* RecordLayout.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE6951C60C4D1F5D00A5826B /* RecordLayout.h */; };
 		DE6954640C5121BD00A5826B /* Token.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE6954630C5121BD00A5826B /* Token.h */; };
+		DE704B260D0FBEBE009C7762 /* SemaDeclObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */; };
 		DE75ED290B044DC90020CF81 /* ASTContext.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE75ED280B044DC90020CF81 /* ASTContext.h */; };
 		DE75EDF10B06880E0020CF81 /* Type.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE75EDF00B06880E0020CF81 /* Type.cpp */; };
 		DE928B130C05659200231DA4 /* ModuleBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE928B120C05659200231DA4 /* ModuleBuilder.cpp */; };
@@ -312,6 +313,7 @@
 		DE67E7270C02109800F66BC5 /* ASTStreamer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASTStreamer.h; path = clang/Sema/ASTStreamer.h; sourceTree = "<group>"; };
 		DE6951C60C4D1F5D00A5826B /* RecordLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = RecordLayout.h; path = clang/AST/RecordLayout.h; sourceTree = "<group>"; };
 		DE6954630C5121BD00A5826B /* Token.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Token.h; sourceTree = "<group>"; };
+		DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclObjC.cpp; path = Sema/SemaDeclObjC.cpp; sourceTree = "<group>"; };
 		DE75ED280B044DC90020CF81 /* ASTContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASTContext.h; path = clang/AST/ASTContext.h; sourceTree = "<group>"; };
 		DE75EDF00B06880E0020CF81 /* Type.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Type.cpp; path = AST/Type.cpp; sourceTree = "<group>"; };
 		DE928B120C05659200231DA4 /* ModuleBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleBuilder.cpp; path = CodeGen/ModuleBuilder.cpp; sourceTree = "<group>"; };
@@ -523,6 +525,7 @@
 				DE67E7160C020EE400F66BC5 /* Sema.cpp */,
 				DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */,
 				DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */,
+				DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */,
 				DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */,
 				DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */,
 				DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */,
@@ -867,6 +870,7 @@
 				35839B0C0CDF845F006ED061 /* TypeSerialization.cpp in Sources */,
 				3580CC0C0D072E5C00C5E4F4 /* LangOptions.cpp in Sources */,
 				353612DA0D075174002E3541 /* TranslationUnit.cpp in Sources */,
+				DE704B260D0FBEBE009C7762 /* SemaDeclObjC.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};





More information about the cfe-commits mailing list