aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaExpr.cpp11
-rw-r--r--lib/Sema/SemaExprObjC.cpp42
-rw-r--r--lib/Sema/TreeTransform.h46
3 files changed, 71 insertions, 28 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 609465c505..10225b6138 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3307,7 +3307,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
return ExprError();
return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
- MemberLoc, BaseExpr));
+ MemberLoc,
+ BaseExpr));
}
if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
// Check the use of this method.
@@ -3337,7 +3338,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
if (!IsArrow)
if (const ObjCObjectPointerType *OPT =
BaseType->getAsObjCInterfacePointerType())
- return HandleExprPropertyRefExpr(OPT, BaseExpr, MemberName, MemberLoc);
+ return HandleExprPropertyRefExpr(OPT, BaseExpr, MemberName, MemberLoc,
+ SourceLocation(), QualType(), false);
// Handle the following exceptional case (*Obj).isa.
if (!IsArrow &&
@@ -6018,7 +6020,10 @@ static bool IsReadonlyProperty(Expr *E, Sema &S) {
if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) {
const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(E);
if (ObjCPropertyDecl *PDecl = PropExpr->getProperty()) {
- QualType BaseType = PropExpr->getBase()->getType();
+ QualType BaseType = PropExpr->isSuperReceiver() ?
+ PropExpr->getSuperType() :
+ PropExpr->getBase()->getType();
+
if (const ObjCObjectPointerType *OPT =
BaseType->getAsObjCInterfacePointerType())
if (ObjCInterfaceDecl *IFace = OPT->getInterfaceDecl())
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index a9c7a727f1..055edd9710 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -336,7 +336,9 @@ ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
ExprResult Sema::
HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
Expr *BaseExpr, DeclarationName MemberName,
- SourceLocation MemberLoc) {
+ SourceLocation MemberLoc,
+ SourceLocation SuperLoc, QualType SuperType,
+ bool Super) {
const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
ObjCInterfaceDecl *IFace = IFaceT->getDecl();
IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
@@ -351,8 +353,13 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
ResTy = Getter->getSendResultType();
- return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
- MemberLoc, BaseExpr));
+ if (Super)
+ return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
+ MemberLoc,
+ SuperLoc, SuperType));
+ else
+ return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
+ MemberLoc, BaseExpr));
}
// Check protocols on qualified interfaces.
for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
@@ -361,9 +368,14 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
// Check whether we can reference this property.
if (DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
-
+ if (Super)
return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
- MemberLoc, BaseExpr));
+ MemberLoc,
+ SuperLoc, SuperType));
+ else
+ return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
+ MemberLoc,
+ BaseExpr));
}
// If that failed, look for an "implicit" property by seeing if the nullary
// selector is implemented.
@@ -407,8 +419,15 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
if (Getter) {
QualType PType;
PType = Getter->getSendResultType();
- return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
- Setter, MemberLoc, BaseExpr));
+ if (Super)
+ return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
+ Setter, MemberLoc,
+ SuperLoc, SuperType));
+ else
+ return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
+ Setter, MemberLoc,
+ BaseExpr));
+
}
// Attempt to correct for typos in property names.
@@ -422,7 +441,8 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
ObjCPropertyDecl *Property = Res.getAsSingle<ObjCPropertyDecl>();
Diag(Property->getLocation(), diag::note_previous_decl)
<< Property->getDeclName();
- return HandleExprPropertyRefExpr(OPT, BaseExpr, TypoResult, MemberLoc);
+ return HandleExprPropertyRefExpr(OPT, BaseExpr, TypoResult, MemberLoc,
+ SuperLoc, SuperType, Super);
}
Diag(MemberLoc, diag::err_property_not_found)
@@ -453,11 +473,11 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
QualType T =
Context.getObjCInterfaceType(CurMethod->getClassInterface());
T = Context.getObjCObjectPointerType(T);
- Expr *SuperExpr = new (Context) ObjCSuperExpr(receiverNameLoc, T);
return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(),
- SuperExpr, &propertyName,
- propertyNameLoc);
+ /*BaseExpr*/0, &propertyName,
+ propertyNameLoc,
+ receiverNameLoc, T, true);
}
// Otherwise, if this is a class method, try dispatching to our
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index be8295ea1e..0a57c3536f 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1886,14 +1886,26 @@ public:
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildObjCImplicitSetterGetterRefExpr(
ObjCMethodDecl *Getter,
- QualType T,
+ QualType T,
ObjCMethodDecl *Setter,
SourceLocation NameLoc,
- Expr *Base) {
+ Expr *Base,
+ SourceLocation SuperLoc,
+ QualType SuperTy,
+ bool Super) {
// Since these expressions can only be value-dependent, we do not need to
// perform semantic analysis again.
- return Owned(
- new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T,
+ if (Super)
+ return Owned(
+ new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T,
+ Setter,
+ NameLoc,
+ SuperLoc,
+ SuperTy));
+ else
+ return Owned(
+ new (getSema().Context) ObjCImplicitSetterGetterRefExpr(
+ Getter, T,
Setter,
NameLoc,
Base));
@@ -6146,6 +6158,11 @@ TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+ // 'super' never changes. Property never changes. Just retain the existing
+ // expression.
+ if (E->isSuperReceiver())
+ return SemaRef.Owned(E->Retain());
+
// Transform the base expression.
ExprResult Base = getDerived().TransformExpr(E->getBase());
if (Base.isInvalid())
@@ -6166,6 +6183,11 @@ template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *E) {
+ // If this implicit setter/getter refers to super, it cannot have any
+ // dependent parts. Just retain the existing declaration.
+ if (E->isSuperReceiver())
+ return SemaRef.Owned(E->Retain());
+
// If this implicit setter/getter refers to class methods, it cannot have any
// dependent parts. Just retain the existing declaration.
if (E->getInterfaceDecl())
@@ -6185,22 +6207,18 @@ TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
return getDerived().RebuildObjCImplicitSetterGetterRefExpr(
E->getGetterMethod(),
- E->getType(),
+ E->getType(),
E->getSetterMethod(),
- E->getLocation(),
- Base.get());
+ E->getLocation(),
+ Base.get(),
+ E->getSuperLocation(),
+ E->getSuperType(),
+ E->isSuperReceiver());
}
template<typename Derived>
ExprResult
-TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
- // Can never occur in a dependent context.
- return SemaRef.Owned(E->Retain());
-}
-
-template<typename Derived>
-ExprResult
TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
// Transform the base expression.
ExprResult Base = getDerived().TransformExpr(E->getBase());