From: Douglas Gregor Date: Wed, 25 Jan 2012 00:59:09 +0000 (+0000) Subject: Whenever Sema attempts to look in the global method pool, try to load X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0d266d623452f09d06973528217390d762a8f3fa;p=clang Whenever Sema attempts to look in the global method pool, try to load additional data from the external Sema source. This properly copes with modules that are imported after we have already searched in the global method pool for a given selector. For PCH, it's a slight pessimization to be fixed soon. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148891 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 432e3ddf54..4394dbf9be 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1983,17 +1983,13 @@ void Sema::ReadMethodPool(Selector Sel) { void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance) { + if (ExternalSource) + ReadMethodPool(Method->getSelector()); + GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector()); - if (Pos == MethodPool.end()) { - if (ExternalSource) { - ReadMethodPool(Method->getSelector()); - Pos = MethodPool.find(Method->getSelector()); - } - - if (Pos == MethodPool.end()) - Pos = MethodPool.insert(std::make_pair(Method->getSelector(), - GlobalMethods())).first; - } + if (Pos == MethodPool.end()) + Pos = MethodPool.insert(std::make_pair(Method->getSelector(), + GlobalMethods())).first; Method->setDefined(impl); @@ -2023,18 +2019,12 @@ static bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen, ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass, bool warn, bool instance) { + if (ExternalSource) + ReadMethodPool(Sel); + GlobalMethodPool::iterator Pos = MethodPool.find(Sel); - if (Pos == MethodPool.end()) { - if (ExternalSource) { - ReadMethodPool(Sel); - - Pos = MethodPool.find(Sel); - if (Pos == MethodPool.end()) - return 0; - - } else - return 0; - } + if (Pos == MethodPool.end()) + return 0; ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second; diff --git a/test/Modules/Inputs/MethodPoolA.h b/test/Modules/Inputs/MethodPoolA.h new file mode 100644 index 0000000000..6af24a9291 --- /dev/null +++ b/test/Modules/Inputs/MethodPoolA.h @@ -0,0 +1,8 @@ + + + + +@interface A ++ (int)method1; +- (int)method2:(int)param; +@end diff --git a/test/Modules/Inputs/MethodPoolB.h b/test/Modules/Inputs/MethodPoolB.h new file mode 100644 index 0000000000..e1e86edaf8 --- /dev/null +++ b/test/Modules/Inputs/MethodPoolB.h @@ -0,0 +1,13 @@ + + + + + + + + + +@interface B +- (int)method1; +- (int)method2:(float)param; +@end diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index 2819e62b8f..e09073f818 100644 --- a/test/Modules/Inputs/module.map +++ b/test/Modules/Inputs/module.map @@ -75,3 +75,9 @@ module namespaces_right { header "namespaces-right.h" export * } +module MethodPoolA { + header "MethodPoolA.h" +} +module MethodPoolB { + header "MethodPoolB.h" +} diff --git a/test/Modules/method_pool.m b/test/Modules/method_pool.m new file mode 100644 index 0000000000..9574caa152 --- /dev/null +++ b/test/Modules/method_pool.m @@ -0,0 +1,30 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodule-cache-path %t -fmodules -I %S/Inputs %s -verify + +@import MethodPoolA; + + +// in other file: // expected-note{{using}} + + + + +// in other file: expected-note{{also found}} + +void testMethod1(id object) { + [object method1]; +} + +void testMethod2(id object) { + [object method2:1]; +} + +@import MethodPoolB; + +void testMethod1Again(id object) { + [object method1]; +} + +void testMethod2Again(id object) { + [object method2:1]; // expected-warning{{multiple methods named 'method2:' found}} +}