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



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44027 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index cd47b94..65488ca 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -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;
 }