diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 30 | ||||
-rw-r--r-- | lib/AST/ExprClassification.cpp | 1 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 1 | ||||
-rw-r--r-- | lib/AST/StmtDumper.cpp | 15 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 12 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 12 | ||||
-rw-r--r-- | lib/Checker/GRExprEngine.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 1 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/StmtXML.cpp | 6 | ||||
-rw-r--r-- | lib/Rewrite/RewriteObjC.cpp | 52 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 42 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 46 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 20 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 1 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 17 |
20 files changed, 191 insertions, 112 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 708512ce46..98f0656ad1 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -2348,23 +2348,35 @@ Stmt::child_iterator ObjCIvarRefExpr::child_begin() { return &Base; } Stmt::child_iterator ObjCIvarRefExpr::child_end() { return &Base+1; } // ObjCPropertyRefExpr -Stmt::child_iterator ObjCPropertyRefExpr::child_begin() { return &Base; } -Stmt::child_iterator ObjCPropertyRefExpr::child_end() { return &Base+1; } +Stmt::child_iterator ObjCPropertyRefExpr::child_begin() +{ + if (BaseExprOrSuperType.is<Stmt*>()) { + // Hack alert! + return reinterpret_cast<Stmt**> (&BaseExprOrSuperType); + } + return child_iterator(); +} + +Stmt::child_iterator ObjCPropertyRefExpr::child_end() +{ return BaseExprOrSuperType.is<Stmt*>() ? + reinterpret_cast<Stmt**> (&BaseExprOrSuperType)+1 : + child_iterator(); +} // ObjCImplicitSetterGetterRefExpr Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_begin() { - // If this is accessing a class member, skip that entry. - if (Base) return &Base; - return &Base+1; + // If this is accessing a class member or super, skip that entry. + // Technically, 2nd condition is sufficient. But I want to be verbose + if (isSuperReceiver() || !Base) + return child_iterator(); + return &Base; } Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_end() { + if (isSuperReceiver() || !Base) + return child_iterator(); return &Base+1; } -// ObjCSuperExpr -Stmt::child_iterator ObjCSuperExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator ObjCSuperExpr::child_end() { return child_iterator(); } - // ObjCIsaExpr Stmt::child_iterator ObjCIsaExpr::child_begin() { return &Base; } Stmt::child_iterator ObjCIsaExpr::child_end() { return &Base+1; } diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index c9069f8707..0ab1402fa8 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -109,7 +109,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::CXXThrowExprClass: case Expr::ShuffleVectorExprClass: case Expr::IntegerLiteralClass: - case Expr::ObjCSuperExprClass: case Expr::CharacterLiteralClass: case Expr::AddrLabelExprClass: case Expr::CXXDeleteExprClass: diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 69a008fdc5..715d30ead0 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2468,7 +2468,6 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::ObjCIvarRefExprClass: case Expr::ObjCPropertyRefExprClass: case Expr::ObjCImplicitSetterGetterRefExprClass: - case Expr::ObjCSuperExprClass: case Expr::ObjCIsaExprClass: case Expr::ShuffleVectorExprClass: case Expr::BlockExprClass: diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index 5c236a45a6..8b3ad5a61f 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -159,7 +159,6 @@ namespace { void VisitObjCImplicitSetterGetterRefExpr( ObjCImplicitSetterGetterRefExpr *Node); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); - void VisitObjCSuperExpr(ObjCSuperExpr *Node); }; } @@ -606,8 +605,11 @@ void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { DumpExpr(Node); - - OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"'; + if (Node->isSuperReceiver()) + OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"' + << " super"; + else + OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"'; } void StmtDumper::VisitObjCImplicitSetterGetterRefExpr( @@ -624,11 +626,8 @@ void StmtDumper::VisitObjCImplicitSetterGetterRefExpr( else OS << "(null)"; OS << "\""; -} - -void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) { - DumpExpr(Node); - OS << " super"; + if (Node->isSuperReceiver()) + OS << " super"; } //===----------------------------------------------------------------------===// diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 2fc08dabf8..51289b2273 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -509,16 +509,21 @@ void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { } void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { - if (Node->getBase()) { + if (Node->isSuperReceiver()) + OS << "super."; + else if (Node->getBase()) { PrintExpr(Node->getBase()); OS << "."; } + OS << Node->getProperty()->getName(); } void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr( ObjCImplicitSetterGetterRefExpr *Node) { - if (Node->getBase()) { + if (Node->isSuperReceiver()) + OS << "super."; + else if (Node->getBase()) { PrintExpr(Node->getBase()); OS << "."; } @@ -1298,9 +1303,6 @@ void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { OS << "]"; } -void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) { - OS << "super"; -} void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { BlockDecl *BD = Node->getBlockDecl(); diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 607cf213db..3f17a2b471 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -863,6 +863,10 @@ void StmtProfiler::VisitObjCIvarRefExpr(ObjCIvarRefExpr *S) { void StmtProfiler::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *S) { VisitExpr(S); VisitDecl(S->getProperty()); + if (S->isSuperReceiver()) { + ID.AddBoolean(S->isSuperReceiver()); + VisitType(S->getSuperType()); + } } void StmtProfiler::VisitObjCImplicitSetterGetterRefExpr( @@ -871,6 +875,10 @@ void StmtProfiler::VisitObjCImplicitSetterGetterRefExpr( VisitDecl(S->getGetterMethod()); VisitDecl(S->getSetterMethod()); VisitDecl(S->getInterfaceDecl()); + if (S->isSuperReceiver()) { + ID.AddBoolean(S->isSuperReceiver()); + VisitType(S->getSuperType()); + } } void StmtProfiler::VisitObjCMessageExpr(ObjCMessageExpr *S) { @@ -879,10 +887,6 @@ void StmtProfiler::VisitObjCMessageExpr(ObjCMessageExpr *S) { VisitDecl(S->getMethodDecl()); } -void StmtProfiler::VisitObjCSuperExpr(ObjCSuperExpr *S) { - VisitExpr(S); -} - void StmtProfiler::VisitObjCIsaExpr(ObjCIsaExpr *S) { VisitExpr(S); ID.AddBoolean(S->isArrow()); diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 0c3a7bbc15..babea205be 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -830,7 +830,6 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, case Stmt::ObjCProtocolExprClass: case Stmt::ObjCSelectorExprClass: case Stmt::ObjCStringLiteralClass: - case Stmt::ObjCSuperExprClass: case Stmt::ParenListExprClass: case Stmt::PredefinedExprClass: case Stmt::ShuffleVectorExprClass: diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 35a2ada974..ca78781ec6 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -122,12 +122,19 @@ static void CollectBlockDeclRefInfo(const Stmt *S, CGBlockInfo &Info) { E->getReceiverKind() == ObjCMessageExpr::SuperInstance) Info.NeedsObjCSelf = true; } - - // Getter/setter uses may also cause implicit super references, - // which we can check for with: - else if (isa<ObjCSuperExpr>(S)) - Info.NeedsObjCSelf = true; - + else if (const ObjCPropertyRefExpr *PE = dyn_cast<ObjCPropertyRefExpr>(S)) { + // Getter/setter uses may also cause implicit super references, + // which we can check for with: + if (PE->isSuperReceiver()) + Info.NeedsObjCSelf = true; + } + else if (const ObjCImplicitSetterGetterRefExpr *IE = + dyn_cast<ObjCImplicitSetterGetterRefExpr>(S)) { + // Getter/setter uses may also cause implicit super references, + // which we can check for with: + if (IE->isSuperReceiver()) + Info.NeedsObjCSelf = true; + } else if (isa<CXXThisExpr>(S)) Info.CXXThisRef = cast<CXXThisExpr>(S); } diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index e4ed5d64d9..186c5ff428 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -552,9 +552,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E)); case Expr::ObjCImplicitSetterGetterRefExprClass: return EmitObjCKVCRefLValue(cast<ObjCImplicitSetterGetterRefExpr>(E)); - case Expr::ObjCSuperExprClass: - return EmitObjCSuperExprLValue(cast<ObjCSuperExpr>(E)); - case Expr::StmtExprClass: return EmitStmtExprLValue(cast<StmtExpr>(E)); case Expr::UnaryOperatorClass: @@ -2082,10 +2079,6 @@ LValue CodeGenFunction::EmitObjCKVCRefLValue( return LValue::MakeKVCRef(E, E->getType().getCVRQualifiers()); } -LValue CodeGenFunction::EmitObjCSuperExprLValue(const ObjCSuperExpr *E) { - return EmitUnsupportedLValue(E, "use of super"); -} - LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) { // Can only get l-value for message expression returning aggregate type RValue RV = EmitAnyExprToTemp(E); diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 8abcbea5d0..7c2dfe8b23 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -534,7 +534,7 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp, // FIXME: Split it into two separate routines. if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) { Selector S = E->getProperty()->getGetterName(); - if (isa<ObjCSuperExpr>(E->getBase())) + if (E->isSuperReceiver()) return EmitObjCSuperPropertyGet(E, S, Return); return CGM.getObjCRuntime(). GenerateMessageSend(*this, Return, Exp->getType(), S, @@ -548,7 +548,7 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp, if (KE->getInterfaceDecl()) { const ObjCInterfaceDecl *OID = KE->getInterfaceDecl(); Receiver = CGM.getObjCRuntime().GetClass(Builder, OID); - } else if (isa<ObjCSuperExpr>(KE->getBase())) + } else if (KE->isSuperReceiver()) return EmitObjCSuperPropertyGet(KE, S, Return); else Receiver = EmitScalarExpr(KE->getBase()); @@ -586,7 +586,7 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp, // FIXME: Split it into two separate routines. if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) { Selector S = E->getProperty()->getSetterName(); - if (isa<ObjCSuperExpr>(E->getBase())) { + if (E->isSuperReceiver()) { EmitObjCSuperPropertySet(E, S, Src); return; } @@ -605,7 +605,7 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp, if (E->getInterfaceDecl()) { const ObjCInterfaceDecl *OID = E->getInterfaceDecl(); Receiver = CGM.getObjCRuntime().GetClass(Builder, OID); - } else if (isa<ObjCSuperExpr>(E->getBase())) { + } else if (E->isSuperReceiver()) { EmitObjCSuperPropertySet(E, S, Src); return; } else diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index cb9274388e..4e64319ae5 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1439,7 +1439,6 @@ public: LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E); LValue EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E); LValue EmitObjCKVCRefLValue(const ObjCImplicitSetterGetterRefExpr *E); - LValue EmitObjCSuperExprLValue(const ObjCSuperExpr *E); LValue EmitStmtExprLValue(const StmtExpr *E); LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E); LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E); diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 1cf3211b70..36c908b099 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -1610,7 +1610,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::ObjCProtocolExprClass: case Expr::ObjCSelectorExprClass: case Expr::ObjCStringLiteralClass: - case Expr::ObjCSuperExprClass: case Expr::OffsetOfExprClass: case Expr::PredefinedExprClass: case Expr::ShuffleVectorExprClass: diff --git a/lib/Frontend/StmtXML.cpp b/lib/Frontend/StmtXML.cpp index b6607349d7..fdd40b15c9 100644 --- a/lib/Frontend/StmtXML.cpp +++ b/lib/Frontend/StmtXML.cpp @@ -150,7 +150,6 @@ namespace { void VisitObjCImplicitSetterGetterRefExpr( ObjCImplicitSetterGetterRefExpr *Node); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); - void VisitObjCSuperExpr(ObjCSuperExpr *Node); #endif }; } @@ -428,11 +427,6 @@ void StmtXML::VisitObjCImplicitSetterGetterRefExpr( Doc.addAttribute("Setter", Setter ? Setter->getSelector().getAsString().c_str() : "(null)"); } -void StmtXML::VisitObjCSuperExpr(ObjCSuperExpr *Node) { - DumpExpr(Node); - Doc.addAttribute("super", "1"); -} - void StmtXML::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { DumpExpr(Node); Doc.addAttribute("kind", Node->getDecl()->getDeclKindName()); diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp index 339b7d1640..8532bc7f13 100644 --- a/lib/Rewrite/RewriteObjC.cpp +++ b/lib/Rewrite/RewriteObjC.cpp @@ -1209,6 +1209,9 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr * QualType Ty; Selector Sel; Stmt *Receiver; + bool Super = false; + QualType SuperTy; + SourceLocation SuperLocation; // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr or ObjCImplicitSetterGetterRefExpr. // This allows us to reuse all the fun and games in SynthMessageExpr(). if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(BinOp->getLHS())) { @@ -1216,14 +1219,26 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr * OMD = PDecl->getSetterMethodDecl(); Ty = PDecl->getType(); Sel = PDecl->getSetterName(); - Receiver = PropRefExpr->getBase(); + Super = PropRefExpr->isSuperReceiver(); + if (!Super) + Receiver = PropRefExpr->getBase(); + else { + SuperTy = PropRefExpr->getSuperType(); + SuperLocation = PropRefExpr->getSuperLocation(); + } } else if (ObjCImplicitSetterGetterRefExpr *ImplicitRefExpr = dyn_cast<ObjCImplicitSetterGetterRefExpr>(BinOp->getLHS())) { OMD = ImplicitRefExpr->getSetterMethod(); Sel = OMD->getSelector(); Ty = ImplicitRefExpr->getType(); - Receiver = ImplicitRefExpr->getBase(); + Super = ImplicitRefExpr->isSuperReceiver(); + if (!Super) + Receiver = ImplicitRefExpr->getBase(); + else { + SuperTy = ImplicitRefExpr->getSuperType(); + SuperLocation = ImplicitRefExpr->getSuperLocation(); + } } assert(OMD && "RewritePropertyOrImplicitSetter - null OMD"); @@ -1236,13 +1251,13 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr * Receiver = PropGetters[Exp]; ObjCMessageExpr *MsgExpr; - if (isa<ObjCSuperExpr>(Receiver)) + if (Super) MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), /*FIXME?*/SourceLocation(), - Receiver->getLocStart(), + SuperLocation, /*IsInstanceSuper=*/true, - cast<Expr>(Receiver)->getType(), + SuperTy, Sel, OMD, &ExprVec[0], 1, /*FIXME:*/SourceLocation()); @@ -1272,20 +1287,35 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) { ObjCMethodDecl *OMD = 0; QualType Ty; Selector Sel; + bool Super = false; + QualType SuperTy; + SourceLocation SuperLocation; if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(PropOrGetterRefExpr)) { ObjCPropertyDecl *PDecl = PropRefExpr->getProperty(); OMD = PDecl->getGetterMethodDecl(); - Receiver = PropRefExpr->getBase(); Ty = PDecl->getType(); Sel = PDecl->getGetterName(); + Super = PropRefExpr->isSuperReceiver(); + if (!Super) + Receiver = PropRefExpr->getBase(); + else { + SuperTy = PropRefExpr->getSuperType(); + SuperLocation = PropRefExpr->getSuperLocation(); + } } else if (ObjCImplicitSetterGetterRefExpr *ImplicitRefExpr = dyn_cast<ObjCImplicitSetterGetterRefExpr>(PropOrGetterRefExpr)) { OMD = ImplicitRefExpr->getGetterMethod(); - Receiver = ImplicitRefExpr->getBase(); Sel = OMD->getSelector(); Ty = ImplicitRefExpr->getType(); + Super = ImplicitRefExpr->isSuperReceiver(); + if (!Super) + Receiver = ImplicitRefExpr->getBase(); + else { + SuperTy = ImplicitRefExpr->getSuperType(); + SuperLocation = ImplicitRefExpr->getSuperLocation(); + } } assert (OMD && "RewritePropertyOrImplicitGetter - OMD is null"); @@ -1296,13 +1326,13 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) { Receiver = PropGetters[Exp]; ObjCMessageExpr *MsgExpr; - if (isa<ObjCSuperExpr>(Receiver)) + if (Super) MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), - /*FIXME:*/SourceLocation(), - Receiver->getLocStart(), + /*FIXME?*/SourceLocation(), + SuperLocation, /*IsInstanceSuper=*/true, - cast<Expr>(Receiver)->getType(), + SuperTy, Sel, OMD, 0, 0, /*FIXME:*/SourceLocation()); 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()); diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index f361f0d260..2f4bddf468 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -122,7 +122,6 @@ namespace clang { void VisitObjCImplicitSetterGetterRefExpr( ObjCImplicitSetterGetterRefExpr *E); void VisitObjCMessageExpr(ObjCMessageExpr *E); - void VisitObjCSuperExpr(ObjCSuperExpr *E); void VisitObjCIsaExpr(ObjCIsaExpr *E); void VisitObjCForCollectionStmt(ObjCForCollectionStmt *); @@ -843,7 +842,13 @@ void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { VisitExpr(E); E->setProperty(cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++]))); E->setLocation(ReadSourceLocation(Record, Idx)); - E->setBase(Reader.ReadSubExpr()); + E->SuperLoc = ReadSourceLocation(Record, Idx); + if (E->isSuperReceiver()) { + QualType T = Reader.GetType(Record[Idx++]); + E->BaseExprOrSuperType = T.getTypePtr(); + } + else + E->setBase(Reader.ReadSubExpr()); } void ASTStmtRea |