aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclObjC.cpp
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-10-21 10:37:50 +0000
committerSteve Naroff <snaroff@apple.com>2008-10-21 10:37:50 +0000
commitfe6b0dc94a5279f33aba9a3bc0237c9841be3d43 (patch)
tree091174f8436358b15d2b6cb4edc6fc7f5975d66c /lib/Sema/SemaDeclObjC.cpp
parent933c3e1dca3bb88bf113290ef0ade8f5262a89c0 (diff)
Fix <rdar://problem/6261178> clang-on-xcode: [sema] multiple method warning is over enthusiastic.
Fix <rdar://problem/6265257> warnings for ambiguous message send swamp other warnings. Reworked Sema::MatchTwoMethodDeclarations() to optionally match based on method size and alignment (the default in GCC). Changed Sema::LookupInstanceMethodInGlobalPool() to use this feature. Added -Wno-struct-selector-match to driver, however didn't hook it up yet. Added a FIXME that says this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57898 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r--lib/Sema/SemaDeclObjC.cpp46
1 files changed, 37 insertions, 9 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 6375d91448..d5fa8848c3 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -739,17 +739,37 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
/// returns true, or false, accordingly.
/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
- const ObjCMethodDecl *PrevMethod) {
- if (Context.getCanonicalType(Method->getResultType()) !=
- Context.getCanonicalType(PrevMethod->getResultType()))
- return false;
- for (unsigned i = 0, e = Method->getNumParams(); i != e; ++i) {
- ParmVarDecl *ParamDecl = Method->getParamDecl(i);
- ParmVarDecl *PrevParamDecl = PrevMethod->getParamDecl(i);
- if (Context.getCanonicalType(ParamDecl->getType()) !=
- Context.getCanonicalType(PrevParamDecl->getType()))
+ const ObjCMethodDecl *PrevMethod,
+ bool matchBasedOnSizeAndAlignment) {
+ QualType T1 = Context.getCanonicalType(Method->getResultType());
+ QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
+
+ if (T1 != T2) {
+ // The result types are different.
+ if (!matchBasedOnSizeAndAlignment)
+ return false;
+ // Incomplete types don't have a size and alignment.
+ if (T1->isIncompleteType() || T2->isIncompleteType())
+ return false;
+ // Check is based on size and alignment.
+ if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
return false;
}
+ for (unsigned i = 0, e = Method->getNumParams(); i != e; ++i) {
+ T1 = Context.getCanonicalType(Method->getParamDecl(i)->getType());
+ T2 = Context.getCanonicalType(PrevMethod->getParamDecl(i)->getType());
+ if (T1 != T2) {
+ // The result types are different.
+ if (!matchBasedOnSizeAndAlignment)
+ return false;
+ // Incomplete types don't have a size and alignment.
+ if (T1->isIncompleteType() || T2->isIncompleteType())
+ return false;
+ // Check is based on size and alignment.
+ if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
+ return false;
+ }
+ }
return true;
}
@@ -776,11 +796,19 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
}
}
+// FIXME: Finish implementing -Wno-struct-selector-match.
ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
SourceRange R) {
ObjCMethodList &MethList = InstanceMethodPool[Sel];
+ bool issueWarning = false;
if (MethList.Method && MethList.Next) {
+ for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
+ // This checks if the methods differ by size & alignment.
+ if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
+ issueWarning = true;
+ }
+ if (issueWarning && (MethList.Method && MethList.Next)) {
Diag(R.getBegin(), diag::warn_multiple_method_decl, Sel.getName(), R);
Diag(MethList.Method->getLocStart(), diag::warn_using_decl,
MethList.Method->getSourceRange());