]> granicus.if.org Git - clang/commitdiff
Improve how we find private method decls. This involved:
authorSteve Naroff <snaroff@apple.com>
Tue, 18 Dec 2007 01:30:32 +0000 (01:30 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 18 Dec 2007 01:30:32 +0000 (01:30 +0000)
- Changed Sema::ObjcActOnStartOfMethodDef() to register the methods with the global pools.
- Changed Sema::ActOnInstanceMessage() to look in global pools (should be much less error prone).
- Added a test case to message.m (for lookup that was broken).

Misc changes while I was investigating this...

- Changed Sema::ActOnAtEnd() to call AddFactoryMethodToGlobalPool (this looked like a cut/paste error).
- Added a comment and tweaked another where I was using the first person.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45142 91177308-0d34-0410-b5e6-96231b3b80d8

Sema/SemaDeclObjC.cpp
Sema/SemaExpr.cpp
test/Sema/message.m

index d520c4f357cdabcd1d572462ad87a5a0967ddd95..946d12f5c068a233a60623e033b407dda37fd82f 100644 (file)
@@ -24,6 +24,12 @@ 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 the rest of sema to find private method decl implementations.
+  if (MDecl->isInstance())
+    AddInstanceMethodToGlobalPool(MDecl);
+  else
+    AddFactoryMethodToGlobalPool(MDecl);
   
   // Allow all of Sema to see that we are entering a method definition.
   CurMethodDecl = MDecl;
@@ -666,13 +672,15 @@ void Sema::AddFactoryMethodToGlobalPool(ObjcMethodDecl *Method) {
   }
 }
 
+// Note: For class/category implemenations, allMethods/allProperties is
+// always null.
 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()
+  // FIXME: If we don't have a ClassDecl, we have an error. We should consider
+  // always passing in a decl. If the decl has an error, isInvalidDecl()
   // should be true.
   if (!ClassDecl)
     return;
@@ -731,8 +739,8 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
       } else {
         clsMethods.push_back(Method);
         ClsMap[Method->getSelector()] = Method;
-        /// The following allows us to typecheck messages to "id".
-        AddInstanceMethodToGlobalPool(Method);
+        /// The following allows us to typecheck messages to "Class".
+        AddFactoryMethodToGlobalPool(Method);
       }
     }
   }
index 45d04705447b98a8f10a861cfa1e66e641c8646c..e5f748fa66796092ba91fbce605a7be6c7292bab 100644 (file)
@@ -2264,23 +2264,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
   if (receiverType == Context.getObjcIdType() ||
       receiverType == Context.getObjcClassType()) {
     Method = InstanceMethodPool[Sel].Method;
-    // If we didn't find an public method, look for a private one.
-    if (!Method && CurMethodDecl) {
-      NamedDecl *impCxt = CurMethodDecl->getMethodContext();
-      if (ObjcImplementationDecl *IMD = 
-          dyn_cast<ObjcImplementationDecl>(impCxt)) {
-        if (receiverType == Context.getObjcIdType())
-          Method = IMD->lookupInstanceMethod(Sel);
-        else
-          Method = IMD->lookupClassMethod(Sel);
-      } else if (ObjcCategoryImplDecl *CID = 
-                 dyn_cast<ObjcCategoryImplDecl>(impCxt)) {
-        if (receiverType == Context.getObjcIdType())
-          Method = CID->lookupInstanceMethod(Sel);
-        else
-          Method = CID->lookupClassMethod(Sel);
-      }
-    }
+       if (!Method)
+         Method = FactoryMethodPool[Sel].Method;
     if (!Method) {
       Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
            SourceRange(lbrac, rbrac));
index dc50a19c81b4c731943d20ba037bb51928ea077c..9c9289b6b8584ad9acd311150e45966b40ea1a5a 100644 (file)
@@ -36,3 +36,28 @@ static void func(Helicopter *obj) {
   // behavior isn't very desirable, however wee need it for GCC compatibility.
   NSRect r = [obj rect];
 }
+
+@interface NSObject @end
+
+extern Class NSClassFromObject(id object);
+
+@interface XX : NSObject 
+@end
+
+@implementation XX
+
++ _privateMethod {
+  return self;
+}
+
+- (void) xx {
+  [NSClassFromObject(self) _privateMethod];
+}
+@end
+
+@implementation XX (Private)
+- (void) yy {
+  [NSClassFromObject(self) _privateMethod];
+}
+@end
+