[cfe-commits] r55681 - in /cfe/trunk: include/clang/AST/ExprObjC.h lib/AST/StmtDumper.cpp lib/AST/StmtSerialization.cpp lib/CodeGen/CGObjC.cpp lib/CodeGen/CGObjCMac.cpp

Daniel Dunbar daniel at zuster.org
Tue Sep 2 17:27:27 PDT 2008


Author: ddunbar
Date: Tue Sep  2 19:27:26 2008
New Revision: 55681

URL: http://llvm.org/viewvc/llvm-project?rev=55681&view=rev
Log:
Fix ObjCPropertRefExpr to be able to encode all the information for
uses which refer to methods not properties.
 - Not yet wired in Sema.

Modified:
    cfe/trunk/include/clang/AST/ExprObjC.h
    cfe/trunk/lib/AST/StmtDumper.cpp
    cfe/trunk/lib/AST/StmtSerialization.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp

Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=55681&r1=55680&r2=55681&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Tue Sep  2 19:27:26 2008
@@ -20,6 +20,8 @@
 namespace clang {
   class IdentifierInfo;
   class ASTContext;
+  class ObjCMethodDecl;
+  class ObjCPropertyDecl;
   
 /// ObjCStringLiteral, used for Objective-C string literals
 /// i.e. @"foo".
@@ -189,18 +191,70 @@
   static ObjCIvarRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
 };
 
-/// ObjCPropertyRefExpr - A reference to an ObjC property.
+/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
+/// property. Note that dot-syntax can also be used to access
+/// "implicit" properties (i.e. methods following the property naming
+/// convention). Additionally, sema is not yet smart enough to know if
+/// a property reference is to a getter or a setter, so the expr must
+/// have access to both methods.
+///
+// FIXME: Consider splitting these into separate Expr classes.
 class ObjCPropertyRefExpr : public Expr {
-  class Decl *D; // an ObjCMethodDecl or ObjCPropertyDecl
+public:
+  enum Kind {
+    PropertyRef, // This expressions references a declared property.
+    MethodRef   // This expressions references methods.
+  };
+
+private:
+  // A dot-syntax reference via methods must always have a getter. We
+  // avoid storing the kind explicitly by relying on this invariant
+  // and assuming this is a MethodRef iff Getter is non-null. Setter
+  // can be null in situations which access a read-only property.
+  union {
+    ObjCPropertyDecl *AsProperty;
+    struct {
+      ObjCMethodDecl *Setter;
+      ObjCMethodDecl *Getter;
+    } AsMethod;
+  } Referent;
   SourceLocation Loc;
   Stmt *Base;
   
 public:
-  ObjCPropertyRefExpr(Decl *d, QualType t, SourceLocation l, Expr *base) : 
-    Expr(ObjCPropertyRefExprClass, t), D(d), Loc(l), Base(base) {}
-  
-  Decl *getDecl() { return D; }
-  const Decl *getDecl() const { return D; }
+  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 
+                      SourceLocation l, Expr *base)
+    : Expr(ObjCPropertyRefExprClass, t), Loc(l), Base(base) {
+    Referent.AsMethod.Getter = Referent.AsMethod.Setter = NULL;
+    Referent.AsProperty = PD;
+  }
+  ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+                      QualType t, 
+                      SourceLocation l, Expr *base)
+    : Expr(ObjCPropertyRefExprClass, t), Loc(l), Base(base) {
+    Referent.AsMethod.Getter = Getter;
+    Referent.AsMethod.Setter = Setter;
+  }
+
+  Kind getKind() const { 
+    return Referent.AsMethod.Getter ? MethodRef : PropertyRef; 
+  }
+
+  ObjCPropertyDecl *getProperty() const {
+    assert(getKind() == PropertyRef && 
+           "Cannot get property from an ObjCPropertyRefExpr using methods");
+    return Referent.AsProperty;
+  }
+  ObjCMethodDecl *getGetterMethod() const {
+    assert(getKind() == MethodRef && 
+           "Cannot get method from an ObjCPropertyRefExpr using a property");
+    return Referent.AsMethod.Getter;
+  }
+  ObjCMethodDecl *getSetterMethod() const {
+    assert(getKind() == MethodRef && 
+           "Cannot get method from an ObjCPropertyRefExpr using a property");
+    return Referent.AsMethod.Setter;
+  }
   
   virtual SourceRange getSourceRange() const { 
     return SourceRange(getBase()->getLocStart(), Loc); 

Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=55681&r1=55680&r2=55681&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Tue Sep  2 19:27:26 2008
@@ -453,12 +453,15 @@
 
 void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
   DumpExpr(Node);
-  
-  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(Node->getDecl())) {
-    fprintf(F, " MethodDecl=\"%s\"", MD->getSelector().getName().c_str());
+
+  if (Node->getKind() == ObjCPropertyRefExpr::MethodRef) {
+    ObjCMethodDecl *Getter = Node->getGetterMethod();
+    ObjCMethodDecl *Setter = Node->getSetterMethod();
+    fprintf(F, " Kind=MethodRef Getter=\"%s\" Setter=\"%s\"", 
+            Getter->getSelector().getName().c_str(),
+            Setter ? Setter->getSelector().getName().c_str() : "(null)");
   } else {
-    ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(Node->getDecl());
-    fprintf(F, " PropertyDecl=\"%s\"", PD->getName());
+    fprintf(F, " Kind=PropertyRef Property=\"%s\"", Node->getProperty()->getName());
   }
 }
 

Modified: cfe/trunk/lib/AST/StmtSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtSerialization.cpp?rev=55681&r1=55680&r2=55681&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/lib/AST/StmtSerialization.cpp Tue Sep  2 19:27:26 2008
@@ -998,7 +998,14 @@
 void ObjCPropertyRefExpr::EmitImpl(Serializer& S) const {
   S.Emit(Loc);
   S.Emit(getType());
-  S.EmitPtr(getDecl());
+  unsigned Kind = getKind();
+  S.Emit(Kind);
+  if (Kind == PropertyRef) {
+    S.EmitPtr(getProperty());
+  } else {
+    S.EmitPtr(getGetterMethod());
+    S.EmitPtr(getSetterMethod());
+  }
 }
   
 ObjCPropertyRefExpr* ObjCPropertyRefExpr::CreateImpl(Deserializer& D, 
@@ -1006,7 +1013,13 @@
   SourceLocation Loc = SourceLocation::ReadVal(D);
   QualType T = QualType::ReadVal(D);
   ObjCPropertyRefExpr* dr = new ObjCPropertyRefExpr(NULL,T,Loc,0);
-  D.ReadPtr(dr->D,false);  
+  unsigned Kind = D.ReadInt();
+  if (Kind == PropertyRef) {
+    D.ReadPtr(dr->Referent.AsProperty,false);
+  } else {
+    D.ReadPtr(dr->Referent.AsMethod.Setter,false);
+    D.ReadPtr(dr->Referent.AsMethod.Getter,false);
+  }
   return dr;
 }
 

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=55681&r1=55680&r2=55681&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Tue Sep  2 19:27:26 2008
@@ -16,6 +16,7 @@
 #include "CodeGenModule.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/Basic/Diagnostic.h"
 #include "llvm/ADT/STLExtras.h"
 
 using namespace clang;
@@ -231,10 +232,10 @@
 RValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) {
   // Determine getter selector.
   Selector S;
-  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(E->getDecl())) {
-    S = MD->getSelector();
+  if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
+    S = E->getGetterMethod()->getSelector();
   } else {
-    S = cast<ObjCPropertyDecl>(E->getDecl())->getGetterName();
+    S = E->getProperty()->getGetterName();
   }
 
   return CGM.getObjCRuntime().
@@ -246,12 +247,21 @@
 void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E,
                                           RValue Src) {
   Selector S;
-  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(E->getDecl())) {
-    S = PD->getSetterName();
+  if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
+    ObjCMethodDecl *Setter = E->getSetterMethod(); 
+    
+    if (Setter) {
+      S = Setter->getSelector();
+    } else {
+      // FIXME: This should be diagnosed by sema.
+      SourceRange Range = E->getSourceRange();
+      CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()),
+                            diag::err_typecheck_assign_const, 0, 0,
+                            &Range, 1);
+      return;
+    }
   } else {
-    // FIXME: How can we have a method decl here?
-    ErrorUnsupported(E, "Objective-C property setter call");
-    return;
+    S = E->getProperty()->getSetterName();
   }
 
   CallArgList Args;

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=55681&r1=55680&r2=55681&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Sep  2 19:27:26 2008
@@ -499,9 +499,8 @@
   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
 
   // FIXME: This is a hack, we are implicitly coordinating with
-  // EmitCallExprExt, which will move the return type to the first
-  // parameter and set the structure return flag. See
-  // getMessageSendFn().
+  // EmitCall, which will move the return type to the first parameter
+  // and set the structure return flag. See getMessageSendFn().
                                                    
   const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(ResultType);
   return CGF.EmitCall(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy),





More information about the cfe-commits mailing list