diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-02-12 18:51:23 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-02-12 18:51:23 +0000 |
commit | 01a0c3624aaa976ccba08b6cee1606521b8378d2 (patch) | |
tree | dd912ff232cd0dd3a8327903e7e912161f8c11e3 /lib/CodeGen/CGObjCMac.cpp | |
parent | df6b68c9487aed2042c7fc23db10a79f89083a11 (diff) |
Fix a bug whereby, an ivar used to synthesize a property belongs
to a base class (nonfragile abi ir gen bug).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64391 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 5286593ac4..103acab13a 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -677,7 +677,7 @@ private: /// the given ivar. /// llvm::GlobalVariable * ObjCIvarOffsetVariable(std::string &Name, - const NamedDecl *IDName, + const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar); /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, @@ -1600,6 +1600,26 @@ static int countInheritedIvars(const ObjCInterfaceDecl *OI) { return count; } +/// getInterfaceDeclForIvar - Get the interface declaration node where +/// this ivar is declared in. +/// FIXME. Ideally, this info should be in the ivar node. But currently +/// it is not and prevailing wisdom is that ASTs should not have more +/// info than is absolutely needed, even though this info reflects the +/// source language. +/// +static const ObjCInterfaceDecl *getInterfaceDeclForIvar( + const ObjCInterfaceDecl *OI, + const ObjCIvarDecl *IVD) { + if (!OI) + return 0; + assert(isa<ObjCInterfaceDecl>(OI) && "OI is not an interface"); + for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(), + E = OI->ivar_end(); I != E; ++I) + if ((*I)->getIdentifier() == IVD->getIdentifier()) + return OI; + return getInterfaceDeclForIvar(OI->getSuperClass(), IVD); +} + /* struct objc_ivar { char *ivar_name; @@ -3921,9 +3941,10 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( /// llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable( std::string &Name, - const NamedDecl *IDName, + const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar) { - Name += "\01_OBJC_IVAR_$_" + IDName->getNameAsString() + '.' + Name += "\01_OBJC_IVAR_$_" + + getInterfaceDeclForIvar(ID, Ivar)->getNameAsString() + '.' + Ivar->getNameAsString(); llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name); @@ -4298,7 +4319,7 @@ LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( unsigned CVRQualifiers) { assert(ObjectTy->isObjCInterfaceType() && "CGObjCNonFragileABIMac::EmitObjCValueForIvar"); - NamedDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl(); + ObjCInterfaceDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl(); std::string ExternalName; llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ExternalName, ID, Ivar); |