diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-12-12 21:26:21 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-12-12 21:26:21 +0000 |
commit | 191dcd76046ea751f21aae008df21bb3468a2188 (patch) | |
tree | bd3bc2b20f38d6601eb76c9d9abb1289577151cd /lib/CodeGen/CGObjCMac.cpp | |
parent | 4224f061b7888b268cca363805df98e89261b6e6 (diff) |
patch to add a property from a protocol to a class that adopts the protocol.
(fixes radar 7466494).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91227 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index d4e0aa7fa4..d847cea389 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetData.h" #include <cstdio> @@ -905,6 +906,13 @@ protected: const ObjCContainerDecl *OCD, const ObjCCommonTypesHelper &ObjCTypes); + /// PushProtocolProperties - Push protocol's property on the input stack. + void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, + std::vector<llvm::Constant*> &Properties, + const Decl *Container, + const ObjCProtocolDecl *PROTO, + const ObjCCommonTypesHelper &ObjCTypes); + /// GetProtocolRef - Return a reference to the internal protocol /// description, creating an empty one if it has not been /// defined. The return value has type ProtocolPtrTy. @@ -1793,6 +1801,26 @@ CGObjCMac::EmitProtocolList(llvm::Twine Name, return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); } +void CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, + std::vector<llvm::Constant*> &Properties, + const Decl *Container, + const ObjCProtocolDecl *PROTO, + const ObjCCommonTypesHelper &ObjCTypes) { + std::vector<llvm::Constant*> Prop(2); + for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(), + E = PROTO->protocol_end(); P != E; ++P) + PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes); + for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(), + E = PROTO->prop_end(); I != E; ++I) { + const ObjCPropertyDecl *PD = *I; + if (!PropertySet.insert(PD->getIdentifier())) + continue; + Prop[0] = GetPropertyName(PD->getIdentifier()); + Prop[1] = GetPropertyTypeString(PD, Container); + Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop)); + } +} + /* struct _objc_property { const char * const name; @@ -1810,14 +1838,20 @@ llvm::Constant *CGObjCCommonMac::EmitPropertyList(llvm::Twine Name, const ObjCContainerDecl *OCD, const ObjCCommonTypesHelper &ObjCTypes) { std::vector<llvm::Constant*> Properties, Prop(2); + llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(), E = OCD->prop_end(); I != E; ++I) { const ObjCPropertyDecl *PD = *I; + PropertySet.insert(PD->getIdentifier()); Prop[0] = GetPropertyName(PD->getIdentifier()); Prop[1] = GetPropertyTypeString(PD, Container); Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop)); } + if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) + for (ObjCInterfaceDecl::protocol_iterator P = OID->protocol_begin(), + E = OID->protocol_end(); P != E; ++P) + PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes); // Return null for empty list. if (Properties.empty()) |