aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-02-12 18:51:23 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-02-12 18:51:23 +0000
commit01a0c3624aaa976ccba08b6cee1606521b8378d2 (patch)
treedd912ff232cd0dd3a8327903e7e912161f8c11e3 /lib/CodeGen/CGObjCMac.cpp
parentdf6b68c9487aed2042c7fc23db10a79f89083a11 (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.cpp29
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);