summaryrefslogtreecommitdiffstats
path: root/clang/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
commit7988d7dc3e638c7419f84f0892fe16ae03c7b07b (patch)
tree08b22a551b7a32e8dbe43ac00d46bbe6f5baa6b6 /clang/lib/Sema/SemaDeclObjC.cpp
parent5101c24f60997b3775624f5c9488ded8e9f3cdf2 (diff)
downloadbcm5719-llvm-7988d7dc3e638c7419f84f0892fe16ae03c7b07b.tar.gz
bcm5719-llvm-7988d7dc3e638c7419f84f0892fe16ae03c7b07b.zip
(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. llvm-svn: 60598
Diffstat (limited to 'clang/lib/Sema/SemaDeclObjC.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp73
1 files changed, 50 insertions, 23 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 01a453d3be6..a58d1da6322 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/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(),
OpenPOWER on IntegriCloud