]> granicus.if.org Git - clang/commitdiff
Patch to do statically typed ivar references.
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 12 Nov 2007 22:29:28 +0000 (22:29 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 12 Nov 2007 22:29:28 +0000 (22:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44028 91177308-0d34-0410-b5e6-96231b3b80d8

AST/StmtPrinter.cpp
Sema/SemaExpr.cpp
include/clang/AST/Expr.h
test/Sema/static-ivar-ref-1.m [new file with mode: 0644]

index ae8bb1ae57925193b3e554db49847a8d295d77b7..d96a0486cf28d327ee649ae8dbb5595d2e55e529 100644 (file)
@@ -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();
 }
 
index d51a29631bf92619d8670859aa6353e14ac565b3..8f816e67ef42e9a5bfede4a0db529e228e76f601 100644 (file)
@@ -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<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.
index 0a3caa7f888a4cd526b3ea6e6f4170fa4f6ac92f..b3279a0429e4a78adfa0e76884d352f211ff8862 100644 (file)
@@ -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 (file)
index 0000000..d01a7fb
--- /dev/null
@@ -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;
+}