[cfe-commits] r55209 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Daniel Dunbar
daniel at zuster.org
Fri Aug 22 17:19:03 PDT 2008
Author: ddunbar
Date: Fri Aug 22 19:19:03 2008
New Revision: 55209
URL: http://llvm.org/viewvc/llvm-project?rev=55209&view=rev
Log:
NeXT: Emit property metadata (classes, protocols, categories).
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=55209&r1=55208&r2=55209&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Aug 22 19:19:03 2008
@@ -80,8 +80,12 @@
/// MethodDescriptionListPtrTy - LLVM type for struct
/// objc_method_description_list *.
const llvm::Type *MethodDescriptionListPtrTy;
- /// PropertyListTy - LLVM type for struct objc_property_list.
- const llvm::Type *PropertyListTy;
+ /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
+ /// in GCC parlance).
+ const llvm::StructType *PropertyTy;
+ /// PropertyListTy - LLVM type for struct objc_property_list
+ /// (_prop_list_t in GCC parlance).
+ const llvm::StructType *PropertyListTy;
/// PropertyListPtrTy - LLVM type for struct objc_property_list*.
const llvm::Type *PropertyListPtrTy;
/// ProtocolListTy - LLVM type for struct objc_property_list.
@@ -141,6 +145,9 @@
/// a StringMap here because have no other unique reference.
llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
+ /// PropertyNames - uniqued method variable names.
+ llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
+
/// ClassReferences - uniqued class references.
llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
@@ -206,7 +213,7 @@
/// EmitMethodList - Emit the method list for the given
/// implementation. If ForClass is true the list of class methods
/// will be emitted, otherwise the list of instance methods will be
- /// generated.The return value has type MethodListPtrTy.
+ /// generated. The return value has type MethodListPtrTy.
llvm::Constant *EmitMethodList(const std::string &Name,
const char *Section,
llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
@@ -230,6 +237,12 @@
ObjCMethodDecl * const *begin,
ObjCMethodDecl * const *end);
+ /// EmitPropertyList - Emit the given property list. The return
+ /// value has type PropertyListPtrTy.
+ llvm::Constant *EmitPropertyList(const std::string &Name,
+ ObjCPropertyDecl * const *begin,
+ ObjCPropertyDecl * const *end);
+
/// EmitProtocolExtension - Generate the protocol extension
/// structure used to store optional instance and class methods, and
/// protocol properties. The return value has type
@@ -256,18 +269,25 @@
llvm::Constant *GetClassName(IdentifierInfo *Ident);
/// GetMethodVarName - Return a unique constant for the given
- /// selector's name. This returns a constant i8* to the start of
- /// the name. The return value has type char *.
+ /// selector's name. The return value has type char *.
llvm::Constant *GetMethodVarName(Selector Sel);
- llvm::Constant *GetMethodVarName(IdentifierInfo *);
+ llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
llvm::Constant *GetMethodVarName(const std::string &Name);
/// GetMethodVarType - Return a unique constant for the given
- /// selector's name. This returns a constant i8* to the start of
- /// the name. The return value has type char *.
+ /// selector's name. The return value has type char *.
+
+ // FIXME: This is a horrible name.
llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
llvm::Constant *GetMethodVarType(const std::string &Name);
+ /// GetPropertyName - Return a unique constant for the given
+ /// name. The return value has type char *.
+ llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
+
+ // FIXME: This is a horrible name too.
+ llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
+
/// GetNameForMethod - Return a name for the given method.
/// \param[out] NameOut - The return value.
void GetNameForMethod(const ObjCMethodDecl *OMD,
@@ -555,9 +575,10 @@
false, // Required
PD->classmeth_begin(),
PD->classmeth_end());
- Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
- assert(!PD->getNumPropertyDecl() &&
- "Cannot emit Obj-C protocol properties for NeXT runtime.");
+ Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
+ PD->getName(),
+ PD->classprop_begin(),
+ PD->classprop_end());
// Return null if no extension bits are used.
if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
@@ -623,6 +644,57 @@
}
/*
+ struct _objc_property {
+ const char * const name;
+ const char * const attributes;
+ };
+
+ struct _objc_property_list {
+ uint32_t entsize; // sizeof (struct _objc_property)
+ uint32_t prop_count;
+ struct _objc_property[prop_count];
+ };
+*/
+llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
+ ObjCPropertyDecl * const *begin,
+ ObjCPropertyDecl * const *end) {
+ std::vector<llvm::Constant*> Properties, Prop(2);
+ for (; begin != end; ++begin) {
+ const ObjCPropertyDecl *PD = *begin;
+ Prop[0] = GetPropertyName(PD->getIdentifier());
+ Prop[1] = GetPropertyType(PD);
+ Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
+ Prop));
+ }
+
+ // Return null for empty list.
+ if (Properties.empty())
+ return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
+
+ unsigned PropertySize =
+ CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
+ std::vector<llvm::Constant*> Values(3);
+ Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
+ Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
+ llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
+ Properties.size());
+ Values[2] = llvm::ConstantArray::get(AT, Properties);
+ llvm::Constant *Init = llvm::ConstantStruct::get(Values);
+
+ llvm::GlobalVariable *GV =
+ new llvm::GlobalVariable(Init->getType(), false,
+ llvm::GlobalValue::InternalLinkage,
+ Init,
+ Name,
+ &CGM.getModule());
+ // No special section on property lists?
+ UsedGlobals.push_back(GV);
+ return llvm::ConstantExpr::getBitCast(GV,
+ ObjCTypes.PropertyListPtrTy);
+
+}
+
+/*
struct objc_method_description_list {
int count;
struct objc_method_description list[];
@@ -705,19 +777,25 @@
std::vector<llvm::Constant*> Values(7);
Values[0] = GetClassName(OCD->getIdentifier());
Values[1] = GetClassName(Interface->getIdentifier());
- Values[2] = EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") + ExtName,
- "__OBJC,__cat_inst_meth,regular,no_dead_strip",
- OCD->instmeth_begin(),
- OCD->instmeth_end());
- Values[3] = EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
- "__OBJC,__cat_class_meth,regular,no_dead_strip",
- OCD->classmeth_begin(),
- OCD->classmeth_end());
- Values[4] = EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
- Interface->protocol_begin(),
- Interface->protocol_end());
+ Values[2] =
+ EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
+ ExtName,
+ "__OBJC,__cat_inst_meth,regular,no_dead_strip",
+ OCD->instmeth_begin(),
+ OCD->instmeth_end());
+ Values[3] =
+ EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
+ "__OBJC,__cat_class_meth,regular,no_dead_strip",
+ OCD->classmeth_begin(),
+ OCD->classmeth_end());
+ Values[4] =
+ EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
+ Interface->protocol_begin(),
+ Interface->protocol_end());
Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
- Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
+ Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
+ Interface->classprop_begin(),
+ Interface->classprop_end());
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
Values);
@@ -815,10 +893,11 @@
Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
- Values[ 7] = EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
- "__OBJC,__inst_meth,regular,no_dead_strip",
- ID->instmeth_begin(),
- ID->instmeth_end());
+ Values[ 7] =
+ EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
+ "__OBJC,__inst_meth,regular,no_dead_strip",
+ ID->instmeth_begin(),
+ ID->instmeth_end());
// cache is always NULL.
Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
Values[ 9] = Protocols;
@@ -875,10 +954,11 @@
Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
- Values[ 7] = EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
- "__OBJC,__inst_meth,regular,no_dead_strip",
- ID->classmeth_begin(),
- ID->classmeth_end());
+ Values[ 7] =
+ EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
+ "__OBJC,__inst_meth,regular,no_dead_strip",
+ ID->classmeth_begin(),
+ ID->classmeth_end());
// cache is always NULL.
Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
Values[ 9] = Protocols;
@@ -919,10 +999,10 @@
Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
// FIXME: Output weak_ivar_layout string.
Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
- // FIXME: Output properties.
- Values[2] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
- assert(!ID->getClassInterface()->getNumPropertyDecl() &&
- "Cannot emit Obj-C class properties for NeXt runtime.");
+ Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
+ ID->getName(),
+ ID->getClassInterface()->classprop_begin(),
+ ID->getClassInterface()->classprop_end());
// Return null if no extension bits are used.
if (Values[1]->isNullValue() && Values[2]->isNullValue())
@@ -1362,6 +1442,31 @@
return GetMethodVarType(TypeStr);
}
+// FIXME: Merge into a single cstring creation function.
+llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
+ llvm::GlobalVariable *&Entry = PropertyNames[Ident];
+
+ if (!Entry) {
+ llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
+ Entry =
+ new llvm::GlobalVariable(C->getType(), false,
+ llvm::GlobalValue::InternalLinkage,
+ C, "\01L_OBJC_PROP_NAME_ATTR_",
+ &CGM.getModule());
+ Entry->setSection("__TEXT,__cstring,cstring_literals");
+ UsedGlobals.push_back(Entry);
+ }
+
+ return getConstantGEP(Entry, 0, 0);
+}
+
+// FIXME: Merge into a single cstring creation function.
+llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
+ std::string TypeStr("MOOO!");
+ //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
+ return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
+}
+
void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
std::string &NameOut) {
// FIXME: Find the mangling GCC uses.
@@ -1436,7 +1541,16 @@
MethodDescriptionListPtrTy =
llvm::PointerType::getUnqual(MethodDescriptionListTy);
- PropertyListTy = llvm::OpaqueType::get();
+ PropertyTy = llvm::StructType::get(Int8PtrTy,
+ Int8PtrTy,
+ NULL);
+ CGM.getModule().addTypeName("struct._objc_property",
+ PropertyTy);
+
+ PropertyListTy = llvm::StructType::get(IntTy,
+ IntTy,
+ llvm::ArrayType::get(PropertyTy, 0),
+ NULL);
CGM.getModule().addTypeName("struct._objc_property_list",
PropertyListTy);
PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
More information about the cfe-commits
mailing list