From 8ac2d449820fd0df00fcbde5bf82165c1f49854d Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 14 Oct 2010 16:04:05 +0000 Subject: [PATCH] Eliminate usage of ObjCSuperExpr used for 'super' as receiver of property or a setter/getter methods. //rdar: //8525788 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116483 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprObjC.h | 113 +++++++++++++++------- include/clang/AST/RecursiveASTVisitor.h | 1 - include/clang/Basic/StmtNodes.td | 1 - include/clang/Sema/Sema.h | 4 +- include/clang/Serialization/ASTBitCodes.h | 2 - lib/AST/Expr.cpp | 30 ++++-- lib/AST/ExprClassification.cpp | 1 - lib/AST/ExprConstant.cpp | 1 - lib/AST/StmtDumper.cpp | 15 ++- lib/AST/StmtPrinter.cpp | 12 ++- lib/AST/StmtProfile.cpp | 12 ++- lib/Checker/GRExprEngine.cpp | 1 - lib/CodeGen/CGBlocks.cpp | 19 ++-- lib/CodeGen/CGExpr.cpp | 7 -- lib/CodeGen/CGObjC.cpp | 8 +- lib/CodeGen/CodeGenFunction.h | 1 - lib/CodeGen/Mangle.cpp | 1 - lib/Frontend/StmtXML.cpp | 6 -- lib/Rewrite/RewriteObjC.cpp | 52 +++++++--- lib/Sema/SemaExpr.cpp | 11 ++- lib/Sema/SemaExprObjC.cpp | 42 +++++--- lib/Sema/TreeTransform.h | 46 ++++++--- lib/Serialization/ASTReaderStmt.cpp | 20 ++-- lib/Serialization/ASTWriter.cpp | 1 - lib/Serialization/ASTWriterStmt.cpp | 17 ++-- tools/libclang/CXCursor.cpp | 1 - 26 files changed, 273 insertions(+), 152 deletions(-) diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 15b70075cb..407a64938b 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -229,13 +229,29 @@ class ObjCPropertyRefExpr : public Expr { private: ObjCPropertyDecl *AsProperty; SourceLocation IdLoc; - Stmt *Base; + + /// \brief When the receiver in property access is 'super', this is + /// the location of the 'super' keyword. + SourceLocation SuperLoc; + + /// \brief When the receiver in property access is 'super', this is + /// the type associated with 'super' keyword. A null type indicates + /// that this is not a 'super' receiver. + llvm::PointerUnion BaseExprOrSuperType; + public: ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, SourceLocation l, Expr *base) : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false, base->isValueDependent()), - AsProperty(PD), IdLoc(l), Base(base) { + AsProperty(PD), IdLoc(l), BaseExprOrSuperType(base) { + } + + ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, + SourceLocation l, SourceLocation sl, QualType st) + : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false, false), + AsProperty(PD), IdLoc(l), SuperLoc(sl), + BaseExprOrSuperType(st.getTypePtr()) { } explicit ObjCPropertyRefExpr(EmptyShell Empty) @@ -243,13 +259,27 @@ public: ObjCPropertyDecl *getProperty() const { return AsProperty; } - const Expr *getBase() const { return cast(Base); } - Expr *getBase() { return cast(Base); } + const Expr *getBase() const { + return cast(BaseExprOrSuperType.get()); + } + Expr *getBase() { + return cast(BaseExprOrSuperType.get()); + } SourceLocation getLocation() const { return IdLoc; } + + SourceLocation getSuperLocation() const { return SuperLoc; } + QualType getSuperType() const { + Type *t = BaseExprOrSuperType.get(); + return QualType(t, 0); + } + bool isSuperReceiver() const { return BaseExprOrSuperType.is(); } virtual SourceRange getSourceRange() const { - return SourceRange(getBase()->getLocStart(), IdLoc); + return SourceRange( + (BaseExprOrSuperType.is() ? getBase()->getLocStart() + : getSuperLocation()), + IdLoc); } static bool classof(const Stmt *T) { @@ -263,8 +293,10 @@ public: private: friend class ASTStmtReader; void setProperty(ObjCPropertyDecl *D) { AsProperty = D; } - void setBase(Expr *base) { Base = base; } + void setBase(Expr *base) { BaseExprOrSuperType = base; } void setLocation(SourceLocation L) { IdLoc = L; } + void setSuperLocation(SourceLocation Loc) { SuperLoc = Loc; } + void setSuperType(QualType T) { BaseExprOrSuperType = T.getTypePtr(); } }; /// ObjCImplicitSetterGetterRefExpr - A dot-syntax expression to access two @@ -292,10 +324,22 @@ class ObjCImplicitSetterGetterRefExpr : public Expr { // FIXME: Swizzle these into a single pointer. Stmt *Base; ObjCInterfaceDecl *InterfaceDecl; - /// Location of the receiver class in the dot syntax notation + /// \brief Location of the receiver class in the dot syntax notation /// used to call a class method setter/getter. SourceLocation ClassLoc; + /// \brief When the receiver in dot-syntax expression is 'super', + /// this is the location of the 'super' keyword. + SourceLocation SuperLoc; + + /// \brief When the receiver in dot-syntax expression is 'super', this is + /// the type associated with 'super' keyword. + QualType SuperTy; + + /// \brief When the receiver in dot-syntax expression is 'super', this is + /// set to true. + bool IsSuper:1; + public: ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, @@ -305,7 +349,22 @@ public: base->isValueDependent()), Setter(setter), Getter(getter), MemberLoc(l), Base(base), InterfaceDecl(0), ClassLoc(SourceLocation()) { + IsSuper = false; } + + ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, + QualType t, + ObjCMethodDecl *setter, + SourceLocation l, + SourceLocation sl, + QualType st) + : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false, + false), + Setter(setter), Getter(getter), MemberLoc(l), + InterfaceDecl(0), ClassLoc(SourceLocation()), + SuperLoc(sl), SuperTy(st), IsSuper(true) { + } + ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, ObjCMethodDecl *setter, @@ -313,6 +372,7 @@ public: : Expr(ObjCImplicitSetterGetterRefExprClass, t, false, false), Setter(setter), Getter(getter), MemberLoc(l), Base(0), InterfaceDecl(C), ClassLoc(CL) { + IsSuper = false; } explicit ObjCImplicitSetterGetterRefExpr(EmptyShell Empty) : Expr(ObjCImplicitSetterGetterRefExprClass, Empty){} @@ -325,6 +385,8 @@ public: void setInterfaceDecl(ObjCInterfaceDecl *D) { InterfaceDecl = D; } virtual SourceRange getSourceRange() const { + if (isSuperReceiver()) + return SourceRange(getSuperLocation(), MemberLoc); if (Base) return SourceRange(getBase()->getLocStart(), MemberLoc); return SourceRange(ClassLoc, MemberLoc); @@ -337,6 +399,10 @@ public: void setLocation(SourceLocation L) { MemberLoc = L; } SourceLocation getClassLoc() const { return ClassLoc; } void setClassLoc(SourceLocation L) { ClassLoc = L; } + + SourceLocation getSuperLocation() const { return SuperLoc; } + QualType getSuperType() const { return SuperTy; } + bool isSuperReceiver() const { return IsSuper; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCImplicitSetterGetterRefExprClass; @@ -346,6 +412,12 @@ public: // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); + +private: + friend class ASTStmtReader; + void setSuperLocation(SourceLocation Loc) { SuperLoc = Loc; } + void setSuperType(QualType T) { SuperTy = T; } + void setSuperReceiver(bool bv) { IsSuper = bv; } }; /// \brief An expression that sends a message to the given Objective-C @@ -738,33 +810,6 @@ public: const_arg_iterator arg_end() const { return getArgs() + NumArgs; } }; -/// ObjCSuperExpr - Represents the "super" expression in Objective-C, -/// which refers to the object on which the current method is executing. -/// -/// FIXME: This class is intended for removal, once its remaining -/// clients have been altered to represent "super" internally. -class ObjCSuperExpr : public Expr { - SourceLocation Loc; -public: - ObjCSuperExpr(SourceLocation L, QualType Type) - : Expr(ObjCSuperExprClass, Type, false, false), Loc(L) { } - explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {} - - SourceLocation getLoc() const { return Loc; } - void setLoc(SourceLocation L) { Loc = L; } - - virtual SourceRange getSourceRange() const { return SourceRange(Loc); } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCSuperExprClass; - } - static bool classof(const ObjCSuperExpr *) { return true; } - - // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); -}; - /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. /// (similiar in spirit to MemberExpr). class ObjCIsaExpr : public Expr { diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 83a3d145e2..cb617f14e0 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1835,7 +1835,6 @@ DEF_TRAVERSE_STMT(ObjCMessageExpr, { }) DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { }) DEF_TRAVERSE_STMT(ObjCProtocolExpr, { }) DEF_TRAVERSE_STMT(ObjCSelectorExpr, { }) -DEF_TRAVERSE_STMT(ObjCSuperExpr, { }) DEF_TRAVERSE_STMT(ParenExpr, { }) DEF_TRAVERSE_STMT(ParenListExpr, { }) DEF_TRAVERSE_STMT(PredefinedExpr, { }) diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 94702841d3..53beb98eea 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -121,7 +121,6 @@ def ObjCProtocolExpr : DStmt; def ObjCIvarRefExpr : DStmt; def ObjCPropertyRefExpr : DStmt; def ObjCImplicitSetterGetterRefExpr : DStmt; -def ObjCSuperExpr : DStmt; def ObjCIsaExpr : DStmt; // Clang Extensions. diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index b1cd5628a7..6021cf76a3 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3786,7 +3786,9 @@ public: HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, DeclarationName MemberName, - SourceLocation MemberLoc); + SourceLocation MemberLoc, + SourceLocation SuperLoc, QualType SuperType, + bool Super); ExprResult ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 8628d74ff1..6e9658bfff 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -830,8 +830,6 @@ namespace clang { EXPR_OBJC_KVC_REF_EXPR, /// \brief An ObjCMessageExpr record. EXPR_OBJC_MESSAGE_EXPR, - /// \brief An ObjCSuperExpr record. - EXPR_OBJC_SUPER_EXPR, /// \brief An ObjCIsa Expr record. EXPR_OBJC_ISA, 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()) { + // Hack alert! + return reinterpret_cast (&BaseExprOrSuperType); + } + return child_iterator(); +} + +Stmt::child_iterator ObjCPropertyRefExpr::child_end() +{ return BaseExprOrSuperType.is() ? + reinterpret_cast (&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(S)) - Info.NeedsObjCSelf = true; - + else if (const ObjCPropertyRefExpr *PE = dyn_cast(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(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(S)) Info.CXXThisRef = cast(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(E)); case Expr::ObjCImplicitSetterGetterRefExprClass: return EmitObjCKVCRefLValue(cast(E)); - case Expr::ObjCSuperExprClass: - return EmitObjCSuperExprLValue(cast(E)); - case Expr::StmtExprClass: return EmitStmtExprLValue(cast(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(Exp)) { Selector S = E->getProperty()->getGetterName(); - if (isa(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(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(Exp)) { Selector S = E->getProperty()->getSetterName(); - if (isa(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(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(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(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(Receiver)) + if (Super) MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), /*FIXME?*/SourceLocation(), - Receiver->getLocStart(), + SuperLocation, /*IsInstanceSuper=*/true, - cast(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(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(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(Receiver)) + if (Super) MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), - /*FIXME:*/SourceLocation(), - Receiver->getLocStart(), + /*FIXME?*/SourceLocation(), + SuperLocation, /*IsInstanceSuper=*/true, - cast(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(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(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(); 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::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) { template ExprResult TreeTransform::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 ExprResult TreeTransform::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,20 +6207,16 @@ TreeTransform::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 -ExprResult -TreeTransform::TransformObjCSuperExpr(ObjCSuperExpr *E) { - // Can never occur in a dependent context. - return SemaRef.Owned(E->Retain()); -} - template ExprResult TreeTransform::TransformObjCIsaExpr(ObjCIsaExpr *E) { 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(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 ASTStmtReader::VisitObjCImplicitSetterGetterRefExpr( @@ -858,6 +863,9 @@ void ASTStmtReader::VisitObjCImplicitSetterGetterRefExpr( E->setBase(Reader.ReadSubExpr()); E->setLocation(ReadSourceLocation(Record, Idx)); E->setClassLoc(ReadSourceLocation(Record, Idx)); + E->SuperLoc = ReadSourceLocation(Record, Idx); + E->SuperTy = Reader.GetType(Record[Idx++]); + E->IsSuper = Record[Idx++]; } void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { @@ -898,11 +906,6 @@ void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { E->setArg(I, Reader.ReadSubExpr()); } -void ASTStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) { - VisitExpr(E); - E->setLoc(ReadSourceLocation(Record, Idx)); -} - void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { VisitStmt(S); S->setElement(Reader.ReadSubStmt()); @@ -1631,9 +1634,6 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { S = ObjCMessageExpr::CreateEmpty(*Context, Record[ASTStmtReader::NumExprFields]); break; - case EXPR_OBJC_SUPER_EXPR: - S = new (Context) ObjCSuperExpr(Empty); - break; case EXPR_OBJC_ISA: S = new (Context) ObjCIsaExpr(Empty); break; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index f26731caea..eae47db44e 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -592,7 +592,6 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_OBJC_PROPERTY_REF_EXPR); RECORD(EXPR_OBJC_KVC_REF_EXPR); RECORD(EXPR_OBJC_MESSAGE_EXPR); - RECORD(EXPR_OBJC_SUPER_EXPR); RECORD(STMT_OBJC_FOR_COLLECTION); RECORD(STMT_OBJC_CATCH); RECORD(STMT_OBJC_FINALLY); diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 3905ad6896..489d186973 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -103,7 +103,6 @@ namespace clang { void VisitObjCImplicitSetterGetterRefExpr( ObjCImplicitSetterGetterRefExpr *E); void VisitObjCMessageExpr(ObjCMessageExpr *E); - void VisitObjCSuperExpr(ObjCSuperExpr *E); void VisitObjCIsaExpr(ObjCIsaExpr *E); // Objective-C Statements @@ -824,7 +823,12 @@ void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { VisitExpr(E); Writer.AddDeclRef(E->getProperty(), Record); Writer.AddSourceLocation(E->getLocation(), Record); - Writer.AddStmt(E->getBase()); + Writer.AddSourceLocation(E->getSuperLocation(), Record); + if (E->isSuperReceiver()) + Writer.AddTypeRef(E->getSuperType(), Record); + else + Writer.AddStmt(E->getBase()); + Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR; } @@ -839,6 +843,9 @@ void ASTStmtWriter::VisitObjCImplicitSetterGetterRefExpr( Writer.AddStmt(E->getBase()); Writer.AddSourceLocation(E->getLocation(), Record); Writer.AddSourceLocation(E->getClassLoc(), Record); + Writer.AddSourceLocation(E->getSuperLocation(), Record); + Writer.AddTypeRef(E->getSuperType(), Record); + Record.push_back(E->isSuperReceiver()); Code = serialization::EXPR_OBJC_KVC_REF_EXPR; } @@ -879,12 +886,6 @@ void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) { Code = serialization::EXPR_OBJC_MESSAGE_EXPR; } -void ASTStmtWriter::VisitObjCSuperExpr(ObjCSuperExpr *E) { - VisitExpr(E); - Writer.AddSourceLocation(E->getLoc(), Record); - Code = serialization::EXPR_OBJC_SUPER_EXPR; -} - void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { VisitStmt(S); Writer.AddStmt(S->getElement()); diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 0db477498a..52594dcf6b 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -153,7 +153,6 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) { case Stmt::ObjCSelectorExprClass: case Stmt::ObjCProtocolExprClass: case Stmt::ObjCImplicitSetterGetterRefExprClass: - case Stmt::ObjCSuperExprClass: case Stmt::ObjCIsaExprClass: case Stmt::ShuffleVectorExprClass: case Stmt::BlockExprClass: -- 2.40.0