[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