From: Fariborz Jahanian Date: Sat, 13 Dec 2008 22:20:28 +0000 (+0000) Subject: Patch for ObjCIvarRefExpr containing the field X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aaa63a761c6671a08e3f4f463435b72739fa194b;p=clang Patch for ObjCIvarRefExpr containing the field matching the storage layout for this ivar git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60996 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index f83ac4a7af..8f9bc2f01c 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -353,6 +353,7 @@ public: void CollectObjCIvars(std::vector &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, diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 6cf01bc3aa..22848b1c57 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -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) diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index e3e4548f64..f22b5b435b 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -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(*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) diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp index 9b6207be2b..aea3d99f19 100644 --- a/lib/AST/StmtSerialization.cpp +++ b/lib/AST/StmtSerialization.cpp @@ -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; } diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index e605065848..f955782ffd 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -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); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 264b85b69c..98afb0f701 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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(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();