]> granicus.if.org Git - clang/commitdiff
Objective-C. Patch to allow use of dot syntax on class
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 21 Apr 2014 20:22:17 +0000 (20:22 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 21 Apr 2014 20:22:17 +0000 (20:22 +0000)
objects to fund root class's instance methods.
// rdar://16650575

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206781 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaPseudoObject.cpp
test/SemaObjC/class-property-access.m

index 5bffdd1573a6ba4434ff96181e8cc8ba2b936f20..8dd319c98bdc9bb21c613ab1e807015f067f1d2c 100644 (file)
@@ -1762,10 +1762,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
 
   // If this reference is in an @implementation, check for 'private' methods.
   if (!Getter)
-    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
-      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
-        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
-          Getter = ImpDecl->getClassMethod(Sel);
+    Getter = IFace->lookupPrivateClassMethod(Sel);
 
   if (Getter) {
     // FIXME: refactor/share with ActOnMemberReference().
@@ -1784,10 +1781,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
   if (!Setter) {
     // If this reference is in an @implementation, also check for 'private'
     // methods.
-    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
-      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
-        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
-          Setter = ImpDecl->getClassMethod(SetterSel);
+    Setter = IFace->lookupPrivateClassMethod(SetterSel);
   }
   // Look through local category implementations associated with the class.
   if (!Setter)
index de02fa935ef6bd7daff354001add3492bcb94ffa..a8463cdbd4ef662d4928c7e6afec91baf78aaa17 100644 (file)
@@ -681,7 +681,8 @@ ExprResult ObjCPropertyOpBuilder::buildGet() {
 
   // Build a message-send.
   ExprResult msg;
-  if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
+  if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
+      RefExpr->isObjectReceiver()) {
     assert(InstanceReceiver || RefExpr->isSuperReceiver());
     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
                                          GenericLoc, Getter->getSelector(),
@@ -750,7 +751,8 @@ ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
 
   // Build a message-send.
   ExprResult msg;
-  if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
+  if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
+      RefExpr->isObjectReceiver()) {
     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
                                          GenericLoc, SetterSelector, Setter,
                                          MultiExprArg(args, 1));
index 735b51a3c432908d1a148077d4d2cfaa6f66e3cf..a4c188c434ec2211a5882d7c59c996618d0b032d 100644 (file)
@@ -11,3 +11,46 @@ int main ()
   return Test.one.two;
 }
 
+// rdar://16650575
+__attribute__((objc_root_class))
+@interface RootClass { 
+  Class isa; 
+}
+
+@property int property;
+-(int)method;
+- (void) setMethod : (int)arg;
++(int)classMethod;
+@end
+
+@interface Subclass : RootClass @end
+void Test1() { 
+    // now okay
+    (void)RootClass.property;
+    (void)Subclass.property;
+    (void)RootClass.method;
+    (void)Subclass.method;
+
+    RootClass.property = 1;
+    Subclass.property = 2;
+    RootClass.method = 3;
+    Subclass.method = 4;
+
+    // okay
+    (void)RootClass.classMethod;
+    (void)Subclass.classMethod;
+
+    // also okay
+    [RootClass property];
+    [Subclass property];
+    [RootClass method];
+    [Subclass method];
+    [RootClass classMethod];
+    [Subclass classMethod];
+
+    // also okay
+    [RootClass setProperty : 1];
+    [Subclass setProperty : 2];
+    [RootClass setMethod : 3];
+    [Subclass setMethod : 4];
+}