aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-01-24 21:21:53 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-01-24 21:21:53 +0000
commit84394a50e307e2f056e270e1eeadd4f26913cd1e (patch)
tree4d2b1619da7be8a8974badf04b8c1963170b71e7 /lib/CodeGen/CGObjCMac.cpp
parentf30208ad5b334e93582e846a2a0c92f38a607b8a (diff)
Patch to build class meta-data for each implementation
of class in objc2's nonfragile abi. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62935 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r--lib/CodeGen/CGObjCMac.cpp53
1 files changed, 44 insertions, 9 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index a7c6aee562..be3a0bdd00 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -551,9 +551,10 @@ private:
unsigned InstanceStart,
unsigned InstanceSize,
const ObjCImplementationDecl *ID);
- void BuildClassMetaData(std::string &ClassName,
- llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
- llvm::Constant *ClassRoGV);
+ llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
+ llvm::Constant *IsAGV,
+ llvm::Constant *SuperClassGV,
+ llvm::Constant *ClassRoGV);
@@ -3161,13 +3162,16 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
/// struct class_ro_t *ro;
/// }
///
-void CGObjCNonFragileABIMac::BuildClassMetaData(std::string &ClassName,
+llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
+ std::string &ClassName,
llvm::Constant *IsAGV,
llvm::Constant *SuperClassGV,
llvm::Constant *ClassRoGV) {
std::vector<llvm::Constant*> Values(5);
Values[0] = IsAGV;
- Values[1] = SuperClassGV;
+ Values[1] = SuperClassGV
+ ? SuperClassGV
+ : llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar
Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar
Values[4] = ClassRoGV; // &CLASS_RO_GV
@@ -3187,7 +3191,7 @@ void CGObjCNonFragileABIMac::BuildClassMetaData(std::string &ClassName,
UsedGlobals.push_back(GV);
// FIXME! why?
GV->setAlignment(32);
-
+ return GV;
}
void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
@@ -3245,7 +3249,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
&CGM.getModule());
UsedGlobals.push_back(IsAGV);
} else {
- // Not a root.
+ // Has a root. Current class is not a root.
std::string RootClassName =
ID->getClassInterface()->getSuperClass()->getNameAsString();
std::string SuperClassName = ObjCMetaClassName + RootClassName;
@@ -3263,8 +3267,39 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
InstanceStart,
InstanceSize,ID);
- std::string MetaClassName = ObjCMetaClassName + ClassName;
- BuildClassMetaData(MetaClassName, IsAGV, SuperClassGV, CLASS_RO_GV);
+ std::string TClassName = ObjCMetaClassName + ClassName;
+ llvm::GlobalVariable *MetaTClass =
+ BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV);
+
+ // Metadata for the class
+ flags = CLS;
+ if (ID->getClassInterface() && !ID->getClassInterface()->getSuperClass()) {
+ flags |= CLS_ROOT;
+ SuperClassGV = 0;
+ }
+ else {
+ // Has a root. Current class is not a root.
+ std::string RootClassName =
+ ID->getClassInterface()->getSuperClass()->getNameAsString();
+ std::string SuperClassName = ObjCClassName + RootClassName;
+ SuperClassGV = CGM.getModule().getGlobalVariable(SuperClassName);
+ if (!SuperClassGV)
+ SuperClassGV =
+ new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false,
+ llvm::GlobalValue::ExternalLinkage,
+ 0,
+ SuperClassName,
+ &CGM.getModule());
+ UsedGlobals.push_back(SuperClassGV);
+
+ }
+
+ CLASS_RO_GV = BuildClassRoTInitializer(flags,
+ 0,
+ 0,ID);
+
+ TClassName = ObjCClassName + ClassName;
+ BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV);
}
/* *** */