diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 42 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 46 |
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()); |