[cfe-commits] r65292 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/AST/Decl.cpp lib/AST/DeclObjC.cpp lib/Sema/SemaExprObjC.cpp test/SemaObjC/property-11.m test/SemaObjC/protocol-id-test-1.m test/SemaObjC/protocol-id-test-2.m
Steve Naroff
snaroff at apple.com
Sun Feb 22 11:35:57 PST 2009
Author: snaroff
Date: Sun Feb 22 13:35:57 2009
New Revision: 65292
URL: http://llvm.org/viewvc/llvm-project?rev=65292&view=rev
Log:
Contains the following (related to problems found while investigting <rdar://problem/6497631> Message lookup is sometimes different than gcc's).
- Implement instance/class overloading in ObjCContainerDecl (removing a FIXME). This involved hacking NamedDecl::declarationReplaces(), which took awhile to figure out (didn't realize replace was the default).
- Changed Sema::ActOnInstanceMessage() to remove redundant warnings when dealing with protocols. For now, I've omitted the "protocol" term in the diagnostic. It simplifies the code flow and wan't always 100% accurate (e.g. "Foo<Prot>" looks in the class interface, not just the protocol).
- Changed several test cases to jive with the above changes.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/SemaObjC/property-11.m
cfe/trunk/test/SemaObjC/protocol-id-test-1.m
cfe/trunk/test/SemaObjC/protocol-id-test-2.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=65292&r1=65291&r2=65292&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Sun Feb 22 13:35:57 2009
@@ -916,8 +916,6 @@
"no super class declared in @interface for %0")
DIAG(err_invalid_receiver_to_message, ERROR,
"invalid receiver to message expression")
-DIAG(warn_method_not_found_in_protocol, WARNING,
- "method %objcinstance0 not found in protocol (return type defaults to 'id')")
DIAG(error_bad_receiver_type, ERROR,
"bad receiver type %0")
DIAG(error_objc_throw_expects_object, ERROR,
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=65292&r1=65291&r2=65292&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sun Feb 22 13:35:57 2009
@@ -13,6 +13,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Expr.h"
@@ -194,6 +195,10 @@
// For function declarations, we keep track of redeclarations.
return FD->getPreviousDeclaration() == OldD;
+ // For method declarations, we keep track of redeclarations.
+ if (isa<ObjCMethodDecl>(this))
+ return false;
+
// For non-function declarations, if the declarations are of the
// same kind then this must be a redeclaration, or semantic analysis
// would not have given us the new declaration.
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=65292&r1=65291&r2=65292&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Sun Feb 22 13:35:57 2009
@@ -14,6 +14,7 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Stmt.h"
+#include "llvm/ADT/STLExtras.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -42,21 +43,42 @@
//===----------------------------------------------------------------------===//
// Get the local instance method declared in this interface.
-// FIXME: handle overloading, instance & class methods can have the same name.
ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
- lookup_const_result MethodResult = lookup(Sel);
- if (MethodResult.first)
- return const_cast<ObjCMethodDecl*>(
- dyn_cast<ObjCMethodDecl>(*MethodResult.first));
+ // Since instance & class methods can have the same name, the loop below
+ // ensures we get the correct method.
+ //
+ // @interface Whatever
+ // - (int) class_method;
+ // + (float) class_method;
+ // @end
+ //
+ lookup_const_iterator Meth, MethEnd;
+ for (llvm::tie(Meth, MethEnd) = lookup(Sel);
+ Meth != MethEnd; ++Meth) {
+ ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+ if (MD && MD->isInstanceMethod())
+ return MD;
+ }
return 0;
}
// Get the local class method declared in this interface.
ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
- lookup_const_result MethodResult = lookup(Sel);
- if (MethodResult.first)
- return const_cast<ObjCMethodDecl*>(
- dyn_cast<ObjCMethodDecl>(*MethodResult.first));
+ // Since instance & class methods can have the same name, the loop below
+ // ensures we get the correct method.
+ //
+ // @interface Whatever
+ // - (int) class_method;
+ // + (float) class_method;
+ // @end
+ //
+ lookup_const_iterator Meth, MethEnd;
+ for (llvm::tie(Meth, MethEnd) = lookup(Sel);
+ Meth != MethEnd; ++Meth) {
+ ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+ if (MD && MD->isClassMethod())
+ return MD;
+ }
return 0;
}
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=65292&r1=65291&r2=65292&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Sun Feb 22 13:35:57 2009
@@ -397,9 +397,6 @@
if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
break;
}
- if (!Method)
- Diag(lbrac, diag::warn_method_not_found_in_protocol)
- << Sel << RExpr->getSourceRange();
// Check for GCC extension "Class<foo>".
} else if (ObjCQualifiedClassType *QIT =
dyn_cast<ObjCQualifiedClassType>(ReceiverCType)) {
@@ -409,9 +406,6 @@
if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
break;
}
- if (!Method)
- Diag(lbrac, diag::warn_method_not_found_in_protocol)
- << Sel << RExpr->getSourceRange();
} else if (const ObjCInterfaceType *OCIReceiver =
ReceiverCType->getAsPointerToObjCInterfaceType()) {
// We allow sending a message to a pointer to an interface (an object).
@@ -422,19 +416,29 @@
// The idea is to add class info to InstanceMethodPool.
Method = ClassDecl->lookupInstanceMethod(Sel);
+ bool haveQualifiers = false;
if (!Method) {
// Search protocol qualifiers.
for (ObjCQualifiedIdType::qual_iterator QI = OCIReceiver->qual_begin(),
E = OCIReceiver->qual_end(); QI != E; ++QI) {
+ haveQualifiers = true;
if ((Method = (*QI)->lookupInstanceMethod(Sel)))
break;
}
}
-
- if (!Method && !OCIReceiver->qual_empty())
- Diag(lbrac, diag::warn_method_not_found_in_protocol)
- << Sel << SourceRange(lbrac, rbrac);
-
+ if (!Method) {
+ // If we have an implementation in scope, check "private" methods.
+ if (ClassDecl)
+ if (ObjCImplementationDecl *ImpDecl =
+ ObjCImplementations[ClassDecl->getIdentifier()])
+ Method = ImpDecl->getInstanceMethod(Sel);
+ // If we still haven't found a method, look in the global pool. This
+ // behavior isn't very desirable, however we need it for GCC
+ // compatibility. FIXME: should we deviate??
+ if (!Method && !haveQualifiers)
+ Method = LookupInstanceMethodInGlobalPool(
+ Sel, SourceRange(lbrac,rbrac));
+ }
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
return true;
} else {
@@ -443,19 +447,6 @@
return true;
}
- if (!Method) {
- // If we have an implementation in scope, check "private" methods.
- if (ClassDecl)
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
- Method = ImpDecl->getInstanceMethod(Sel);
- // If we still haven't found a method, look in the global pool. This
- // behavior isn't very desirable, however we need it for GCC
- // compatibility.
- if (!Method)
- Method = LookupInstanceMethodInGlobalPool(
- Sel, SourceRange(lbrac,rbrac));
- }
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
lbrac, rbrac, returnType))
return true;
Modified: cfe/trunk/test/SemaObjC/property-11.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-11.m?rev=65292&r1=65291&r2=65292&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-11.m (original)
+++ cfe/trunk/test/SemaObjC/property-11.m Sun Feb 22 13:35:57 2009
@@ -22,7 +22,10 @@
NSSound *x;
id o;
- o = [x foo];
+ // GCC does *not* warn about the following. Since foo/setFoo: are not in the
+ // class or category interface for NSSound, the compiler shouldn't find them.
+ // For now, we will support GCC's behavior (sigh).
+ o = [x foo];
o = x.foo;
[x setFoo:o];
x.foo = o;
Modified: cfe/trunk/test/SemaObjC/protocol-id-test-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-id-test-1.m?rev=65292&r1=65291&r2=65292&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-id-test-1.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-id-test-1.m Sun Feb 22 13:35:57 2009
@@ -12,5 +12,5 @@
@end
@implementation INTF
-- (void)IMeth {INTF<P> *pi; [pi Meth]; } // expected-warning {{method '-Meth' not found in protocol (return type defaults to 'id')}}
+- (void)IMeth {INTF<P> *pi; [pi Meth]; } // expected-warning {{method '-Meth' not found (return type defaults to 'id')}}
@end
Modified: cfe/trunk/test/SemaObjC/protocol-id-test-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-id-test-2.m?rev=65292&r1=65291&r2=65292&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-id-test-2.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-id-test-2.m Sun Feb 22 13:35:57 2009
@@ -5,10 +5,8 @@
@interface INTF<P>
- (void)IMeth;
- - (void) Meth;
@end
@implementation INTF
-- (void)IMeth { [(id<P>)self Meth]; } // expected-warning {{method '-Meth' not found in protocol (return type defaults to 'id')}}
-- (void) Meth {}
+- (void)IMeth { [(id<P>)self Meth]; } // expected-warning {{method '-Meth' not found (return type defaults to 'id')}}
@end
More information about the cfe-commits
mailing list