aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclObjC.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-07-22 18:24:20 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-07-22 18:24:20 +0000
commit3fe104154dd2e8ffb351142d74f308938b5c99bf (patch)
tree01de90ffd2831c44c2e733ead8d1d226017935d1 /lib/Sema/SemaDeclObjC.cpp
parent44db3251aec7c0e6edaf1c70d7d53a272686791a (diff)
atch for implementation of objective-c's -Wselector
warning flag in clang. Little more to do for a PCH issue. Radar 6507158. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109129 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r--lib/Sema/SemaDeclObjC.cpp85
1 files changed, 55 insertions, 30 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 21aeb59a08..5f2f37eb0b 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -32,10 +32,10 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
// Allow the rest of sema to find private method decl implementations.
if (MDecl->isInstanceMethod())
- AddInstanceMethodToGlobalPool(MDecl);
+ AddInstanceMethodToGlobalPool(MDecl, true);
else
- AddFactoryMethodToGlobalPool(MDecl);
-
+ AddFactoryMethodToGlobalPool(MDecl, true);
+
// Allow all of Sema to see that we are entering a method definition.
PushDeclContext(FnBodyScope, MDecl);
PushFunctionScope();
@@ -1130,7 +1130,7 @@ Sema::MethodPool::iterator Sema::ReadMethodPool(Selector Sel,
return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first;
}
-void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
+void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl) {
llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
= InstanceMethodPool.find(Method->getSelector());
if (Pos == InstanceMethodPool.end()) {
@@ -1140,7 +1140,7 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(),
ObjCMethodList())).first;
}
-
+ Method->setDefined(impl);
ObjCMethodList &Entry = Pos->second;
if (Entry.Method == 0) {
// Haven't seen a method with this selector name yet - add it.
@@ -1152,8 +1152,10 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
// We've seen a method with this name, see if we have already seen this type
// signature.
for (ObjCMethodList *List = &Entry; List; List = List->Next)
- if (MatchTwoMethodDeclarations(Method, List->Method))
+ if (MatchTwoMethodDeclarations(Method, List->Method)) {
+ List->Method->setDefined(impl);
return;
+ }
// We have a new signature for an existing method - add it.
// This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
@@ -1194,7 +1196,7 @@ ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
return MethList.Method;
}
-void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
+void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl) {
llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
= FactoryMethodPool.find(Method->getSelector());
if (Pos == FactoryMethodPool.end()) {
@@ -1204,32 +1206,31 @@ void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(),
ObjCMethodList())).first;
}
-
- ObjCMethodList &FirstMethod = Pos->second;
- if (!FirstMethod.Method) {
+ Method->setDefined(impl);
+ ObjCMethodList &Entry = Pos->second;
+ if (!Entry.Method) {
// Haven't seen a method with this selector name yet - add it.
- FirstMethod.Method = Method;
- FirstMethod.Next = 0;
- } else {
- // We've seen a method with this name, now check the type signature(s).
- bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
-
- for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
- Next = Next->Next)
- match = MatchTwoMethodDeclarations(Method, Next->Method);
-
- if (!match) {
- // We have a new signature for an existing method - add it.
- // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
- ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
- ObjCMethodList *OMI = new (Mem) ObjCMethodList(Method, FirstMethod.Next);
- FirstMethod.Next = OMI;
+ Entry.Method = Method;
+ Entry.Next = 0;
+ return;
+ }
+ // We've seen a method with this name, see if we have already seen this type
+ // signature.
+ for (ObjCMethodList *List = &Entry; List; List = List->Next)
+ if (MatchTwoMethodDeclarations(Method, List->Method)) {
+ List->Method->setDefined(impl);
+ return;
}
- }
+
+ // We have a new signature for an existing method - add it.
+ // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
+ ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
+ Entry.Next = new (Mem) ObjCMethodList(Method, Entry.Next);
}
ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
- SourceRange R) {
+ SourceRange R,
+ bool warn) {
llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
= FactoryMethodPool.find(Sel);
if (Pos == FactoryMethodPool.end()) {
@@ -1246,7 +1247,7 @@ ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
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;
+ issueWarning = warn;
}
if (issueWarning && (MethList.Method && MethList.Next)) {
Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
@@ -1259,6 +1260,18 @@ ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
return MethList.Method;
}
+ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
+ SourceRange SR;
+ ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
+ SR, false);
+ if (Method && Method->isDefined())
+ return Method;
+ Method = LookupFactoryMethodInGlobalPool(Sel, SR, false);
+ if (Method && Method->isDefined())
+ return Method;
+ return 0;
+}
+
/// CompareMethodParamsInBaseAndSuper - This routine compares methods with
/// identical selector names in current and its super classes and issues
/// a warning if any of their argument types are incompatible.
@@ -1540,7 +1553,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
ResultTInfo,
cast<DeclContext>(ClassDecl),
MethodType == tok::minus, isVariadic,
- false,
+ false, false,
MethodDeclKind == tok::objc_optional ?
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
@@ -1849,3 +1862,15 @@ void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
}
}
+void Sema::DiagnoseUseOfUnimplementedSelectors() {
+ if (ReferencedSelectors.empty())
+ return;
+ for (llvm::DenseMap<Selector, SourceLocation>::iterator S =
+ ReferencedSelectors.begin(),
+ E = ReferencedSelectors.end(); S != E; ++S) {
+ Selector Sel = (*S).first;
+ if (!LookupImplementedMethodInGlobalPool(Sel))
+ Diag((*S).second, diag::warn_unimplemented_selector) << Sel;
+ }
+ return;
+}