forked from OSchip/llvm-project
Revert r139989 and r140031, which implemented the Objective-C type
system change in <rdar://problem/10109725> that allows conversion from 'self' in class methods to the root of the class's hierarchy. This conversion rule is a hack that has non-trivial repurcussions (particularly with overload resolution). llvm-svn: 140605
This commit is contained in:
parent
3c9029b06c
commit
486b74e596
|
@ -677,9 +677,8 @@ public:
|
|||
|
||||
GlobalMethodPool::iterator ReadMethodPool(Selector Sel);
|
||||
|
||||
/// Private Helper predicate to check for 'self'. Upon success, it
|
||||
/// returns method declaration where 'self' is referenced.
|
||||
const ObjCMethodDecl *GetMethodIfSelfExpr(Expr *RExpr);
|
||||
/// Private Helper predicate to check for 'self'.
|
||||
bool isSelfExpr(Expr *RExpr);
|
||||
public:
|
||||
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
||||
TranslationUnitKind TUKind = TU_Complete,
|
||||
|
|
|
@ -5107,25 +5107,6 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
|
|||
OK));
|
||||
}
|
||||
|
||||
/// ConvertObjCSelfToClassRootType - convet type of 'self' in class method
|
||||
/// to pointer to root of method's class.
|
||||
static QualType
|
||||
ConvertObjCSelfToClassRootType(Sema &S, Expr *selfExpr) {
|
||||
QualType SelfType;
|
||||
if (const ObjCMethodDecl *MD = S.GetMethodIfSelfExpr(selfExpr))
|
||||
if (MD->isClassMethod()) {
|
||||
const ObjCInterfaceDecl *Root = 0;
|
||||
if (const ObjCInterfaceDecl * IDecl = MD->getClassInterface())
|
||||
do {
|
||||
Root = IDecl;
|
||||
} while ((IDecl = IDecl->getSuperClass()));
|
||||
if (Root)
|
||||
SelfType = S.Context.getObjCObjectPointerType(
|
||||
S.Context.getObjCInterfaceType(Root));
|
||||
}
|
||||
return SelfType;
|
||||
}
|
||||
|
||||
// checkPointerTypesForAssignment - This is a very tricky routine (despite
|
||||
// being closely modeled after the C99 spec:-). The odd characteristic of this
|
||||
// routine is it effectively iqnores the qualifiers on the top level pointee.
|
||||
|
@ -5453,7 +5434,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
|
|||
Kind = CK_BitCast;
|
||||
return Compatible;
|
||||
}
|
||||
|
||||
|
||||
Kind = CK_BitCast;
|
||||
return IncompatiblePointer;
|
||||
}
|
||||
|
@ -5501,9 +5482,6 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
|
|||
|
||||
// Conversions to Objective-C pointers.
|
||||
if (isa<ObjCObjectPointerType>(LHSType)) {
|
||||
QualType RHSQT = ConvertObjCSelfToClassRootType(*this, RHS.get());
|
||||
if (!RHSQT.isNull())
|
||||
RHSType = RHSQT;
|
||||
// A* -> B*
|
||||
if (RHSType->isObjCObjectPointerType()) {
|
||||
Kind = CK_BitCast;
|
||||
|
@ -9619,7 +9597,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
|
|||
Selector Sel = ME->getSelector();
|
||||
|
||||
// self = [<foo> init...]
|
||||
if (GetMethodIfSelfExpr(Op->getLHS()) && Sel.getNameForSlot(0).startswith("init"))
|
||||
if (isSelfExpr(Op->getLHS()) && Sel.getNameForSlot(0).startswith("init"))
|
||||
diagnostic = diag::warn_condition_is_idiomatic_assignment;
|
||||
|
||||
// <foo> = [<bar> nextObject]
|
||||
|
|
|
@ -457,20 +457,18 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
|
|||
return IsError;
|
||||
}
|
||||
|
||||
/// GetMethodIfSelfExpr - Check if receiver is an objc 'self' expression
|
||||
/// and return its method declaration if so; else return 0.
|
||||
const ObjCMethodDecl *Sema::GetMethodIfSelfExpr(Expr *receiver) {
|
||||
bool Sema::isSelfExpr(Expr *receiver) {
|
||||
// 'self' is objc 'self' in an objc method only.
|
||||
DeclContext *DC = CurContext;
|
||||
while (isa<BlockDecl>(DC))
|
||||
DC = DC->getParent();
|
||||
if (DC && !isa<ObjCMethodDecl>(DC))
|
||||
return 0;
|
||||
return false;
|
||||
receiver = receiver->IgnoreParenLValueCasts();
|
||||
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
|
||||
if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
|
||||
return static_cast<ObjCMethodDecl*>(DC);
|
||||
return 0;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helper method for ActOnClassMethod/ActOnInstanceMethod.
|
||||
|
@ -1274,7 +1272,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
|||
}
|
||||
if (!Method) {
|
||||
// If not messaging 'self', look for any factory method named 'Sel'.
|
||||
if (!Receiver || !GetMethodIfSelfExpr(Receiver)) {
|
||||
if (!Receiver || !isSelfExpr(Receiver)) {
|
||||
Method = LookupFactoryMethodInGlobalPool(Sel,
|
||||
SourceRange(LBracLoc, RBracLoc),
|
||||
true);
|
||||
|
@ -1338,7 +1336,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
|||
return ExprError();
|
||||
}
|
||||
|
||||
if (!Method && (!Receiver || !GetMethodIfSelfExpr(Receiver))) {
|
||||
if (!Method && (!Receiver || !isSelfExpr(Receiver))) {
|
||||
// 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??
|
||||
|
@ -1509,7 +1507,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
|||
if (getLangOptions().ObjCAutoRefCount) {
|
||||
// In ARC, annotate delegate init calls.
|
||||
if (Result->getMethodFamily() == OMF_init &&
|
||||
(SuperLoc.isValid() || GetMethodIfSelfExpr(Receiver))) {
|
||||
(SuperLoc.isValid() || isSelfExpr(Receiver))) {
|
||||
// Only consider init calls *directly* in init implementations,
|
||||
// not within blocks.
|
||||
ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(CurContext);
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// rdar://10109725
|
||||
|
||||
@interface NSObject {
|
||||
Class isa;
|
||||
}
|
||||
- (id)addObserver:(NSObject *)observer; // expected-note 2 {{passing argument to parameter 'observer' here}}
|
||||
@end
|
||||
|
||||
@interface MyClass : NSObject {
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSObject
|
||||
+ (void)initialize
|
||||
{
|
||||
NSObject *obj = 0;
|
||||
[obj addObserver:self];
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
NSObject *obj = 0;
|
||||
[obj addObserver:self];
|
||||
return [obj addObserver:(Class)0]; // expected-warning {{incompatible pointer types sending 'Class' to parameter of type 'NSObject *'}}
|
||||
}
|
||||
- (id)addObserver:(NSObject *)observer { return 0; }
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
NSObject *obj = 0;
|
||||
[obj addObserver:self];
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
NSObject *obj = 0;
|
||||
[obj addObserver:self];
|
||||
return [obj addObserver:(Class)0]; // expected-warning {{incompatible pointer types sending 'Class' to parameter of type 'NSObject *'}}
|
||||
}
|
||||
@end
|
Loading…
Reference in New Issue