]> granicus.if.org Git - clang/commitdiff
ir-gen support for class getter/setter call
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 10 Mar 2009 18:03:11 +0000 (18:03 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 10 Mar 2009 18:03:11 +0000 (18:03 +0000)
using property dot-syntax.

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

include/clang/AST/ExprObjC.h
lib/CodeGen/CGObjC.cpp
test/CodeGenObjC/class-getter-dotsyntax.m [new file with mode: 0644]

index d312d539a8a444b7b34af76e56b683c677a266e9..5775cab3ba90eef7964a095eb04397210a1a30d9 100644 (file)
@@ -275,7 +275,11 @@ public:
   ObjCMethodDecl *getSetterMethod() const {
     return Setter;
   }
-    
+
+  ObjCInterfaceDecl *getClassProp() const {
+    return ClassProp;
+  }
+  
   virtual SourceRange getSourceRange() const {
     if (Base)
       return SourceRange(getBase()->getLocStart(), Loc);
index 579886507744099b40497ba3de8523cc2b3cf3c2..aa1f4c24944d6a64ef2de63a93ae226f08acfc0a 100644 (file)
@@ -327,10 +327,17 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
   else {
     const ObjCKVCRefExpr *KE = cast<ObjCKVCRefExpr>(Exp);
     Selector S = KE->getGetterMethod()->getSelector();
+    llvm::Value *Receiver;
+    if (KE->getClassProp()) {
+      const ObjCInterfaceDecl *OID = KE->getClassProp();
+      Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
+    }
+    else 
+      Receiver = EmitScalarExpr(KE->getBase());
     return CGM.getObjCRuntime().
              GenerateMessageSend(*this, Exp->getType(), S, 
-                                 EmitScalarExpr(KE->getBase())
-                                 false, CallArgList());
+                                 Receiver
+                                 KE->getClassProp() != 0, CallArgList());
   }
 }
 
@@ -348,10 +355,17 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
   else if (const ObjCKVCRefExpr *E = dyn_cast<ObjCKVCRefExpr>(Exp)) {
     Selector S = E->getSetterMethod()->getSelector();
     CallArgList Args;
+    llvm::Value *Receiver;
+    if (E->getClassProp()) {
+      const ObjCInterfaceDecl *OID = E->getClassProp();
+      Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
+    }
+    else 
+      Receiver = EmitScalarExpr(E->getBase());
     Args.push_back(std::make_pair(Src, E->getType()));
     CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S, 
-                                             EmitScalarExpr(E->getBase())
-                                             false, Args);
+                                             Receiver
+                                             E->getClassProp() != 0, Args);
   }
   else
     assert (0 && "bad expression node in EmitObjCPropertySet");
diff --git a/test/CodeGenObjC/class-getter-dotsyntax.m b/test/CodeGenObjC/class-getter-dotsyntax.m
new file mode 100644 (file)
index 0000000..54ed890
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: clang -fnext-runtime -emit-llvm -o %t %s
+
+@interface Test { }
++ (Test *)crash;
++ (void)setCrash: (int)value;
+@end
+
+@implementation Test
+static int _value;
+- (void)cachesPath
+{
+ static Test *cachesPath;
+
+ if (!cachesPath) {
+  Test *crash = Test.crash;
+ }
+}
++ (Test *)crash{ return 0; }
++ (void)setCrash: (int)value{ _value = value; }
+@end
+