summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/ExprObjC.h6
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp22
-rw-r--r--clang/test/CodeGenObjC/class-getter-dotsyntax.m21
3 files changed, 44 insertions, 5 deletions
diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h
index d312d539a8a..5775cab3ba9 100644
--- a/clang/include/clang/AST/ExprObjC.h
+++ b/clang/include/clang/AST/ExprObjC.h
@@ -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);
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 57988650774..aa1f4c24944 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -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/clang/test/CodeGenObjC/class-getter-dotsyntax.m b/clang/test/CodeGenObjC/class-getter-dotsyntax.m
new file mode 100644
index 00000000000..54ed890cc4d
--- /dev/null
+++ b/clang/test/CodeGenObjC/class-getter-dotsyntax.m
@@ -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
+
OpenPOWER on IntegriCloud