[cfe-commits] r55405 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Daniel Dunbar
daniel at zuster.org
Tue Aug 26 19:31:56 PDT 2008
Author: ddunbar
Date: Tue Aug 26 21:31:56 2008
New Revision: 55405
URL: http://llvm.org/viewvc/llvm-project?rev=55405&view=rev
Log:
NeXT: Refactor protocol method metadata emission.
Also, fix category protocol list metadata.
Modified:
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=55405&r1=55404&r2=55405&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Aug 26 21:31:56 2008
@@ -29,6 +29,8 @@
namespace {
+ typedef std::vector<llvm::Constant*> ConstantVector;
+
// FIXME: We should find a nicer way to make the labels for
// metadata, string concatenation is lame.
@@ -235,15 +237,17 @@
llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
llvm::Constant *Protocols,
const llvm::Type *InterfaceTy,
- const std::vector<llvm::Constant*> &Methods);
+ const ConstantVector &Methods);
+
+ llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
+
+ llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
/// EmitMethodList - Emit the method list for the given
/// implementation. The return value has type MethodListPtrTy.
llvm::Constant *EmitMethodList(const std::string &Name,
const char *Section,
- const std::vector<llvm::Constant*> &Methods);
-
- llvm::Constant *GetMethodConstant(ObjCMethodDecl *MD);
+ const ConstantVector &Methods);
/// EmitMethodDescList - Emit a method description list for a list of
/// method declarations.
@@ -256,12 +260,9 @@
/// - begin, end: The method list to output.
///
/// The return value has type MethodDescriptionListPtrTy.
- llvm::Constant *EmitMethodDescList(const std::string &TypeName,
- bool IsProtocol,
- bool ClassMethods,
- bool Required,
- ObjCMethodDecl * const *begin,
- ObjCMethodDecl * const *end);
+ llvm::Constant *EmitMethodDescList(const std::string &Name,
+ const char *Section,
+ const ConstantVector &Methods);
/// EmitPropertyList - Emit the given property list. The return
/// value has type PropertyListPtrTy.
@@ -273,7 +274,10 @@
/// structure used to store optional instance and class methods, and
/// protocol properties. The return value has type
/// ProtocolExtensionPtrTy.
- llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
+ llvm::Constant *
+ EmitProtocolExtension(const ObjCProtocolDecl *PD,
+ const ConstantVector &OptInstanceMethods,
+ const ConstantVector &OptClassMethods);
/// EmitProtocolList - Generate the list of referenced
/// protocols. The return value has type ProtocolListPtrTy.
@@ -499,26 +503,49 @@
LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
const char *ProtocolName = PD->getName();
-
+
+ // Construct method lists.
+ std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+ std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
+ for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(),
+ e = PD->instmeth_end(); i != e; ++i) {
+ ObjCMethodDecl *MD = *i;
+ llvm::Constant *C = GetMethodDescriptionConstant(MD);
+ if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+ OptInstanceMethods.push_back(C);
+ } else {
+ InstanceMethods.push_back(C);
+ }
+ }
+
+ for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(),
+ e = PD->classmeth_end(); i != e; ++i) {
+ ObjCMethodDecl *MD = *i;
+ llvm::Constant *C = GetMethodDescriptionConstant(MD);
+ if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+ OptClassMethods.push_back(C);
+ } else {
+ ClassMethods.push_back(C);
+ }
+ }
+
std::vector<llvm::Constant*> Values(5);
- Values[0] = EmitProtocolExtension(PD);
+ Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
Values[1] = GetClassName(PD->getIdentifier());
Values[2] =
EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
PD->protocol_begin(),
PD->protocol_end());
- Values[3] = EmitMethodDescList(ProtocolName,
- true, // IsProtocol
- false, // ClassMethods
- true, // Required
- PD->instmeth_begin(),
- PD->instmeth_end());
- Values[4] = EmitMethodDescList(ProtocolName,
- true, // IsProtocol
- true, // ClassMethods
- true, // Required
- PD->classmeth_begin(),
- PD->classmeth_end());
+ Values[3] =
+ EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_")
+ + PD->getName(),
+ "__OBJC,__cat_inst_meth,regular,no_dead_strip",
+ InstanceMethods);
+ Values[4] =
+ EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_")
+ + PD->getName(),
+ "__OBJC,__cat_cls_meth,regular,no_dead_strip",
+ ClassMethods);
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
Values);
@@ -576,23 +603,24 @@
struct objc_property_list *instance_properties;
};
*/
-llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
+llvm::Constant *
+CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
+ const ConstantVector &OptInstanceMethods,
+ const ConstantVector &OptClassMethods) {
uint64_t Size =
CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
std::vector<llvm::Constant*> Values(4);
Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
- Values[1] = EmitMethodDescList(PD->getName(),
- true, // IsProtocol
- false, // ClassMethods
- false, // Required
- PD->instmeth_begin(),
- PD->instmeth_end());
- Values[2] = EmitMethodDescList(PD->getName(),
- true, // IsProtocol
- true, // ClassMethods
- false, // Required
- PD->classmeth_begin(),
- PD->classmeth_end());
+ Values[1] =
+ EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_")
+ + PD->getName(),
+ "__OBJC,__cat_inst_meth,regular,no_dead_strip",
+ OptInstanceMethods);
+ Values[2] =
+ EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_")
+ + PD->getName(),
+ "__OBJC,__cat_cls_meth,regular,no_dead_strip",
+ OptClassMethods);
Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
PD->getName(),
PD->classprop_begin(),
@@ -718,29 +746,19 @@
struct objc_method_description list[];
};
*/
-llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
- bool IsProtocol,
- bool ClassMethods,
- bool Required,
- ObjCMethodDecl * const *begin,
- ObjCMethodDecl * const *end) {
- std::vector<llvm::Constant*> Methods, Desc(2);
- for (; begin != end; ++begin) {
- ObjCMethodDecl *D = *begin;
- bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
-
- // Skip if this method is required and we are outputting optional
- // methods, or vice versa.
- if (Required != IsRequired)
- continue;
-
- Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
- ObjCTypes.SelectorPtrTy);
- Desc[1] = GetMethodVarType(D);
- Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
- Desc));
- }
+llvm::Constant *
+CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
+ std::vector<llvm::Constant*> Desc(2);
+ Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
+ ObjCTypes.SelectorPtrTy);
+ Desc[1] = GetMethodVarType(MD);
+ return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
+ Desc);
+}
+llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name,
+ const char *Section,
+ const ConstantVector &Methods) {
// Return null for empty list.
if (Methods.empty())
return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
@@ -752,22 +770,11 @@
Values[1] = llvm::ConstantArray::get(AT, Methods);
llvm::Constant *Init = llvm::ConstantStruct::get(Values);
- char Prefix[256];
- sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
- IsProtocol ? "PROTOCOL_" : "",
- ClassMethods ? "CLASS_" : "INSTANCE_",
- !Required ? "OPT_" : "");
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(Init->getType(), false,
llvm::GlobalValue::InternalLinkage,
- Init,
- std::string(Prefix) + TypeName,
- &CGM.getModule());
- if (ClassMethods) {
- GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
- } else {
- GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
- }
+ Init, Name, &CGM.getModule());
+ GV->setSection(Section);
UsedGlobals.push_back(GV);
return llvm::ConstantExpr::getBitCast(GV,
ObjCTypes.MethodDescriptionListPtrTy);
@@ -823,10 +830,14 @@
EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
"__OBJC,__cat_class_meth,regular,no_dead_strip",
ClassMethods);
- Values[4] =
- EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
- Interface->protocol_begin(),
- Interface->protocol_end());
+ if (Category) {
+ Values[4] =
+ EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
+ Category->protocol_begin(),
+ Category->protocol_end());
+ } else {
+ Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
+ }
Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
// If there is no category @interface then there can be no properties.
@@ -996,7 +1007,7 @@
llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
llvm::Constant *Protocols,
const llvm::Type *InterfaceTy,
- const std::vector<llvm::Constant*> &Methods) {
+ const ConstantVector &Methods) {
const char *ClassName = ID->getName();
unsigned Flags = eClassFlags_Meta;
unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
@@ -1223,7 +1234,7 @@
/// GetMethodConstant - Return a struct objc_method constant for the
/// given method if it has been defined. The result is null if the
/// method has not been defined. The return value has type MethodPtrTy.
-llvm::Constant *CGObjCMac::GetMethodConstant(ObjCMethodDecl *MD) {
+llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
// FIXME: Use DenseMap::lookup
llvm::Function *Fn = MethodDefinitions[MD];
if (!Fn)
@@ -1240,8 +1251,7 @@
llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
const char *Section,
- const std::vector<llvm::Constant*>
- &Methods) {
+ const ConstantVector &Methods) {
// Return null for empty list.
if (Methods.empty())
return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
More information about the cfe-commits
mailing list