]> granicus.if.org Git - clang/commitdiff
Patch for ObjCIvarRefExpr containing the field
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 13 Dec 2008 22:20:28 +0000 (22:20 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 13 Dec 2008 22:20:28 +0000 (22:20 +0000)
matching the storage layout for this ivar

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60996 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
include/clang/AST/ExprObjC.h
lib/AST/DeclObjC.cpp
lib/AST/StmtSerialization.cpp
lib/CodeGen/CGObjC.cpp
lib/Sema/SemaExpr.cpp

index f83ac4a7af5453b199605bfa3bf7ce033e6151b7..8f9bc2f01c64b20c0892054c68ab979ea0a02422 100644 (file)
@@ -353,6 +353,7 @@ public:
   void CollectObjCIvars(std::vector<FieldDecl*> &Fields);
   void setRecordForDecl(RecordDecl *Decl) { RecordForDecl = Decl; }
   RecordDecl *getRecordForDecl() const { return RecordForDecl; }
+  RecordDecl *getRecordForDecl() { return RecordForDecl; }
   
   typedef ObjCIvarDecl * const *ivar_iterator;
   ivar_iterator ivar_begin() const { return Ivars; }
@@ -383,7 +384,7 @@ public:
    
   void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars,
                                    SourceLocation RBracLoc);
-  
+  FieldDecl *lookupFieldDeclForIvar(ASTContext &Context, ObjCIvarDecl *ivar);
   void addLayoutToClass(ASTContext &Context);
 
   void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
index 6cf01bc3aaa668b46fe25583b96bcb330378b0de..22848b1c570b452fd3dab62a56db816520a3ef8c 100644 (file)
@@ -155,19 +155,24 @@ public:
 
 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
 class ObjCIvarRefExpr : public Expr {
-  class ObjCIvarDecl *D; 
+  class ObjCIvarDecl *D;
+  FieldDecl *FD;
   SourceLocation Loc;
   Stmt *Base;
   bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
   bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
   
 public:
-  ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l, Expr *base=0, 
+  ObjCIvarRefExpr(ObjCIvarDecl *d, FieldDecl *fd,
+                  QualType t, SourceLocation l, Expr *base=0, 
                   bool arrow = false, bool freeIvar = false) : 
-    Expr(ObjCIvarRefExprClass, t), D(d), Loc(l), Base(base), IsArrow(arrow),
+    Expr(ObjCIvarRefExprClass, t), D(d), FD(fd),
+    Loc(l), Base(base), IsArrow(arrow),
     IsFreeIvar(freeIvar) {}
   
   ObjCIvarDecl *getDecl() { return D; }
+  FieldDecl *getFieldDecl() { return FD; }
+  const FieldDecl *getFieldDecl() const { return FD; }
   const ObjCIvarDecl *getDecl() const { return D; }
   virtual SourceRange getSourceRange() const { 
     return isFreeIvar() ? SourceRange(Loc)
index e3e4548f644dd9023f28fdca7d2da97e74dee70a..f22b5b435b068da5f4566880e92223ed4e8a338f 100644 (file)
@@ -363,7 +363,21 @@ void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
   setLocEnd(RBrac);
 }
 
-/// addInstanceVariablesToClass - produces layout info. for the class for its
+/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
+/// storage which matches this 'ivar'.
+///
+FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context, 
+                                                     ObjCIvarDecl *ivar) {
+  assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
+  DeclarationName Member = ivar->getDeclName();
+  DeclContext::lookup_result Lookup = RecordForDecl->lookup(Context, Member);
+  assert((Lookup.first != Lookup.second) && "field decl not found");
+  FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
+  assert(MemberDecl && "field decl not found");
+  return MemberDecl;
+}
+
+/// addLayoutToClass - produces layout info. for the class for its
 /// ivars and all those inherited.
 ///
 void ObjCInterfaceDecl::addLayoutToClass(ASTContext &Context)
index 9b6207be2b70eaba08e3a359c5a0fc3fc7bc19ab..aea3d99f197553af9f19f5f88ca4a7a298aa3d2c 100644 (file)
@@ -1162,7 +1162,7 @@ void ObjCIvarRefExpr::EmitImpl(Serializer& S) const {
 ObjCIvarRefExpr* ObjCIvarRefExpr::CreateImpl(Deserializer& D, ASTContext& C) {
   SourceLocation Loc = SourceLocation::ReadVal(D);
   QualType T = QualType::ReadVal(D);
-  ObjCIvarRefExpr* dr = new ObjCIvarRefExpr(NULL,T,Loc);
+  ObjCIvarRefExpr* dr = new ObjCIvarRefExpr(NULL,NULL,T,Loc);
   D.ReadPtr(dr->D,false);  
   return dr;
 }
index e605065848d478e6bcc628a7237cd49beba7a7b2..f955782ffdc45a68547674a8546a0ea4b20653fa 100644 (file)
@@ -272,7 +272,9 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
     DeclRefExpr Base(Self, Self->getType(), Loc);
     ParmVarDecl *ArgDecl = OMD->getParamDecl(0);
     DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
-    ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base,
+    ObjCInterfaceDecl *OI = IMP->getClassInterface();
+    FieldDecl *FD = OI->lookupFieldDeclForIvar(getContext(), Ivar);
+    ObjCIvarRefExpr IvarRef(Ivar, FD, Ivar->getType(), Loc, &Base,
                             true, true);
     BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
                           Ivar->getType(), Loc);
index 264b85b69cb2c82b67276a75811c3406d6f23b63..98afb0f701d052ddb7fc5257535b3f646b2e0015 100644 (file)
@@ -418,11 +418,12 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
     if (SD == 0 || SD->isDefinedOutsideFunctionOrMethod()) {
       ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
       if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II)) {
+        FieldDecl *FD = IFace->lookupFieldDeclForIvar(Context, IV);
         // FIXME: This should use a new expr for a direct reference, don't turn
         // this into Self->ivar, just return a BareIVarExpr or something.
         IdentifierInfo &II = Context.Idents.get("self");
         ExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false);
-        return new ObjCIvarRefExpr(IV, IV->getType(), Loc, 
+        return new ObjCIvarRefExpr(IV, FD, IV->getType(), Loc, 
                                  static_cast<Expr*>(SelfExpr.Val), true, true);
       }
     }
@@ -1264,9 +1265,11 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
   // Handle access to Objective-C instance variables, such as "Obj->ivar" and
   // (*Obj).ivar.
   if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) {
-    if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member))
-      return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, 
+    if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member)) {
+      FieldDecl *FD = IFTy->getDecl()->lookupFieldDeclForIvar(Context, IV);
+      return new ObjCIvarRefExpr(IV, FD, IV->getType(), MemberLoc, BaseExpr, 
                                  OpKind == tok::arrow);
+    }
     return Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
              << IFTy->getDecl()->getDeclName() << &Member
              << BaseExpr->getSourceRange();