modern objc translator: category metadata related
patch. llvm-svn: 150825
This commit is contained in:
parent
0c1941cb05
commit
f20550543f
|
@ -5597,6 +5597,61 @@ static void Write_class_t(ASTContext *Context, std::string &Result,
|
||||||
Result += ",\n};\n";
|
Result += ",\n};\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context,
|
||||||
|
std::string &Result,
|
||||||
|
StringRef CatName,
|
||||||
|
StringRef ClassName,
|
||||||
|
ArrayRef<ObjCMethodDecl *> InstanceMethods,
|
||||||
|
ArrayRef<ObjCMethodDecl *> ClassMethods,
|
||||||
|
ArrayRef<ObjCProtocolDecl *> RefedProtocols,
|
||||||
|
ArrayRef<ObjCPropertyDecl *> ClassProperties) {
|
||||||
|
WriteModernMetadataDeclarations(Result);
|
||||||
|
Result += "\nstatic struct _category_t ";
|
||||||
|
Result += "_OBJC_$_CATEGORY_";
|
||||||
|
Result += ClassName; Result += "_$_"; Result += CatName;
|
||||||
|
Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
|
||||||
|
Result += "{\n";
|
||||||
|
Result += "\t\""; Result += ClassName; Result += "\",\n";
|
||||||
|
Result += "\t&"; Result += "OBJC_CLASS_$_"; Result += ClassName;
|
||||||
|
Result += ",\n";
|
||||||
|
if (InstanceMethods.size() > 0) {
|
||||||
|
Result += "\t(const struct _method_list_t *)&";
|
||||||
|
Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
|
||||||
|
Result += ClassName; Result += "_$_"; Result += CatName;
|
||||||
|
Result += ",\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result += "\t0,\n";
|
||||||
|
|
||||||
|
if (ClassMethods.size() > 0) {
|
||||||
|
Result += "\t(const struct _method_list_t *)&";
|
||||||
|
Result += "_OBJC_$_CATEGORY_CLASS_METHODS_";
|
||||||
|
Result += ClassName; Result += "_$_"; Result += CatName;
|
||||||
|
Result += ",\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result += "\t0,\n";
|
||||||
|
|
||||||
|
if (RefedProtocols.size() > 0) {
|
||||||
|
Result += "\t(const struct _protocol_list_t *)&";
|
||||||
|
Result += "_OBJC_CATEGORY_PROTOCOLS_$_";
|
||||||
|
Result += ClassName; Result += "_$_"; Result += CatName;
|
||||||
|
Result += ",\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result += "\t0,\n";
|
||||||
|
|
||||||
|
if (ClassProperties.size() > 0) {
|
||||||
|
Result += "\t(const struct _prop_list_t *)&"; Result += "_OBJC_$_PROP_LIST_";
|
||||||
|
Result += ClassName; Result += "_$_"; Result += CatName;
|
||||||
|
Result += ",\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result += "\t0,\n";
|
||||||
|
|
||||||
|
Result += "};\n";
|
||||||
|
}
|
||||||
|
|
||||||
static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
|
static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
|
||||||
ASTContext *Context, std::string &Result,
|
ASTContext *Context, std::string &Result,
|
||||||
ArrayRef<ObjCMethodDecl *> Methods,
|
ArrayRef<ObjCMethodDecl *> Methods,
|
||||||
|
@ -6113,6 +6168,23 @@ void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
|
||||||
}
|
}
|
||||||
Result += "};\n";
|
Result += "};\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CatDefCount > 0) {
|
||||||
|
Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
|
||||||
|
Result += llvm::utostr(CatDefCount); Result += "]";
|
||||||
|
Result +=
|
||||||
|
" __attribute__((used, section (\"__DATA, __objc_catlist,"
|
||||||
|
"regular,no_dead_strip\")))= {\n";
|
||||||
|
for (int i = 0; i < CatDefCount; i++) {
|
||||||
|
Result += "\t&_OBJC_$_CATEGORY_";
|
||||||
|
Result +=
|
||||||
|
CategoryImplementation[i]->getClassInterface()->getNameAsString();
|
||||||
|
Result += "_$_";
|
||||||
|
Result += CategoryImplementation[i]->getNameAsString();
|
||||||
|
Result += ",\n";
|
||||||
|
}
|
||||||
|
Result += "};\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
|
/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
|
||||||
|
@ -6121,15 +6193,15 @@ void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
|
||||||
std::string &Result) {
|
std::string &Result) {
|
||||||
ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
|
ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
|
||||||
// Find category declaration for this implementation.
|
// Find category declaration for this implementation.
|
||||||
ObjCCategoryDecl *CDecl;
|
ObjCCategoryDecl *CDecl=0;
|
||||||
for (CDecl = ClassDecl->getCategoryList(); CDecl;
|
for (CDecl = ClassDecl->getCategoryList(); CDecl;
|
||||||
CDecl = CDecl->getNextClassCategory())
|
CDecl = CDecl->getNextClassCategory())
|
||||||
if (CDecl->getIdentifier() == IDecl->getIdentifier())
|
if (CDecl->getIdentifier() == IDecl->getIdentifier())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
std::string FullCategoryName = ClassDecl->getNameAsString();
|
std::string FullCategoryName = ClassDecl->getNameAsString();
|
||||||
FullCategoryName += '_';
|
FullCategoryName += "_$_";
|
||||||
FullCategoryName += IDecl->getNameAsString();
|
FullCategoryName += CDecl->getNameAsString();
|
||||||
|
|
||||||
// Build _objc_method_list for class's instance methods if needed
|
// Build _objc_method_list for class's instance methods if needed
|
||||||
SmallVector<ObjCMethodDecl *, 32>
|
SmallVector<ObjCMethodDecl *, 32>
|
||||||
|
@ -6154,79 +6226,55 @@ void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
|
||||||
if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
|
if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
|
||||||
InstanceMethods.push_back(Setter);
|
InstanceMethods.push_back(Setter);
|
||||||
}
|
}
|
||||||
RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
|
|
||||||
true, "CATEGORY_", FullCategoryName.c_str(),
|
|
||||||
Result);
|
|
||||||
|
|
||||||
// Build _objc_method_list for class's class methods if needed
|
Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
|
||||||
RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
|
"_OBJC_$_CATEGORY_INSTANCE_METHODS_",
|
||||||
false, "CATEGORY_", FullCategoryName.c_str(),
|
FullCategoryName, true);
|
||||||
Result);
|
|
||||||
|
SmallVector<ObjCMethodDecl *, 32>
|
||||||
|
ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
|
||||||
|
|
||||||
|
Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
|
||||||
|
"_OBJC_$_CATEGORY_CLASS_METHODS_",
|
||||||
|
FullCategoryName, true);
|
||||||
|
|
||||||
// Protocols referenced in class declaration?
|
// Protocols referenced in class declaration?
|
||||||
// Null CDecl is case of a category implementation with no category interface
|
// Protocol's super protocol list
|
||||||
if (CDecl)
|
std::vector<ObjCProtocolDecl *> RefedProtocols;
|
||||||
RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
|
const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
|
||||||
FullCategoryName, Result);
|
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
|
||||||
/* struct _objc_category {
|
E = Protocols.end();
|
||||||
char *category_name;
|
I != E; ++I) {
|
||||||
char *class_name;
|
RefedProtocols.push_back(*I);
|
||||||
struct _objc_method_list *instance_methods;
|
// Must write out all protocol definitions in current qualifier list,
|
||||||
struct _objc_method_list *class_methods;
|
// and in their nested qualifiers before writing out current definition.
|
||||||
struct _objc_protocol_list *protocols;
|
RewriteObjCProtocolMetaData(*I, Result);
|
||||||
// Objective-C 1.0 extensions
|
}
|
||||||
uint32_t size; // sizeof (struct _objc_category)
|
|
||||||
struct _objc_property_list *instance_properties; // category's own
|
|
||||||
// @property decl.
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool objc_category = false;
|
Write_protocol_list_initializer(Context, Result,
|
||||||
if (!objc_category) {
|
RefedProtocols,
|
||||||
Result += "\nstruct _objc_category {\n";
|
"_OBJC_CATEGORY_PROTOCOLS_$_",
|
||||||
Result += "\tchar *category_name;\n";
|
FullCategoryName);
|
||||||
Result += "\tchar *class_name;\n";
|
|
||||||
Result += "\tstruct _objc_method_list *instance_methods;\n";
|
|
||||||
Result += "\tstruct _objc_method_list *class_methods;\n";
|
|
||||||
Result += "\tstruct _objc_protocol_list *protocols;\n";
|
|
||||||
Result += "\tunsigned int size;\n";
|
|
||||||
Result += "\tstruct _objc_property_list *instance_properties;\n";
|
|
||||||
Result += "};\n";
|
|
||||||
objc_category = true;
|
|
||||||
}
|
|
||||||
Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
|
|
||||||
Result += FullCategoryName;
|
|
||||||
Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
|
|
||||||
Result += IDecl->getNameAsString();
|
|
||||||
Result += "\"\n\t, \"";
|
|
||||||
Result += ClassDecl->getNameAsString();
|
|
||||||
Result += "\"\n";
|
|
||||||
|
|
||||||
if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
|
// Protocol's property metadata.
|
||||||
Result += "\t, (struct _objc_method_list *)"
|
std::vector<ObjCPropertyDecl *> ClassProperties;
|
||||||
"&_OBJC_CATEGORY_INSTANCE_METHODS_";
|
for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
|
||||||
Result += FullCategoryName;
|
E = CDecl->prop_end(); I != E; ++I)
|
||||||
Result += "\n";
|
ClassProperties.push_back(*I);
|
||||||
}
|
|
||||||
else
|
Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
|
||||||
Result += "\t, 0\n";
|
/* Container */0,
|
||||||
if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
|
"_OBJC_$_PROP_LIST_",
|
||||||
Result += "\t, (struct _objc_method_list *)"
|
FullCategoryName);
|
||||||
"&_OBJC_CATEGORY_CLASS_METHODS_";
|
|
||||||
Result += FullCategoryName;
|
Write_category_t(*this, Context, Result,
|
||||||
Result += "\n";
|
CDecl->getNameAsString(),
|
||||||
}
|
ClassDecl->getNameAsString(),
|
||||||
else
|
InstanceMethods,
|
||||||
Result += "\t, 0\n";
|
ClassMethods,
|
||||||
|
RefedProtocols,
|
||||||
|
ClassProperties);
|
||||||
|
|
||||||
if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) {
|
|
||||||
Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
|
|
||||||
Result += FullCategoryName;
|
|
||||||
Result += "\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Result += "\t, 0\n";
|
|
||||||
Result += "\t, sizeof(struct _objc_category), 0\n};\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
|
// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
|
||||||
|
|
Loading…
Reference in New Issue