r215577 - Objective-C. This patch is to resolve the method used in method
Fariborz Jahanian
fjahanian at apple.com
Wed Aug 13 14:07:35 PDT 2014
Author: fjahanian
Date: Wed Aug 13 16:07:35 2014
New Revision: 215577
URL: http://llvm.org/viewvc/llvm-project?rev=215577&view=rev
Log:
Objective-C. This patch is to resolve the method used in method
expression to the best method found in global method pools.
This is wip. // rdar://16808765
Added:
cfe/trunk/test/SemaObjC/resolve-method-in-global-pool.m
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaObjC/warn-strict-selector-match.m
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=215577&r1=215576&r2=215577&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Aug 13 16:07:35 2014
@@ -2883,6 +2883,19 @@ private:
ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R,
bool receiverIdOrClass,
bool warn, bool instance);
+
+ /// \brief - Returns instance or factory methods in global method pool for
+ /// given selector. If no such method or only one method found, function returns
+ /// false; otherwise, it returns true
+ bool CollectMultipleMethodsInGlobalPool(Selector Sel,
+ SmallVectorImpl<ObjCMethodDecl*>& Methods,
+ bool instance);
+
+ /// \brief - Returns a selector which best matches given argument list or
+ /// nullptr if none could be found
+ ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args,
+ SmallVectorImpl<ObjCMethodDecl*>& Methods);
+
/// \brief Record the typo correction failure and return an empty correction.
TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc,
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=215577&r1=215576&r2=215577&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Aug 13 16:07:35 2014
@@ -2315,6 +2315,23 @@ static bool isAcceptableMethodMismatch(O
return (chosen->getReturnType()->isIntegerType());
}
+bool Sema::CollectMultipleMethodsInGlobalPool(Selector Sel,
+ SmallVectorImpl<ObjCMethodDecl*>& Methods,
+ bool instance) {
+ if (ExternalSource)
+ ReadMethodPool(Sel);
+
+ GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
+ if (Pos == MethodPool.end())
+ return false;
+ // Gather the non-hidden methods.
+ ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
+ for (ObjCMethodList *M = &MethList; M; M = M->getNext())
+ if (M->Method && !M->Method->isHidden())
+ Methods.push_back(M->Method);
+ return (Methods.size() > 1);
+}
+
ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
bool receiverIdOrClass,
bool warn, bool instance) {
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=215577&r1=215576&r2=215577&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Aug 13 16:07:35 2014
@@ -2418,6 +2418,13 @@ ExprResult Sema::BuildInstanceMessage(Ex
Method = LookupFactoryMethodInGlobalPool(Sel,
SourceRange(LBracLoc,RBracLoc),
receiverIsId);
+ if (Method) {
+ SmallVector<ObjCMethodDecl*, 4> Methods;
+ if (CollectMultipleMethodsInGlobalPool(Sel, Methods,
+ Method->isInstanceMethod()))
+ if (ObjCMethodDecl *BestMethod = SelectBestMethod(Sel, ArgsIn, Methods))
+ Method = BestMethod;
+ }
} else if (ReceiverType->isObjCClassType() ||
ReceiverType->isObjCQualifiedClassType()) {
// Handle messages to Class.
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=215577&r1=215576&r2=215577&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Aug 13 16:07:35 2014
@@ -5677,6 +5677,79 @@ Sema::AddOverloadCandidate(FunctionDecl
}
}
+ObjCMethodDecl *Sema::SelectBestMethod(Selector Sel, MultiExprArg Args,
+ SmallVectorImpl<ObjCMethodDecl*>& Methods) {
+ for (unsigned b = 0, e = Methods.size(); b < e; b++) {
+ bool Match = true;
+ ObjCMethodDecl *Method = Methods[b];
+ unsigned NumNamedArgs = Sel.getNumArgs();
+ // Method might have more arguments than selector indicates. This is due
+ // to addition of c-style arguments in method.
+ if (Method->param_size() > NumNamedArgs)
+ NumNamedArgs = Method->param_size();
+ if (Args.size() < NumNamedArgs)
+ continue;
+
+ for (unsigned i = 0; i < NumNamedArgs; i++) {
+ // We can't do any type-checking on a type-dependent argument.
+ if (Args[i]->isTypeDependent()) {
+ Match = false;
+ break;
+ }
+
+ ParmVarDecl *param = Method->parameters()[i];
+ Expr *argExpr = Args[i];
+ assert(argExpr && "SelectBestMethod(): missing expression");
+
+ // Strip the unbridged-cast placeholder expression off unless it's
+ // a consumed argument.
+ if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&
+ !param->hasAttr<CFConsumedAttr>())
+ argExpr = stripARCUnbridgedCast(argExpr);
+
+ // If the parameter is __unknown_anytype, move on to the next method.
+ if (param->getType() == Context.UnknownAnyTy) {
+ Match = false;
+ break;
+ }
+
+ ImplicitConversionSequence ConversionState
+ = TryCopyInitialization(*this, argExpr, param->getType(),
+ /*SuppressUserConversions*/false,
+ /*InOverloadResolution=*/true,
+ /*AllowObjCWritebackConversion=*/
+ getLangOpts().ObjCAutoRefCount,
+ /*AllowExplicit*/false);
+ if (ConversionState.isBad()) {
+ Match = false;
+ break;
+ }
+ }
+ // Promote additional arguments to variadic methods.
+ if (Match && Method->isVariadic()) {
+ for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
+ if (Args[i]->isTypeDependent()) {
+ Match = false;
+ break;
+ }
+ ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod,
+ nullptr);
+ if (Arg.isInvalid()) {
+ Match = false;
+ break;
+ }
+ }
+ } else
+ // Check for extra arguments to non-variadic methods.
+ if (Args.size() != NumNamedArgs)
+ Match = false;
+
+ if (Match)
+ return Method;
+ }
+ return nullptr;
+}
+
static bool IsNotEnableIfAttr(Attr *A) { return !isa<EnableIfAttr>(A); }
EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
Added: cfe/trunk/test/SemaObjC/resolve-method-in-global-pool.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/resolve-method-in-global-pool.m?rev=215577&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/resolve-method-in-global-pool.m (added)
+++ cfe/trunk/test/SemaObjC/resolve-method-in-global-pool.m Wed Aug 13 16:07:35 2014
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s
+// expected-no-diagnostics
+
+// rdar://16808765
+
+ at interface NSObject @end
+
+ at class NSDictionary;
+ at class NSError;
+
+ at interface Foo : NSObject
+- (void)getDonuts:(void (^)(NSDictionary *, NSError *))replyBlock;
+- (void)getCake:(int*)arg, ...;
+ at end
+
+ at protocol Protocol
+ at required
+- (void)getDonuts:(void (^)(NSDictionary *))replyBlock;
+- (void)getCake:(float*)arg, ...;
+ at end
+
+ at implementation Foo
+{
+ float g;
+}
+
+- (void)getDonuts:(void (^)(NSDictionary *, NSError *))replyBlock {
+ [(id) 0 getDonuts:^(NSDictionary *replyDict) { }];
+}
+
+- (void) getCake:(int*)arg, ... {
+ [(id)0 getCake: &g, 1,3.14];
+}
+ at end
Modified: cfe/trunk/test/SemaObjC/warn-strict-selector-match.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/warn-strict-selector-match.m?rev=215577&r1=215576&r2=215577&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/warn-strict-selector-match.m (original)
+++ cfe/trunk/test/SemaObjC/warn-strict-selector-match.m Wed Aug 13 16:07:35 2014
@@ -29,8 +29,7 @@ id foo(void) {
}
@protocol MyObject
-- (id)initWithData:(Object *)data; // expected-note {{using}} \
- // expected-note {{passing argument to parameter 'data' here}}
+- (id)initWithData:(Object *)data; // expected-note {{using}}
@end
@protocol SomeOther
@@ -54,8 +53,7 @@ id foo(void) {
}
+ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data
{
- NTGridDataObject *result = [(id)0 initWithData:data]; // expected-warning {{multiple methods named 'initWithData:' found}} \
- expected-warning {{sending 'id<MyObject,MyCoding>' to parameter of incompatible type 'Object *'}}
+ NTGridDataObject *result = [(id)0 initWithData:data]; // expected-warning {{multiple methods named 'initWithData:' found}}
return result;
}
@end
More information about the cfe-commits
mailing list