]> granicus.if.org Git - clang/commitdiff
Initial support for Obj-C dot-syntax for getters.
authorDaniel Dunbar <daniel@zuster.org>
Wed, 27 Aug 2008 06:57:25 +0000 (06:57 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 27 Aug 2008 06:57:25 +0000 (06:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55410 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CodeGenFunction.h

index c3db624478ecfa24580a9c02e969078d63345aa2..d335ea9c3fb384f2d79759d0874d8c2a845bf3ce 100644 (file)
@@ -91,10 +91,7 @@ public:
   void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
     EmitAggLoadOfLValue(E);
   }
-  void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
-    // FIXME: Implement!
-    CGF.ErrorUnsupported(E, "aggregate expression (Objective-C property reference)");
-  }
+  void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
   
   void VisitConditionalOperator(const ConditionalOperator *CO);
   void VisitInitListExpr(InitListExpr *E);
@@ -219,6 +216,18 @@ void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
   EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
 }
 
+void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  RValue RV = CGF.EmitObjCPropertyGet(E);
+  assert(RV.isAggregate() && "Return value must be aggregate value!");
+  
+  // If the result is ignored, don't copy from the value.
+  if (DestPtr == 0)
+    // FIXME: If the source is volatile, we must read from it.
+    return;
+  
+  EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
+}
+
 void AggExprEmitter::VisitOverloadExpr(const OverloadExpr *E) {
   RValue RV = CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
                                E->arg_end(CGF.getContext()));
index 11d1e8dfdb9e2ab770e77c104c903e4e4caab077..cee8852cdca8c6348cac490465c3b09c1a933f30 100644 (file)
@@ -134,14 +134,20 @@ public:
       return llvm::ConstantInt::get(EC->getInitVal());
     return EmitLoadOfLValue(E);
   }
-  Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E);
-  Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E);
-  Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { return EmitLoadOfLValue(E);}
+  Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) { 
+    return CGF.EmitObjCSelectorExpr(E); 
+  }
+  Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) { 
+    return CGF.EmitObjCProtocolExpr(E); 
+  }
+  Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 
+    return EmitLoadOfLValue(E);
+  }
   Value *VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
-    CGF.ErrorUnsupported(E, "scalar expression (Objective-C property reference)");
-    if (E->getType()->isVoidType())
-      return 0;
-    return llvm::UndefValue::get(CGF.ConvertType(E->getType()));    
+    return CGF.EmitObjCPropertyGet(E).getScalarVal();
+  }
+  Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
+    return CGF.EmitObjCMessageExpr(E).getScalarVal();
   }
 
   Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
@@ -196,10 +202,6 @@ public:
     return CGF.EmitCallExpr(E).getScalarVal();
   }
 
-  Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
-    return CGF.EmitObjCMessageExpr(E).getScalarVal();
-  }
-
   Value *VisitStmtExpr(const StmtExpr *E);
   
   // Unary Operators.
@@ -481,14 +483,6 @@ Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
   return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
 }
 
-Value *ScalarExprEmitter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
-  return CGF.EmitObjCSelectorExpr(E);
-}
-
-Value *ScalarExprEmitter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
-  return CGF.EmitObjCProtocolExpr(E);
-}
-
 Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
   // Emit subscript expressions in rvalue context's.  For most cases, this just
   // loads the lvalue formed by the subscript expr.  However, we have to be
index 93567a4f8f58e57d3e9e7fe7a3b3a509d6db8e56..cec75dea9b58aa88af1a98c80b470e25b797a7d7 100644 (file)
@@ -218,4 +218,24 @@ llvm::Value *CodeGenFunction::LoadObjCSelf(void) {
   return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
 }
 
+RValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) {
+  // Determine getter selector.
+  Selector S;
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(E->getDecl())) {
+    S = MD->getSelector();
+  } else {
+    S = cast<ObjCPropertyDecl>(E->getDecl())->getGetterName();
+  }
+
+  // FIXME: Improve location information.
+  SourceLocation Loc = E->getLocation();
+  // PropertyRefExprs are always instance messages.
+  // FIXME: Is there any reason to try and pass the method here?
+  ObjCMessageExpr GetExpr(const_cast<Expr*>(E->getBase()), 
+                          S, E->getType(), 0, Loc, Loc,
+                          0, 0);
+
+  return EmitObjCMessageExpr(&GetExpr);
+}
+
 CGObjCRuntime::~CGObjCRuntime() {}
index 4eed9a7173f574bd7c1f41d4b67d771da447ccf5..0178f8a3e3e14168913f68a1e2eb059ecd082a79 100644 (file)
@@ -326,6 +326,7 @@ public:
   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
   llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
   RValue EmitObjCMessageExpr(const ObjCMessageExpr *E);
+  RValue EmitObjCPropertyGet(const ObjCPropertyRefExpr *E);
 
 
   //===--------------------------------------------------------------------===//