diff options
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 2e8ab29..fb920f0 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()) @@ -2507,8 +2541,11 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // through finally. CGF.PushCleanupBlock(FinallyBlock); - CGF.ObjCEHValueStack.push_back(0); - + if (CGF.ObjCEHValueStack.empty()) + CGF.ObjCEHValueStack.push_back(0); + // If This is a nested @try, caught exception is that of enclosing @try. + else + CGF.ObjCEHValueStack.push_back(CGF.ObjCEHValueStack.back()); // Allocate memory for the exception data and rethrow pointer. llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, "exceptiondata.ptr"); @@ -4134,23 +4171,19 @@ void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { "\01L_OBJC_LABEL_CLASS_$", "__DATA, __objc_classlist, regular, no_dead_strip"); - bool hasWeakImport = false; for (unsigned i = 0; i < DefinedClasses.size(); i++) { llvm::GlobalValue *IMPLGV = DefinedClasses[i]; if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) continue; IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); - hasWeakImport = true; } - if (hasWeakImport) { - for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) { - llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i]; - if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) - continue; - IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); - } - } + for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) { + llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i]; + if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) + continue; + IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); + } AddModuleClassList(DefinedNonLazyClasses, "\01L_OBJC_LABEL_NONLAZY_CLASS_$", @@ -4437,9 +4470,12 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) Root = Super; IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString()); + if (Root->hasAttr<WeakImportAttr>()) + IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); // work on super class metadata symbol. std::string SuperClassName = - ObjCMetaClassName + ID->getClassInterface()->getSuperClass()->getNameAsString(); + ObjCMetaClassName + + ID->getClassInterface()->getSuperClass()->getNameAsString(); SuperClassGV = GetClassGlobal(SuperClassName); if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>()) SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); |