Eliminate usage of ObjCSuperExpr used for

'super' as receiver of property or a setter/getter
methods. //rdar: //8525788

llvm-svn: 116483
This commit is contained in:
Fariborz Jahanian 2010-10-14 16:04:05 +00:00
parent b7fd763369
commit 681c0754d9
26 changed files with 273 additions and 152 deletions

View File

@ -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<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)
@ -243,13 +259,27 @@ public:
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) {
@ -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);
@ -338,6 +400,10 @@ public:
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 {

View File

@ -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, { })

View File

@ -121,7 +121,6 @@ def ObjCProtocolExpr : DStmt<Expr>;
def ObjCIvarRefExpr : DStmt<Expr>;
def ObjCPropertyRefExpr : DStmt<Expr>;
def ObjCImplicitSetterGetterRefExpr : DStmt<Expr>;
def ObjCSuperExpr : DStmt<Expr>;
def ObjCIsaExpr : DStmt<Expr>;
// Clang Extensions.

View File

@ -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,

View File

@ -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,

View File

@ -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; }

View File

@ -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:

View File

@ -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:

View File

@ -159,7 +159,6 @@ namespace {
void VisitObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *Node);
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
void VisitObjCSuperExpr(ObjCSuperExpr *Node);
};
}
@ -606,7 +605,10 @@ void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
DumpExpr(Node);
if (Node->isSuperReceiver())
OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"'
<< " super";
else
OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"';
}
@ -624,10 +626,7 @@ void StmtDumper::VisitObjCImplicitSetterGetterRefExpr(
else
OS << "(null)";
OS << "\"";
}
void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
DumpExpr(Node);
if (Node->isSuperReceiver())
OS << " super";
}

View File

@ -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();

View File

@ -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());

View File

@ -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:

View File

@ -122,12 +122,19 @@ static void CollectBlockDeclRefInfo(const Stmt *S, CGBlockInfo &Info) {
E->getReceiverKind() == ObjCMessageExpr::SuperInstance)
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:
else if (isa<ObjCSuperExpr>(S))
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);
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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:

View File

@ -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());

View File

@ -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();
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();
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());

View File

@ -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())

View File

@ -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,6 +353,11 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
ResTy = Getter->getSendResultType();
if (Super)
return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
MemberLoc,
SuperLoc, SuperType));
else
return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
MemberLoc, BaseExpr));
}
@ -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();
if (Super)
return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
Setter, MemberLoc, BaseExpr));
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

View File

@ -1889,11 +1889,23 @@ public:
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.
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())
@ -6188,17 +6210,13 @@ TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
E->getType(),
E->getSetterMethod(),
E->getLocation(),
Base.get());
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) {

View File

@ -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,6 +842,12 @@ void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
VisitExpr(E);
E->setProperty(cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
E->setLocation(ReadSourceLocation(Record, Idx));
E->SuperLoc = ReadSourceLocation(Record, Idx);
if (E->isSuperReceiver()) {
QualType T = Reader.GetType(Record[Idx++]);
E->BaseExprOrSuperType = T.getTypePtr();
}
else
E->setBase(Reader.ReadSubExpr());
}
@ -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;

View File

@ -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);

View File

@ -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.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());

View File

@ -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: