aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclObjC.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2008-12-05 18:18:52 +0000
committerFariborz Jahanian <fjahanian@apple.com>2008-12-05 18:18:52 +0000
commit8daab970b80ed2e751fc88327180acbeff1dbb9c (patch)
treec0528779be503b4b2913a5984cf9ecf8ea23fac9 /lib/Sema/SemaDeclObjC.cpp
parent72c3f314d92d65c050ee1c07b7753623c044d6c7 (diff)
(instance/class) Method type checking between class and its implementation.
(instance/class) Method type checking between category and its implementation. And a test case for all. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60598 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r--lib/Sema/SemaDeclObjC.cpp73
1 files changed, 50 insertions, 23 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 01a453d3be..a58d1da632 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -590,6 +590,32 @@ void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
Diag(ImpLoc, diag::warn_undef_method_impl) << method->getDeclName();
}
+void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
+ ObjCMethodDecl *IntfMethodDecl) {
+ bool err = false;
+ QualType ImpMethodQType =
+ Context.getCanonicalType(ImpMethodDecl->getResultType());
+ QualType IntfMethodQType =
+ Context.getCanonicalType(IntfMethodDecl->getResultType());
+ if (!Context.typesAreCompatible(IntfMethodQType, ImpMethodQType))
+ err = true;
+ else for (ObjCMethodDecl::param_iterator IM=ImpMethodDecl->param_begin(),
+ IF=IntfMethodDecl->param_begin(),
+ EM=ImpMethodDecl->param_end(); IM!=EM; ++IM, IF++) {
+ ImpMethodQType = Context.getCanonicalType((*IM)->getType());
+ IntfMethodQType = Context.getCanonicalType((*IF)->getType());
+ if (!Context.typesAreCompatible(IntfMethodQType, ImpMethodQType)) {
+ err = true;
+ break;
+ }
+ }
+ if (err) {
+ Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_types)
+ << ImpMethodDecl->getDeclName();
+ Diag(IntfMethodDecl->getLocation(), diag::note_previous_definition);
+ }
+}
+
/// FIXME: Type hierarchies in Objective-C can be deep. We could most
/// likely improve the efficiency of selector lookups and type
/// checking by associating with each protocol / interface / category
@@ -651,32 +677,12 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector()))
WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
else if (!(*I)->isSynthesized()){
- bool err = false;
ObjCMethodDecl *ImpMethodDecl =
IMPDecl->getInstanceMethod((*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
IDecl->getInstanceMethod((*I)->getSelector());
- QualType ImpMethodQType =
- Context.getCanonicalType(ImpMethodDecl->getResultType());
- QualType IntfMethodQType =
- Context.getCanonicalType(IntfMethodDecl->getResultType());
- if (!Context.typesAreCompatible(IntfMethodQType, ImpMethodQType))
- err = true;
- else for (ObjCMethodDecl::param_iterator IM=ImpMethodDecl->param_begin(),
- IF=IntfMethodDecl->param_begin(),
- EM=ImpMethodDecl->param_end(); IM!=EM; ++IM, IF++) {
- ImpMethodQType = Context.getCanonicalType((*IM)->getType());
- IntfMethodQType = Context.getCanonicalType((*IF)->getType());
- if (!Context.typesAreCompatible(IntfMethodQType, ImpMethodQType)) {
- err = true;
- break;
- }
- }
- if (err) {
- Diag(ImpMethodDecl->getLocation(), diag::err_conflicting_types)
- << ImpMethodDecl->getDeclName();
- Diag(IntfMethodDecl->getLocation(), diag::note_previous_definition);
- }
+ WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+
}
llvm::DenseSet<Selector> ClsMap;
@@ -690,6 +696,14 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
E = IDecl->classmeth_end(); I != E; ++I)
if (!ClsMap.count((*I)->getSelector()))
WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
+ else {
+ ObjCMethodDecl *ImpMethodDecl =
+ IMPDecl->getClassMethod((*I)->getSelector());
+ ObjCMethodDecl *IntfMethodDecl =
+ IDecl->getClassMethod((*I)->getSelector());
+ WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+ }
+
// Check the protocol list for unimplemented methods in the @implementation
// class.
@@ -717,6 +731,13 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
E = CatClassDecl->instmeth_end(); I != E; ++I)
if (!InsMap.count((*I)->getSelector()))
WarnUndefinedMethod(CatImplDecl->getLocation(), *I, IncompleteImpl);
+ else {
+ ObjCMethodDecl *ImpMethodDecl =
+ CatImplDecl->getInstanceMethod((*I)->getSelector());
+ ObjCMethodDecl *IntfMethodDecl =
+ CatClassDecl->getInstanceMethod((*I)->getSelector());
+ WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+ }
llvm::DenseSet<Selector> ClsMap;
// Check and see if class methods in category interface have been
@@ -730,7 +751,13 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
E = CatClassDecl->classmeth_end(); I != E; ++I)
if (!ClsMap.count((*I)->getSelector()))
WarnUndefinedMethod(CatImplDecl->getLocation(), *I, IncompleteImpl);
-
+ else {
+ ObjCMethodDecl *ImpMethodDecl =
+ CatImplDecl->getClassMethod((*I)->getSelector());
+ ObjCMethodDecl *IntfMethodDecl =
+ CatClassDecl->getClassMethod((*I)->getSelector());
+ WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+ }
// Check the protocol list for unimplemented methods in the @implementation
// class.
for (ObjCCategoryDecl::protocol_iterator PI = CatClassDecl->protocol_begin(),