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<Stmt*, Type*> 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)
ObjCPropertyDecl *getProperty() const { return AsProperty; }
- const Expr *getBase() const { return cast<Expr>(Base); }
- Expr *getBase() { return cast<Expr>(Base); }
+ const Expr *getBase() const {
+ return cast<Expr>(BaseExprOrSuperType.get<Stmt*>());
+ }
+ Expr *getBase() {
+ return cast<Expr>(BaseExprOrSuperType.get<Stmt*>());
+ }
SourceLocation getLocation() const { return IdLoc; }
+
+ SourceLocation getSuperLocation() const { return SuperLoc; }
+ QualType getSuperType() const {
+ Type *t = BaseExprOrSuperType.get<Type*>();
+ return QualType(t, 0);
+ }
+ bool isSuperReceiver() const { return BaseExprOrSuperType.is<Type*>(); }
virtual SourceRange getSourceRange() const {
- return SourceRange(getBase()->getLocStart(), IdLoc);
+ return SourceRange(
+ (BaseExprOrSuperType.is<Stmt*>() ? getBase()->getLocStart()
+ : getSuperLocation()),
+ IdLoc);
}
static bool classof(const Stmt *T) {
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
// 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,
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,
: 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){}
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);
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;
// 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
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 {
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, { })
def ObjCIvarRefExpr : DStmt<Expr>;
def ObjCPropertyRefExpr : DStmt<Expr>;
def ObjCImplicitSetterGetterRefExpr : DStmt<Expr>;
-def ObjCSuperExpr : DStmt<Expr>;
def ObjCIsaExpr : DStmt<Expr>;
// Clang Extensions.
HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
Expr *BaseExpr,
DeclarationName MemberName,
- SourceLocation MemberLoc);
+ SourceLocation MemberLoc,
+ SourceLocation SuperLoc, QualType SuperType,
+ bool Super);
ExprResult
ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
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,
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; }
case Expr::CXXThrowExprClass:
case Expr::ShuffleVectorExprClass:
case Expr::IntegerLiteralClass:
- case Expr::ObjCSuperExprClass:
case Expr::CharacterLiteralClass:
case Expr::AddrLabelExprClass:
case Expr::CXXDeleteExprClass:
case Expr::ObjCIvarRefExprClass:
case Expr::ObjCPropertyRefExprClass:
case Expr::ObjCImplicitSetterGetterRefExprClass:
- case Expr::ObjCSuperExprClass:
case Expr::ObjCIsaExprClass:
case Expr::ShuffleVectorExprClass:
case Expr::BlockExprClass:
void VisitObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *Node);
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
- void VisitObjCSuperExpr(ObjCSuperExpr *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(
else
OS << "(null)";
OS << "\"";
-}
-
-void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
- DumpExpr(Node);
- OS << " super";
+ if (Node->isSuperReceiver())
+ OS << " super";
}
//===----------------------------------------------------------------------===//
}
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 << ".";
}
OS << "]";
}
-void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
- OS << "super";
-}
void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
BlockDecl *BD = Node->getBlockDecl();
void StmtProfiler::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *S) {
VisitExpr(S);
VisitDecl(S->getProperty());
+ if (S->isSuperReceiver()) {
+ ID.AddBoolean(S->isSuperReceiver());
+ VisitType(S->getSuperType());
+ }
}
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) {
VisitDecl(S->getMethodDecl());
}
-void StmtProfiler::VisitObjCSuperExpr(ObjCSuperExpr *S) {
- VisitExpr(S);
-}
-
void StmtProfiler::VisitObjCIsaExpr(ObjCIsaExpr *S) {
VisitExpr(S);
ID.AddBoolean(S->isArrow());
case Stmt::ObjCProtocolExprClass:
case Stmt::ObjCSelectorExprClass:
case Stmt::ObjCStringLiteralClass:
- case Stmt::ObjCSuperExprClass:
case Stmt::ParenListExprClass:
case Stmt::PredefinedExprClass:
case Stmt::ShuffleVectorExprClass:
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);
}
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:
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);
// 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,
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());
// 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;
}
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
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);
case Expr::ObjCProtocolExprClass:
case Expr::ObjCSelectorExprClass:
case Expr::ObjCStringLiteralClass:
- case Expr::ObjCSuperExprClass:
case Expr::OffsetOfExprClass:
case Expr::PredefinedExprClass:
case Expr::ShuffleVectorExprClass:
void VisitObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *Node);
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
- void VisitObjCSuperExpr(ObjCSuperExpr *Node);
#endif
};
}
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());
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())) {
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");
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());
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");
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());
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.
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 &&
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())
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();
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(),
// 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.
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.
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)
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
/// 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));
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())
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())
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) {
void VisitObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *E);
void VisitObjCMessageExpr(ObjCMessageExpr *E);
- void VisitObjCSuperExpr(ObjCSuperExpr *E);
void VisitObjCIsaExpr(ObjCIsaExpr *E);
void VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
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 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) {
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());
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;
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);
void VisitObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *E);
void VisitObjCMessageExpr(ObjCMessageExpr *E);
- void VisitObjCSuperExpr(ObjCSuperExpr *E);
void VisitObjCIsaExpr(ObjCIsaExpr *E);
// Objective-C Statements
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;
}
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;
}
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());
case Stmt::ObjCSelectorExprClass:
case Stmt::ObjCProtocolExprClass:
case Stmt::ObjCImplicitSetterGetterRefExprClass:
- case Stmt::ObjCSuperExprClass:
case Stmt::ObjCIsaExprClass:
case Stmt::ShuffleVectorExprClass:
case Stmt::BlockExprClass: