From: Fariborz Jahanian Date: Mon, 12 Nov 2007 22:29:28 +0000 (+0000) Subject: Patch to do statically typed ivar references. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=232220c6982e3a70d8f7fc06a011ead490a2f516;p=clang Patch to do statically typed ivar references. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44028 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp index ae8bb1ae57..d96a0486cf 100644 --- a/AST/StmtPrinter.cpp +++ b/AST/StmtPrinter.cpp @@ -383,6 +383,10 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { } void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { + if (Node->getBase()) { + PrintExpr(Node->getBase()); + OS << (Node->isArrow() ? "->" : "."); + } OS << Node->getDecl()->getName(); } diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index d51a29631b..8f816e67ef 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -519,9 +519,20 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, 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(BaseType.getCanonicalType())) + IFace = dyn_cast(BaseType)->getDecl(); + else + IFace = dyn_cast(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. diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 0a3caa7f88..b3279a0429 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1234,13 +1234,19 @@ class ObjCProtocolExpr : public Expr { 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; diff --git a/test/Sema/static-ivar-ref-1.m b/test/Sema/static-ivar-ref-1.m new file mode 100644 index 0000000000..d01a7fb6da --- /dev/null +++ b/test/Sema/static-ivar-ref-1.m @@ -0,0 +1,16 @@ +// 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; +}