[cfe-commits] r44027 - in /cfe/trunk: AST/Decl.cpp Sema/SemaDecl.cpp include/clang/AST/DeclObjC.h

Steve Naroff snaroff at apple.com
Mon Nov 12 14:05:31 PST 2007


Author: snaroff
Date: Mon Nov 12 16:05:31 2007
New Revision: 44027

URL: http://llvm.org/viewvc/llvm-project?rev=44027&view=rev
Log:

Add category method definitions incrementally, removing a FIXME (like we do for class implementations).


Modified:
    cfe/trunk/AST/Decl.cpp
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/include/clang/AST/DeclObjC.h

Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=44027&r1=44026&r2=44027&view=diff

==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Mon Nov 12 16:05:31 2007
@@ -388,26 +388,6 @@
   AtEndLoc = endLoc;
 }
 
-/// addMethods - Insert instance and methods declarations into
-/// ObjcCategoryImplDecl's CatInsMethods and CatClsMethods fields.
-///
-void ObjcCategoryImplDecl::addMethods(ObjcMethodDecl **insMethods, 
-                                      unsigned numInsMembers,
-                                      ObjcMethodDecl **clsMethods,
-                                      unsigned numClsMembers,
-                                      SourceLocation AtEndLoc) {
-  NumInstanceMethods = numInsMembers;
-  if (numInsMembers) {
-    InstanceMethods = new ObjcMethodDecl*[numInsMembers];
-    memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
-  }
-  NumClassMethods = numClsMembers;
-  if (numClsMembers) {
-    ClassMethods = new ObjcMethodDecl*[numClsMembers];
-    memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
-  }
-}
-
 ObjcIvarDecl *ObjcInterfaceDecl::lookupInstanceVariable(
   IdentifierInfo *ID, ObjcInterfaceDecl *&clsDeclared) {
   ObjcInterfaceDecl* ClassDecl = this;
@@ -535,3 +515,30 @@
   return NULL;
 }
 
+// lookupInstanceMethod - This method returns an instance method by looking in
+// the class implementation. Unlike interfaces, we don't look outside the
+// implementation.
+ObjcMethodDecl *ObjcCategoryImplDecl::lookupInstanceMethod(Selector &Sel) {
+  ObjcMethodDecl *const*methods = getInstanceMethods();
+  int methodCount = getNumInstanceMethods();
+  for (int i = 0; i < methodCount; ++i) {
+    if (methods[i]->getSelector() == Sel) {
+      return methods[i];
+    }
+  }
+  return NULL;
+}
+
+// lookupClassMethod - This method returns an instance method by looking in
+// the class implementation. Unlike interfaces, we don't look outside the
+// implementation.
+ObjcMethodDecl *ObjcCategoryImplDecl::lookupClassMethod(Selector &Sel) {
+  ObjcMethodDecl *const*methods = getClassMethods();
+  int methodCount = getNumClassMethods();
+  for (int i = 0; i < methodCount; ++i) {
+    if (methods[i]->getSelector() == Sel) {
+      return methods[i];
+    }
+  }
+  return NULL;
+}

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Nov 12 16:05:31 2007
@@ -1522,7 +1522,7 @@
   llvm::DenseSet<Selector> InsMap;
   // Check and see if instance methods in category interface have been
   // implemented in its implementation class.
-  ObjcMethodDecl **methods = CatImplDecl->getInstanceMethods();
+  ObjcMethodDecl *const*methods = CatImplDecl->getInstanceMethods();
   for (int i=0; i < CatImplDecl->getNumInstanceMethods(); i++)
     InsMap.insert(methods[i]->getSelector());
   
@@ -2070,8 +2070,7 @@
       ImplMethodsVsClassMethods(IC, IDecl);
   } else {
     ObjcCategoryImplDecl* CatImplClass = cast<ObjcCategoryImplDecl>(ClassDecl);
-    CatImplClass->addMethods(&insMethods[0], insMethods.size(),
-                             &clsMethods[0], clsMethods.size(), AtEndLoc);
+    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.
@@ -2143,13 +2142,14 @@
   Decl *CDecl = static_cast<Decl*>(ClassDecl);
   ObjcInterfaceDecl *IDecl = 0;
   ObjcImplementationDecl *ImpDecl = 0;
+  ObjcCategoryImplDecl *CatImpDecl = 0;
   if (isa<ObjcInterfaceDecl>(CDecl))
     IDecl = cast<ObjcInterfaceDecl>(CDecl);
   else if (isa<ObjcCategoryDecl>(CDecl))
     IDecl = cast<ObjcCategoryDecl>(CDecl)->getClassInterface(); // FIXME: what is this? (talk to fariborz)
   else if ((ImpDecl = dyn_cast<ObjcImplementationDecl>(CDecl)))
     IDecl = ImpDecl->getClassInterface(); // FIXME: what is this? (talk to fariborz)
-  else if (isa<ObjcCategoryImplDecl>(CDecl))
+  else if ((CatImpDecl = dyn_cast<ObjcCategoryImplDecl>(CDecl)))
     IDecl = cast<ObjcCategoryImplDecl>(CDecl)->getClassInterface(); // FIXME: what is this? (talk to fariborz)
   
   ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, EndLoc, Sel,
@@ -2163,13 +2163,12 @@
   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 (ImpDecl) {
-    // 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.
-    // FIXME: still need to do this for ObjcCategoryImplDecl.
-    const ObjcMethodDecl *PrevMethod = 0;
     if (MethodType == tok::minus) {
       PrevMethod = ImpDecl->lookupInstanceMethod(Sel);
       ImpDecl->addInstanceMethod(ObjcMethod);
@@ -2177,13 +2176,21 @@
       PrevMethod = ImpDecl->lookupClassMethod(Sel);
       ImpDecl->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);
-    } 
+  } else if (CatImpDecl) {
+    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;
 }
 

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=44027&r1=44026&r2=44027&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Nov 12 16:05:31 2007
@@ -572,36 +572,47 @@
   /// Class interface for this category implementation
   ObjcInterfaceDecl *ClassInterface;
 
-  /// category instance methods being implemented
-  ObjcMethodDecl **InstanceMethods; // Null if category is not implementing any
-  int NumInstanceMethods;           // -1 if category is not implementing any
-  
-  /// category class methods being implemented
-  ObjcMethodDecl **ClassMethods; // Null if category is not implementing any
-  int NumClassMethods;  // -1 if category is not implementing any
+  /// implemented instance methods
+  llvm::SmallVector<ObjcMethodDecl*, 32> InstanceMethods;
   
-  public:
+  /// implemented class methods
+  llvm::SmallVector<ObjcMethodDecl*, 32> ClassMethods;
+
+  SourceLocation EndLoc;  
+public:
     ObjcCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
                          ObjcInterfaceDecl *classInterface)
     : NamedDecl(ObjcCategoryImpl, L, Id),
-    ClassInterface(classInterface),
-    InstanceMethods(0), NumInstanceMethods(-1),
-    ClassMethods(0), NumClassMethods(-1) {}
+    ClassInterface(classInterface) {}
         
-    ObjcInterfaceDecl *getClassInterface() const { 
-      return ClassInterface; 
-    }
-  
-  ObjcMethodDecl **getInstanceMethods() const { return InstanceMethods; }
-  int getNumInstanceMethods() const { return NumInstanceMethods; }
-  
-  ObjcMethodDecl **getClassMethods() const { return ClassMethods; }
-  int getNumClassMethods() const { return NumClassMethods; }
-  
-  void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
-                  ObjcMethodDecl **clsMethods, unsigned numClsMembers,
-                  SourceLocation AtEndLoc);
+  ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; }
   
+  // FIXME: Figure out how to remove the const pointer below.
+  ObjcMethodDecl *const*getInstanceMethods() const {
+    return &InstanceMethods[0];
+  }
+  int getNumInstanceMethods() const { return InstanceMethods.size(); }
+  
+  // FIXME: Figure out how to remove the const pointer below.
+  ObjcMethodDecl *const*getClassMethods() const { 
+    return &ClassMethods[0];
+  }
+  int getNumClassMethods() const { return ClassMethods.size(); }
+
+  void addInstanceMethod(ObjcMethodDecl *method) {
+    InstanceMethods.push_back(method);
+  }
+  void addClassMethod(ObjcMethodDecl *method) {
+    ClassMethods.push_back(method);
+  }    
+  ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
+  ObjcMethodDecl *lookupClassMethod(Selector &Sel);
+
+  // Location information, modeled after the Stmt API. 
+  SourceLocation getLocStart() const { return getLocation(); }
+  SourceLocation getLocEnd() const { return EndLoc; }
+  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
+    
   static bool classof(const Decl *D) { return D->getKind() == ObjcCategoryImpl;}
   static bool classof(const ObjcCategoryImplDecl *D) { return true; }
 };





More information about the cfe-commits mailing list