[cfe-commits] r150714 - /cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
Fariborz Jahanian
fjahanian at apple.com
Thu Feb 16 10:54:09 PST 2012
Author: fjahanian
Date: Thu Feb 16 12:54:09 2012
New Revision: 150714
URL: http://llvm.org/viewvc/llvm-project?rev=150714&view=rev
Log:
modern objc translator: meta-data generation for first
part of class meta-data.
Modified:
cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=150714&r1=150713&r2=150714&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Thu Feb 16 12:54:09 2012
@@ -5453,6 +5453,20 @@
}
}
+// Metadata flags
+enum MetaDataDlags {
+ CLS = 0x0,
+ CLS_META = 0x1,
+ CLS_ROOT = 0x2,
+ OBJC2_CLS_HIDDEN = 0x10,
+ CLS_EXCEPTION = 0x20,
+
+ /// (Obsolete) ARC-specific: this class has a .release_ivars method
+ CLS_HAS_IVAR_RELEASER = 0x40,
+ /// class was compiled with -fobjc-arr
+ CLS_COMPILED_BY_ARC = 0x80 // (1<<7)
+};
+
static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result,
unsigned int flags,
const std::string &InstanceStart,
@@ -5478,15 +5492,20 @@
// const uint8_t * const ivarLayout;
Result += "0, \n\t";
Result += "\""; Result += ClassName; Result += "\",\n\t";
+ bool metaclass = ((flags & CLS_META) != 0);
if (baseMethods.size() > 0) {
Result += "(const struct _method_list_t *)&";
- Result += "_OBJC_$_INSTANCE_METHODS_"; Result += ClassName;
+ if (metaclass)
+ Result += "_OBJC_$_CLASS_METHODS_";
+ else
+ Result += "_OBJC_$_INSTANCE_METHODS_";
+ Result += ClassName;
Result += ",\n\t";
}
else
Result += "0, \n\t";
- if (baseProtocols.size() > 0) {
+ if (!metaclass && baseProtocols.size() > 0) {
Result += "(const struct _objc_protocol_list *)&";
Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
Result += ",\n\t";
@@ -5494,7 +5513,7 @@
else
Result += "0, \n\t";
- if (ivars.size() > 0) {
+ if (!metaclass && ivars.size() > 0) {
Result += "(const struct _ivar_list_t *)&";
Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
Result += ",\n\t";
@@ -5504,7 +5523,7 @@
// weakIvarLayout
Result += "0, \n\t";
- if (Properties.size() > 0) {
+ if (!metaclass && Properties.size() > 0) {
Result += "(const struct _prop_list_t *)&";
Result += "_OBJC_CLASS_PROPERTIES_$_"; Result += ClassName;
Result += ",\n";
@@ -5825,19 +5844,17 @@
Result += "\t }\n};\n";
}
-// Metadata flags
-enum MetaDataDlags {
- CLS = 0x0,
- CLS_META = 0x1,
- CLS_ROOT = 0x2,
- OBJC2_CLS_HIDDEN = 0x10,
- CLS_EXCEPTION = 0x20,
-
- /// (Obsolete) ARC-specific: this class has a .release_ivars method
- CLS_HAS_IVAR_RELEASER = 0x40,
- /// class was compiled with -fobjc-arr
- CLS_COMPILED_BY_ARC = 0x80 // (1<<7)
-};
+/// hasObjCExceptionAttribute - Return true if this class or any super
+/// class has the __objc_exception__ attribute.
+/// FIXME. Move this to ASTContext.cpp as it is also used for IRGen.
+static bool hasObjCExceptionAttribute(ASTContext &Context,
+ const ObjCInterfaceDecl *OID) {
+ if (OID->hasAttr<ObjCExceptionAttr>())
+ return true;
+ if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
+ return hasObjCExceptionAttribute(Context, Super);
+ return false;
+}
void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
std::string &Result) {
@@ -5930,16 +5947,45 @@
CDecl->getNameAsString());
+ // Data for initializing _class_ro_t metaclass meta-data
+ uint32_t flags = CLS_META;
+ std::string InstanceSize;
+ std::string InstanceStart;
+
+
+ bool classIsHidden = CDecl->getVisibility() == HiddenVisibility;
+ if (classIsHidden)
+ flags |= OBJC2_CLS_HIDDEN;
+
+ if (!CDecl->getSuperClass())
+ // class is root
+ flags |= CLS_ROOT;
+ InstanceSize = "sizeof(struct _class_t)";
+ InstanceStart = InstanceSize;
+ Write__class_ro_t_initializer(Context, Result, flags,
+ InstanceStart, InstanceSize,
+ ClassMethods,
+ 0,
+ 0,
+ 0,
+ "_OBJC_METACLASS_RO_$_",
+ CDecl->getNameAsString());
+
+
// Data for initializing _class_ro_t meta-data
- uint32_t flags = CLS;
- // FIXME. condition for class visibility hidden
- // flags |= OBJC2_CLS_HIDDEN;
+ flags = CLS;
+ if (classIsHidden)
+ flags |= OBJC2_CLS_HIDDEN;
+
+ if (hasObjCExceptionAttribute(*Context, CDecl))
+ flags |= CLS_EXCEPTION;
+
if (!CDecl->getSuperClass())
// class is root
flags |= CLS_ROOT;
- std::string InstanceSize;
- std::string InstanceStart;
+ InstanceSize.clear();
+ InstanceStart.clear();
if (!ObjCSynthesizedStructs.count(CDecl)) {
InstanceSize = "0";
InstanceStart = "0";
More information about the cfe-commits
mailing list