summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r--lib/CodeGen/CGObjCMac.cpp62
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);
OpenPOWER on IntegriCloud