[cfe-commits] r70568 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp test/Analysis/PR2978.m test/SemaObjC/method-typecheck-2.m test/SemaObjC/props-on-prots.m test/SemaObjC/protocol-lookup.m test/SemaObjCXX/protocol-lookup.mm
Fariborz Jahanian
fjahanian at apple.com
Fri May 1 13:07:13 PDT 2009
Author: fjahanian
Date: Fri May 1 15:07:12 2009
New Revision: 70568
URL: http://llvm.org/viewvc/llvm-project?rev=70568&view=rev
Log:
Check for method type conflict between declaration in
class/protocol and implementation which could be
an imm. implementation or down in the inheritance
hierarchy.
Added:
cfe/trunk/test/SemaObjC/method-typecheck-2.m
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/test/Analysis/PR2978.m
cfe/trunk/test/SemaObjC/props-on-prots.m
cfe/trunk/test/SemaObjC/protocol-lookup.m
cfe/trunk/test/SemaObjCXX/protocol-lookup.mm
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=70568&r1=70567&r2=70568&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri May 1 15:07:12 2009
@@ -1114,6 +1114,17 @@
const ObjCMethodDecl *PrevMethod,
bool matchBasedOnSizeAndAlignment = false);
+ /// MatchAllMethodDeclarations - Check methods declaraed in interface or
+ /// or protocol against those declared in their implementations.
+ void MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
+ const llvm::DenseSet<Selector> &ClsMap,
+ llvm::DenseSet<Selector> &InsMapSeen,
+ llvm::DenseSet<Selector> &ClsMapSeen,
+ ObjCImplDecl* IMPDecl,
+ ObjCContainerDecl* IDecl,
+ bool &IncompleteImpl,
+ bool ImmediateClass);
+
/// AddInstanceMethodToGlobalPool - All instance methods in a translation
/// unit are added to a global pool. This allows us to efficiently associate
/// a selector with a method declaraation for purposes of typechecking
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=70568&r1=70567&r2=70568&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri May 1 15:07:12 2009
@@ -885,6 +885,79 @@
CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
}
+/// MatchAllMethodDeclarations - Check methods declaraed in interface or
+/// or protocol against those declared in their implementations.
+///
+void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
+ const llvm::DenseSet<Selector> &ClsMap,
+ llvm::DenseSet<Selector> &InsMapSeen,
+ llvm::DenseSet<Selector> &ClsMapSeen,
+ ObjCImplDecl* IMPDecl,
+ ObjCContainerDecl* CDecl,
+ bool &IncompleteImpl,
+ bool ImmediateClass)
+{
+ // Check and see if instance methods in class interface have been
+ // implemented in the implementation class. If so, their types match.
+ for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context),
+ E = CDecl->instmeth_end(Context); I != E; ++I) {
+ if (InsMapSeen.count((*I)->getSelector()))
+ continue;
+ InsMapSeen.insert((*I)->getSelector());
+ if (!(*I)->isSynthesized() &&
+ !InsMap.count((*I)->getSelector())) {
+ if (ImmediateClass)
+ WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
+ continue;
+ }
+ else {
+ ObjCMethodDecl *ImpMethodDecl =
+ IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
+ ObjCMethodDecl *IntfMethodDecl =
+ CDecl->getInstanceMethod(Context, (*I)->getSelector());
+ assert(IntfMethodDecl &&
+ "IntfMethodDecl is null in ImplMethodsVsClassMethods");
+ // ImpMethodDecl may be null as in a @dynamic property.
+ if (ImpMethodDecl)
+ WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+ }
+ }
+
+ // Check and see if class methods in class interface have been
+ // implemented in the implementation class. If so, their types match.
+ for (ObjCInterfaceDecl::classmeth_iterator
+ I = CDecl->classmeth_begin(Context),
+ E = CDecl->classmeth_end(Context);
+ I != E; ++I) {
+ if (ClsMapSeen.count((*I)->getSelector()))
+ continue;
+ ClsMapSeen.insert((*I)->getSelector());
+ if (!ClsMap.count((*I)->getSelector())) {
+ if (ImmediateClass)
+ WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
+ }
+ else {
+ ObjCMethodDecl *ImpMethodDecl =
+ IMPDecl->getClassMethod(Context, (*I)->getSelector());
+ ObjCMethodDecl *IntfMethodDecl =
+ CDecl->getClassMethod(Context, (*I)->getSelector());
+ WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+ }
+ }
+ if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
+ // Check for any implementation of a methods declared in protocol.
+ for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
+ E = I->protocol_end(); PI != E; ++PI)
+ MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
+ IMPDecl,
+ (*PI), IncompleteImpl, false);
+ if (I->getSuperClass())
+ MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
+ IMPDecl,
+ I->getSuperClass(), IncompleteImpl, false);
+ }
+}
+
void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
ObjCContainerDecl* CDecl,
bool IncompleteImpl) {
@@ -933,51 +1006,26 @@
}
}
- for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context),
- E = CDecl->instmeth_end(Context); I != E; ++I) {
- if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector())) {
- WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
- continue;
- }
-
- ObjCMethodDecl *ImpMethodDecl =
- IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
- ObjCMethodDecl *IntfMethodDecl =
- CDecl->getInstanceMethod(Context, (*I)->getSelector());
- assert(IntfMethodDecl &&
- "IntfMethodDecl is null in ImplMethodsVsClassMethods");
- // ImpMethodDecl may be null as in a @dynamic property.
- if (ImpMethodDecl)
- WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
- }
-
llvm::DenseSet<Selector> ClsMap;
- // Check and see if class methods in class interface have been
- // implemented in the implementation class.
for (ObjCImplementationDecl::classmeth_iterator
- I = IMPDecl->classmeth_begin(Context),
- E = IMPDecl->classmeth_end(Context); I != E; ++I)
+ I = IMPDecl->classmeth_begin(Context),
+ E = IMPDecl->classmeth_end(Context); I != E; ++I)
ClsMap.insert((*I)->getSelector());
- for (ObjCInterfaceDecl::classmeth_iterator
- I = CDecl->classmeth_begin(Context),
- E = CDecl->classmeth_end(Context);
- I != E; ++I)
- if (!ClsMap.count((*I)->getSelector()))
- WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
- else {
- ObjCMethodDecl *ImpMethodDecl =
- IMPDecl->getClassMethod(Context, (*I)->getSelector());
- ObjCMethodDecl *IntfMethodDecl =
- CDecl->getClassMethod(Context, (*I)->getSelector());
- WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
- }
-
+ // Check for type conflict of methods declared in a class/protocol and
+ // its implementation; if any.
+ llvm::DenseSet<Selector> InsMapSeen, ClsMapSeen;
+ MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
+ IMPDecl, CDecl,
+ IncompleteImpl, true);
// Check the protocol list for unimplemented methods in the @implementation
// class.
+ // Check and see if class methods in class interface have been
+ // implemented in the implementation class.
+
if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
- for (ObjCCategoryDecl::protocol_iterator PI = I->protocol_begin(),
+ for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
E = I->protocol_end(); PI != E; ++PI)
CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
InsMap, ClsMap, I);
Modified: cfe/trunk/test/Analysis/PR2978.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/PR2978.m?rev=70568&r1=70567&r2=70568&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/PR2978.m (original)
+++ cfe/trunk/test/Analysis/PR2978.m Fri May 1 15:07:12 2009
@@ -44,7 +44,7 @@
-(id) O{ return 0; }
-(void) setO:(id)arg { }
-- (void)dealloc
+- (id)dealloc
{
[_X release];
[_Z release];
Added: cfe/trunk/test/SemaObjC/method-typecheck-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/method-typecheck-2.m?rev=70568&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/method-typecheck-2.m (added)
+++ cfe/trunk/test/SemaObjC/method-typecheck-2.m Fri May 1 15:07:12 2009
@@ -0,0 +1,25 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+ at protocol P
+- (void) doSomethingInProtocol: (float) x; // expected-note {{previous definition is here}}
++ (void) doSomethingClassyInProtocol: (float) x; // expected-note {{previous definition is here}}
+- (void) doNothingInProtocol : (float) x;
++ (void) doNothingClassyInProtocol : (float) x;
+ at end
+
+ at interface I <P>
+- (void) doSomething: (float) x; // expected-note {{previous definition is here}}
++ (void) doSomethingClassy: (int) x; // expected-note {{previous definition is here}}
+ at end
+
+ at interface Bar : I
+ at end
+
+ at implementation Bar
+- (void) doSomething: (int) x {} // expected-warning {{conflicting parameter types}}
++ (void) doSomethingClassy: (float) x{} // expected-warning {{conflicting parameter types}}
+- (void) doSomethingInProtocol: (id) x {} // expected-warning {{conflicting parameter types}}
++ (void) doSomethingClassyInProtocol: (id) x {} // expected-warning {{conflicting parameter types}}
+ at end
+
+
Modified: cfe/trunk/test/SemaObjC/props-on-prots.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/props-on-prots.m?rev=70568&r1=70567&r2=70568&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/props-on-prots.m (original)
+++ cfe/trunk/test/SemaObjC/props-on-prots.m Fri May 1 15:07:12 2009
@@ -21,7 +21,7 @@
typedef struct _XCElementInset {} XCElementInset;
@protocol XCElementP < NSObject >
--(BOOL) vertical;
+-(id) vertical;
@end
@protocol XCElementDisplayDelegateP;
@@ -60,6 +60,6 @@
if (_marker && _marker.variableSized) {
}
}
-- vertical { return self; }
+- (id)vertical { return self; }
- (BOOL)isEqual:x { return 1; }
@end
Modified: cfe/trunk/test/SemaObjC/protocol-lookup.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-lookup.m?rev=70568&r1=70567&r2=70568&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-lookup.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-lookup.m Fri May 1 15:07:12 2009
@@ -39,7 +39,7 @@
return self;
}
-- (void)dealloc
+- dealloc
{
[_foo release];
[_bar release];
Modified: cfe/trunk/test/SemaObjCXX/protocol-lookup.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/protocol-lookup.mm?rev=70568&r1=70567&r2=70568&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/protocol-lookup.mm (original)
+++ cfe/trunk/test/SemaObjCXX/protocol-lookup.mm Fri May 1 15:07:12 2009
@@ -39,7 +39,7 @@
return self;
}
-- (void)dealloc
+- dealloc
{
[_foo release];
[_bar release];
More information about the cfe-commits
mailing list