[cfe-commits] r59878 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/ExprObjC.h include/clang/Basic/DiagnosticKinds.def lib/AST/Expr.cpp lib/AST/StmtSerialization.cpp lib/Sema/SemaExpr.cpp test/SemaObjC/property-error-readonly-assign.m
Fariborz Jahanian
fjahanian at apple.com
Sat Nov 22 12:25:51 PST 2008
Author: fjahanian
Date: Sat Nov 22 14:25:50 2008
New Revision: 59878
URL: http://llvm.org/viewvc/llvm-project?rev=59878&view=rev
Log:
Support for implicit property assignment. Error assigning to
'implicit' property with no 'setter'.
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/ExprObjC.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/StmtSerialization.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaObjC/property-error-readonly-assign.m
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=59878&r1=59877&r2=59878&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Nov 22 14:25:50 2008
@@ -104,7 +104,8 @@
MLV_ConstQualified,
MLV_ArrayType,
MLV_NotBlockQualified,
- MLV_ReadonlyProperty
+ MLV_ReadonlyProperty,
+ MLV_NoSetterProperty
};
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx) const;
Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=59878&r1=59877&r2=59878&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Sat Nov 22 14:25:50 2008
@@ -251,17 +251,15 @@
public:
ObjCKVCRefExpr(ObjCMethodDecl *getter,
QualType t,
+ ObjCMethodDecl *setter,
SourceLocation l, Expr *base)
- : Expr(ObjCKVCRefExprClass, t), Setter(0),
+ : Expr(ObjCKVCRefExprClass, t), Setter(setter),
Getter(getter), Loc(l), Base(base) {
}
ObjCMethodDecl *getGetterMethod() const {
return Getter;
}
- void setSetterMethod(ObjCMethodDecl *setter) {
- Setter = setter;
- }
ObjCMethodDecl *getSetterMethod() const {
return Setter;
}
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=59878&r1=59877&r2=59878&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sat Nov 22 14:25:50 2008
@@ -543,6 +543,9 @@
"type of property '%0' does not match type of ivar '%1'")
DIAG(error_readonly_property_assignment, ERROR,
"assigning to property with 'readonly' attribute not allowed")
+DIAG(error_nosetter_property_assignment, ERROR,
+ "setter method is needed to assign to object using property"
+ " assignment syntax")
DIAG(warn_readonly_property, WARNING,
"attribute 'readonly' of property '%0' restricts attribute "
"'readwrite' of property inherited from '%1'")
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=59878&r1=59877&r2=59878&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat Nov 22 14:25:50 2008
@@ -557,6 +557,12 @@
return MLV_ReadonlyProperty;
}
}
+ // Assigning to an 'implicit' property?
+ if (getStmtClass() == ObjCKVCRefExprClass) {
+ const ObjCKVCRefExpr* KVCExpr = cast<ObjCKVCRefExpr>(this);
+ if (KVCExpr->getSetterMethod() == 0)
+ return MLV_NoSetterProperty;
+ }
return MLV_Valid;
}
Modified: cfe/trunk/lib/AST/StmtSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtSerialization.cpp?rev=59878&r1=59877&r2=59878&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/lib/AST/StmtSerialization.cpp Sat Nov 22 14:25:50 2008
@@ -1173,7 +1173,7 @@
ASTContext& C) {
SourceLocation Loc = SourceLocation::ReadVal(D);
QualType T = QualType::ReadVal(D);
- ObjCKVCRefExpr* dr = new ObjCKVCRefExpr(NULL,T,Loc,0);
+ ObjCKVCRefExpr* dr = new ObjCKVCRefExpr(NULL,T,NULL,Loc,0);
D.ReadPtr(dr->Setter,false);
D.ReadPtr(dr->Getter,false);
return dr;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=59878&r1=59877&r2=59878&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Nov 22 14:25:50 2008
@@ -1090,6 +1090,20 @@
return VT; // should never get here (a typedef type should always be found).
}
+/// constructSetterName - Return the setter name for the given
+/// identifier, i.e. "set" + Name where the initial character of Name
+/// has been capitalized.
+// FIXME: Merge with same routine in Parser. But where should this
+// live?
+static IdentifierInfo *constructSetterName(IdentifierTable &Idents,
+ const IdentifierInfo *Name) {
+ llvm::SmallString<100> SelectorName;
+ SelectorName = "set";
+ SelectorName.append(Name->getName(), Name->getName()+Name->getLength());
+ SelectorName[3] = toupper(SelectorName[3]);
+ return &Idents.get(&SelectorName[0], &SelectorName[SelectorName.size()]);
+}
+
Action::ExprResult Sema::
ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc,
@@ -1198,9 +1212,30 @@
}
if (Getter) {
// If we found a getter then this may be a valid dot-reference, we
- // will look for the matching setter, if it is needed. But we don't
- // know this yet.
- return new ObjCKVCRefExpr(Getter, Getter->getResultType(),
+ // will look for the matching setter, in case it is needed.
+ IdentifierInfo *SetterName = constructSetterName(PP.getIdentifierTable(),
+ &Member);
+ Selector SetterSel = PP.getSelectorTable().getUnarySelector(SetterName);
+ ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
+ if (!Setter) {
+ // If this reference is in an @implementation, also check for 'private'
+ // methods.
+ if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
+ if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
+ if (ObjCImplementationDecl *ImpDecl =
+ ObjCImplementations[ClassDecl->getIdentifier()])
+ Setter = ImpDecl->getInstanceMethod(SetterSel);
+ }
+ // Look through local category implementations associated with the class.
+ if (!Setter) {
+ for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
+ if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
+ Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
+ }
+ }
+
+ // FIXME: we must check that the setter has property type.
+ return new ObjCKVCRefExpr(Getter, Getter->getResultType(), Setter,
MemberLoc, BaseExpr);
}
}
@@ -2522,6 +2557,9 @@
case Expr::MLV_ReadonlyProperty:
Diag = diag::error_readonly_property_assignment;
break;
+ case Expr::MLV_NoSetterProperty:
+ Diag = diag::error_nosetter_property_assignment;
+ break;
}
if (NeedType)
Modified: cfe/trunk/test/SemaObjC/property-error-readonly-assign.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-error-readonly-assign.m?rev=59878&r1=59877&r2=59878&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-error-readonly-assign.m (original)
+++ cfe/trunk/test/SemaObjC/property-error-readonly-assign.m Sat Nov 22 14:25:50 2008
@@ -6,8 +6,16 @@
@property int ok;
@end
-void f0(A *a) {
+ at interface B
+ -(void) setOk:(int)arg;
+ -(int) x;
+ -(int) ok;
+ at end
+
+void f0(A *a, B* b) {
a.x = 10; // expected-error {{assigning to property with 'readonly' attribute not allowed}}
a.ok = 20;
+ b.x = 10; // expected-error {{setter method is needed to assign to object using property assignment syntax}}
+ b.ok = 20;
}
More information about the cfe-commits
mailing list