]> granicus.if.org Git - clang/commitdiff
Teach Sema::ActOnInstanceMessage() about private methods. That is, methods declared...
authorSteve Naroff <snaroff@apple.com>
Sun, 11 Nov 2007 00:10:47 +0000 (00:10 +0000)
committerSteve Naroff <snaroff@apple.com>
Sun, 11 Nov 2007 00:10:47 +0000 (00:10 +0000)
This commit is only 95% of the bug fix. The last piece to this puzzle is to add the method decls to the implementation incrementally (as we encounter them). At the moment, the methods aren't added until we see an @end (which is too late).

I will complete this later...

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

AST/Decl.cpp
Sema/Sema.h
Sema/SemaDecl.cpp
Sema/SemaExpr.cpp
include/clang/AST/DeclObjC.h
test/Sema/message.m [new file with mode: 0644]

index 3cfe4aeed9a73e1e968b45922cb90506e3f0a314..2e79de3f6367c8b8c59e331da84dc4d7fa1c5555 100644 (file)
@@ -510,4 +510,31 @@ ObjcMethodDecl *ObjcInterfaceDecl::lookupClassMethod(Selector &Sel) {
   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 *ObjcImplementationDecl::lookupInstanceMethod(Selector &Sel) {
+  ObjcMethodDecl **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 *ObjcImplementationDecl::lookupClassMethod(Selector &Sel) {
+  ObjcMethodDecl **methods = getClassMethods();
+  int methodCount = getNumClassMethods();
+  for (int i = 0; i < methodCount; ++i) {
+    if (methods[i]->getSelector() == Sel) {
+      return methods[i];
+    }
+  }
+  return NULL;
+}
 
index 2d6c42593bde2067931a1c2c0320cf1b7d6cd379..de464c111a9494d3369d7c837e43a9aef7018ec3 100644 (file)
@@ -85,7 +85,7 @@ class Sema : public Action {
 
   /// ObjcImplementations - Keep track of all of the classes with
   /// @implementation's, so that we can emit errors on duplicates.
-  llvm::SmallPtrSet<IdentifierInfo*, 8> ObjcImplementations;
+  llvm::DenseMap<IdentifierInfo*, ObjcImplementationDecl*> ObjcImplementations;
   
   /// ObjcProtocols - Keep track of all protocol declarations declared
   /// with @protocol keyword, so that we can emit errors on duplicates and
index 006bb18bd16a8625c2b7de6c3cf7f170eaa50e25..e9c438ffc5e21e21a9e38a3dfbe75d629c8241c7 100644 (file)
@@ -1477,9 +1477,10 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
   new ObjcImplementationDecl(AtClassImplLoc, ClassName, IDecl, SDecl);
   
   // Check that there is no duplicate implementation of this class.
-  if (!ObjcImplementations.insert(ClassName))
+  if (ObjcImplementations[ClassName])
     Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName());
-
+  else // add it to the list.
+    ObjcImplementations[ClassName] = IMPDecl;
   return IMPDecl;
 }
 
index 47cbbcabf30977a068ce6a2c7fd55e67b4ce22ea..bd210c3adf7f9f79fd3ca9609ade189ac38eeb37 100644 (file)
@@ -2125,6 +2125,12 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
     // than the following method (which can do *many* linear searches). The
     // idea is to add class info to InstanceMethodPool...
     Method = ClassDecl->lookupInstanceMethod(Sel);
+    if (!Method) {
+      // If we have an implementation in scope, check "private" methods.
+      if (ObjcImplementationDecl *ImpDecl = 
+            ObjcImplementations[ClassDecl->getIdentifier()])
+        Method = ImpDecl->lookupInstanceMethod(Sel);
+    }
     if (!Method) {
       Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
            SourceRange(lbrac, rbrac));
index 550b64791acf5ef66b8e9767a4ee3bc488ffd1bd..3fb09036e16dcb8e847557b0948638612dd7f584 100644 (file)
@@ -667,6 +667,9 @@ public:
   
   ObjcMethodDecl **getClassMethods() const { return ClassMethods; }
   int getNumClassMethods() const { return NumClassMethods; }
+
+  ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
+  ObjcMethodDecl *lookupClassMethod(Selector &Sel);
   
   ObjcIvarDecl **getImplDeclIVars() const { return Ivars; }
   int getImplDeclNumIvars() const { return NumIvars; }
diff --git a/test/Sema/message.m b/test/Sema/message.m
new file mode 100644 (file)
index 0000000..517a5f6
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: clang -fsyntax-only -verify %s
+
+@interface foo
+- (void)meth;
+@end
+
+@implementation foo
+- (void) contents {}                   // No declaration in @interface!
+- (void) meth { [self contents]; } // expected-warning {{method '-contents' not found (return type defaults to 'id')}}
+@end
+