}
void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
+ if (Node->getBase()) {
+ PrintExpr(Node->getBase());
+ OS << (Node->isArrow() ? "->" : ".");
+ }
OS << Node->getDecl()->getName();
}
if (ret.isNull())
return true;
return new OCUVectorElementExpr(ret, BaseExpr, Member, MemberLoc);
- } else
- return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion,
- SourceRange(MemberLoc));
+ } else if (BaseType->isObjcInterfaceType()) {
+ ObjcInterfaceDecl *IFace;
+ if (isa<ObjcInterfaceType>(BaseType.getCanonicalType()))
+ IFace = dyn_cast<ObjcInterfaceType>(BaseType)->getDecl();
+ else
+ IFace = dyn_cast<ObjcQualifiedInterfaceType>(BaseType)
+ ->getInterfaceType()->getDecl();
+ ObjcInterfaceDecl *clsDeclared;
+ if (ObjcIvarDecl *IV = IFace->lookupInstanceVariable(&Member, clsDeclared))
+ return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr,
+ OpKind==tok::arrow);
+ }
+ return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion,
+ SourceRange(MemberLoc));
}
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
class ObjCIvarRefExpr : public Expr {
class ObjcIvarDecl *D;
SourceLocation Loc;
+ Expr *Base;
+ bool IsArrow; // True if this is "X->F", false if this is "X.F".
+
public:
- ObjCIvarRefExpr(ObjcIvarDecl *d, QualType t, SourceLocation l) :
- Expr(ObjCIvarRefExprClass, t), D(d), Loc(l) {}
+ ObjCIvarRefExpr(ObjcIvarDecl *d, QualType t, SourceLocation l, Expr *base=0,
+ bool arrow = false) :
+ Expr(ObjCIvarRefExprClass, t), D(d), Loc(l), Base(base), IsArrow(arrow) {}
ObjcIvarDecl *getDecl() { return D; }
const ObjcIvarDecl *getDecl() const { return D; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+ Expr *const getBase() const { return Base; }
+ const bool isArrow() const { return IsArrow; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIvarRefExprClass;
--- /dev/null
+// RUN: clang -ast-print %s
+
+@interface current
+{
+ int ivar;
+ int ivar1;
+ int ivar2;
+}
+@end
+
+current *pc;
+
+int foo()
+{
+ return pc->ivar2 + (*pc).ivar + pc->ivar1;
+}