diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 43 |
3 files changed, 33 insertions, 15 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 14b72874f7f..9cb47cce4b2 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -226,6 +226,9 @@ public: /// extremely uncommon (only 1% of selectors are "overloaded"). llvm::DenseMap<Selector, ObjCMethodList> InstanceMethodPool; llvm::DenseMap<Selector, ObjCMethodList> FactoryMethodPool; + + /// Private Helper predicate to check for 'self'. + bool isSelfExpr(Expr *RExpr); public: Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer); ~Sema() { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6252bcaef5b..43909b9afe3 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2302,6 +2302,8 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) { } else if (castType->isVectorType()) { if (CheckVectorCast(TyR, castType, castExpr->getType())) return true; + } else if (getLangOptions().ObjC1 && isa<ObjCSuperExpr>(castExpr)) { + return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast); } return false; } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 39a89d6d942..8705baffcb6 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -202,6 +202,13 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, return anyIncompatibleArgs; } +bool Sema::isSelfExpr(Expr *RExpr) { + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr)) + if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self")) + return true; + return false; +} + // Helper method for ActOnClassMethod/ActOnInstanceMethod. // Will search "local" class/category implementations for a method decl. // Returns 0 if no method is found. @@ -385,6 +392,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, // Handle messages to Class. if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) { ObjCMethodDecl *Method = 0; + if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) { // First check the public methods in the class interface. @@ -396,12 +404,15 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) return true; } - // Look for any factory method named 'Sel'. - if (!Method) - Method = FactoryMethodPool[Sel].Method; - if (!Method) - Method = LookupInstanceMethodInGlobalPool( - Sel, SourceRange(lbrac,rbrac)); + if (!Method) { + // If not messaging 'self', look for any factory method named 'Sel'. + if (!isSelfExpr(RExpr)) { + Method = FactoryMethodPool[Sel].Method; + if (!Method) + Method = LookupInstanceMethodInGlobalPool( + Sel, SourceRange(lbrac,rbrac)); + } + } if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, lbrac, rbrac, returnType)) return true; @@ -462,15 +473,17 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, } } } - // If we still haven't found a method, look in the global pool. This - // behavior isn't very desirable, however we need it for GCC - // compatibility. FIXME: should we deviate?? - if (!Method && OCIType->qual_empty()) { - Method = LookupInstanceMethodInGlobalPool( - Sel, SourceRange(lbrac,rbrac)); - if (Method && !OCIType->getDecl()->isForwardDecl()) - Diag(lbrac, diag::warn_maynot_respond) - << OCIType->getDecl()->getIdentifier()->getName() << Sel; + if (!isSelfExpr(RExpr)) { + // If we still haven't found a method, look in the global pool. This + // behavior isn't very desirable, however we need it for GCC + // compatibility. FIXME: should we deviate?? + if (!Method && OCIType->qual_empty()) { + Method = LookupInstanceMethodInGlobalPool( + Sel, SourceRange(lbrac,rbrac)); + if (Method && !OCIType->getDecl()->isForwardDecl()) + Diag(lbrac, diag::warn_maynot_respond) + << OCIType->getDecl()->getIdentifier()->getName() << Sel; + } } } if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) |