[cfe-commits] r128435 - in /cfe/trunk: lib/CodeGen/CGObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaObjCProperty.cpp test/SemaObjCXX/references.mm
Fariborz Jahanian
fjahanian at apple.com
Mon Mar 28 16:47:18 PDT 2011
Author: fjahanian
Date: Mon Mar 28 18:47:18 2011
New Revision: 128435
URL: http://llvm.org/viewvc/llvm-project?rev=128435&view=rev
Log:
Implements property of reference types. Adding
an executable test to llvm test suite.
// rdar://9070460.
Modified:
cfe/trunk/lib/CodeGen/CGObjC.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/lib/Sema/SemaObjCProperty.cpp
cfe/trunk/test/SemaObjCXX/references.mm
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=128435&r1=128434&r2=128435&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon Mar 28 18:47:18 2011
@@ -294,11 +294,17 @@
else {
LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
Ivar, 0);
- CodeGenTypes &Types = CGM.getTypes();
- RValue RV = EmitLoadOfLValue(LV, IVART);
- RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
+ if (PD->getType()->isReferenceType()) {
+ RValue RV = RValue::get(LV.getAddress());
+ EmitReturnOfRValue(RV, PD->getType());
+ }
+ else {
+ CodeGenTypes &Types = CGM.getTypes();
+ RValue RV = EmitLoadOfLValue(LV, IVART);
+ RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
Types.ConvertType(PD->getType())));
- EmitReturnOfRValue(RV, PD->getType());
+ EmitReturnOfRValue(RV, PD->getType());
+ }
}
}
@@ -436,7 +442,10 @@
ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
DeclRefExpr Base(Self, Self->getType(), VK_RValue, Loc);
ParmVarDecl *ArgDecl = *OMD->param_begin();
- DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), VK_LValue, Loc);
+ QualType T = ArgDecl->getType();
+ if (T->isReferenceType())
+ T = cast<ReferenceType>(T)->getPointeeType();
+ DeclRefExpr Arg(ArgDecl, T, VK_LValue, Loc);
ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true);
// The property type can differ from the ivar type in some situations with
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=128435&r1=128434&r2=128435&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Mar 28 18:47:18 2011
@@ -7413,6 +7413,21 @@
return false;
}
+static bool IsConstProperty(Expr *E, Sema &S) {
+ if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) {
+ const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(E);
+ if (PropExpr->isImplicitProperty()) return false;
+
+ ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty();
+ QualType T = PDecl->getType();
+ if (T->isReferenceType())
+ T = cast<ReferenceType>(T)->getPointeeType();
+ CanQualType CT = S.Context.getCanonicalType(T);
+ return CT.isConstQualified();
+ }
+ return false;
+}
+
static bool IsReadonlyMessage(Expr *E, Sema &S) {
if (E->getStmtClass() != Expr::MemberExprClass)
return false;
@@ -7435,6 +7450,8 @@
&Loc);
if (IsLV == Expr::MLV_Valid && IsReadonlyProperty(E, S))
IsLV = Expr::MLV_ReadonlyProperty;
+ else if (Expr::MLV_ConstQualified && IsConstProperty(E, S))
+ IsLV = Expr::MLV_Valid;
else if (IsLV == Expr::MLV_ClassTemporary && IsReadonlyMessage(E, S))
IsLV = Expr::MLV_InvalidMessageExpression;
if (IsLV == Expr::MLV_Valid)
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=128435&r1=128434&r2=128435&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Mar 28 18:47:18 2011
@@ -428,6 +428,7 @@
if (DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
QualType ResTy = PD->getType();
+ ResTy = ResTy.getNonLValueExprType(Context);
Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=128435&r1=128434&r2=128435&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Mon Mar 28 18:47:18 2011
@@ -45,11 +45,7 @@
!(Attributes & ObjCDeclSpec::DQ_PR_copy)));
TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
- QualType T = TSI->getType();
- if (T->isReferenceType()) {
- Diag(AtLoc, diag::error_reference_property);
- return 0;
- }
+
// Proceed with constructing the ObjCPropertDecls.
ObjCContainerDecl *ClassDecl =
cast<ObjCContainerDecl>(ClassCategory);
@@ -404,13 +400,16 @@
if (!PropertyIvar)
PropertyIvar = PropertyId;
QualType PropType = Context.getCanonicalType(property->getType());
+ QualType PropertyIvarType = PropType;
+ if (PropType->isReferenceType())
+ PropertyIvarType = cast<ReferenceType>(PropType)->getPointeeType();
// Check that this is a previously declared 'ivar' in 'IDecl' interface
ObjCInterfaceDecl *ClassDeclared;
Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
if (!Ivar) {
Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl,
PropertyLoc, PropertyLoc, PropertyIvar,
- PropType, /*Dinfo=*/0,
+ PropertyIvarType, /*Dinfo=*/0,
ObjCIvarDecl::Private,
(Expr *)0, true);
ClassImpDecl->addDecl(Ivar);
@@ -433,19 +432,19 @@
QualType IvarType = Context.getCanonicalType(Ivar->getType());
// Check that type of property and its ivar are type compatible.
- if (PropType != IvarType) {
+ if (PropertyIvarType != IvarType) {
bool compat = false;
- if (isa<ObjCObjectPointerType>(PropType)
+ if (isa<ObjCObjectPointerType>(PropertyIvarType)
&& isa<ObjCObjectPointerType>(IvarType))
compat =
Context.canAssignObjCInterfaces(
- PropType->getAs<ObjCObjectPointerType>(),
+ PropertyIvarType->getAs<ObjCObjectPointerType>(),
IvarType->getAs<ObjCObjectPointerType>());
else {
SourceLocation Loc = PropertyIvarLoc;
if (Loc.isInvalid())
Loc = PropertyLoc;
- compat = (CheckAssignmentConstraints(Loc, PropType, IvarType)
+ compat = (CheckAssignmentConstraints(Loc, PropertyIvarType, IvarType)
== Compatible);
}
if (!compat) {
@@ -460,7 +459,7 @@
// FIXME! Rules for properties are somewhat different that those
// for assignments. Use a new routine to consolidate all cases;
// specifically for property redeclarations as well as for ivars.
- QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType();
+ QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType();
QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
if (lhsType != rhsType &&
lhsType->isArithmeticType()) {
@@ -539,7 +538,10 @@
SelfExpr, true, true);
ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
ParmVarDecl *Param = (*P);
- Expr *rhs = new (Context) DeclRefExpr(Param, Param->getType(),
+ QualType T = Param->getType();
+ if (T->isReferenceType())
+ T = cast<ReferenceType>(T)->getPointeeType();
+ Expr *rhs = new (Context) DeclRefExpr(Param, T,
VK_LValue, SourceLocation());
ExprResult Res = BuildBinOp(S, lhs->getLocEnd(),
BO_Assign, lhs, rhs);
Modified: cfe/trunk/test/SemaObjCXX/references.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/references.mm?rev=128435&r1=128434&r2=128435&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/references.mm (original)
+++ cfe/trunk/test/SemaObjCXX/references.mm Mon Mar 28 18:47:18 2011
@@ -9,7 +9,7 @@
@interface A
@property (assign) T p0;
- at property (assign) T& p1; // expected-error {{property of reference type is not supported}}
+ at property (assign) T& p1;
@end
int f0(const T& t) {
@@ -21,7 +21,7 @@
}
int f2(A *a) {
- return f0(a.p1); // expected-error {{property 'p1' not found on object of type 'A *'}}
+ return f0(a.p1);
}
// PR7740
More information about the cfe-commits
mailing list