aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-09-17 19:23:40 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-09-17 19:23:40 +0000
commit1d4e8e9340c9699069a33a74562e883a305f7607 (patch)
treecf1ede6e3c7bf0d5de25e2f32d9f57cb6e6a0aea /lib/Sema/SemaExpr.cpp
parent898f284d3777b6880b6a7051cccd0d11db7d5457 (diff)
objc - Treat type of 'self' in class methods as root of
class of this method. // rdar://10109725 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139989 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 2d80ac1265..715a4bd025 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5074,6 +5074,23 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
OK));
}
+/// SelfInClassMethodType - convet type of 'self' in class method
+/// to pointer to root of method's class.
+static void
+SelfInClassMethodType(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));
+ }
+}
+
// 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.
@@ -5309,6 +5326,8 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
return Compatible;
}
+ SelfInClassMethodType(*this, RHS.get(), RHSType);
+
// If the left-hand side is a reference type, then we are in a
// (rare!) case where we've allowed the use of references in C,
// e.g., as a parameter type in a built-in function. In this case,
@@ -9564,7 +9583,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
Selector Sel = ME->getSelector();
// self = [<foo> init...]
- if (isSelfExpr(Op->getLHS()) && Sel.getNameForSlot(0).startswith("init"))
+ if (GetMethodIfSelfExpr(Op->getLHS()) && Sel.getNameForSlot(0).startswith("init"))
diagnostic = diag::warn_condition_is_idiomatic_assignment;
// <foo> = [<bar> nextObject]