forked from OSchip/llvm-project
Class Property: generate metadata for class properties in categories.
The list of class properties is saved in Old ABI: category->class_properties (category->size will be updated as well) New ABI: category->class_properties (a flag in objc_image_info to indicate whether or not the list of class properties is present) rdar://23891898 llvm-svn: 259267
This commit is contained in:
parent
63634cb0bc
commit
96df0b33f6
|
@ -3045,6 +3045,7 @@ CGObjCMac::EmitMethodDescList(Twine Name, const char *Section,
|
|||
struct _objc_protocol_list *protocols;
|
||||
uint32_t size; // <rdar://4585769>
|
||||
struct _objc_property_list *instance_properties;
|
||||
struct _objc_property_list *class_properties;
|
||||
};
|
||||
*/
|
||||
void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
||||
|
@ -3071,7 +3072,7 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
// Class methods should always be defined.
|
||||
ClassMethods.push_back(GetMethodConstant(I));
|
||||
|
||||
llvm::Constant *Values[7];
|
||||
llvm::Constant *Values[8];
|
||||
Values[0] = GetClassName(OCD->getName());
|
||||
Values[1] = GetClassName(Interface->getObjCRuntimeNameAsString());
|
||||
LazySymbols.insert(Interface->getIdentifier());
|
||||
|
@ -3094,8 +3095,11 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
if (Category) {
|
||||
Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
|
||||
OCD, Category, ObjCTypes, false);
|
||||
Values[7] = EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
|
||||
OCD, Category, ObjCTypes, true);
|
||||
} else {
|
||||
Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
|
||||
Values[7] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
|
||||
}
|
||||
|
||||
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
|
||||
|
@ -4480,7 +4484,8 @@ enum ImageInfoFlags {
|
|||
// A flag indicating that the module has no instances of a @synthesize of a
|
||||
// superclass variable. <rdar://problem/6803242>
|
||||
eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
|
||||
eImageInfo_ImageIsSimulated = (1 << 5)
|
||||
eImageInfo_ImageIsSimulated = (1 << 5),
|
||||
eImageInfo_ClassProperties = (1 << 6)
|
||||
};
|
||||
|
||||
void CGObjCCommonMac::EmitImageInfo() {
|
||||
|
@ -4532,6 +4537,10 @@ void CGObjCCommonMac::EmitImageInfo() {
|
|||
Triple.getArch() == llvm::Triple::x86_64))
|
||||
Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
|
||||
eImageInfo_ImageIsSimulated);
|
||||
|
||||
// Indicate whether we are generating class properties.
|
||||
Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties",
|
||||
eImageInfo_ClassProperties);
|
||||
}
|
||||
|
||||
// struct objc_module {
|
||||
|
@ -5387,12 +5396,14 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
// struct _objc_protocol_list *protocols;
|
||||
// uint32_t size; // sizeof(struct _objc_category)
|
||||
// struct _objc_property_list *instance_properties;// category's @property
|
||||
// struct _objc_property_list *class_properties;
|
||||
// }
|
||||
CategoryTy =
|
||||
llvm::StructType::create("struct._objc_category",
|
||||
Int8PtrTy, Int8PtrTy, MethodListPtrTy,
|
||||
MethodListPtrTy, ProtocolListPtrTy,
|
||||
IntTy, PropertyListPtrTy, nullptr);
|
||||
IntTy, PropertyListPtrTy, PropertyListPtrTy,
|
||||
nullptr);
|
||||
|
||||
// Global metadata structures
|
||||
|
||||
|
@ -5565,6 +5576,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
|
|||
// const struct _method_list_t * const class_methods;
|
||||
// const struct _protocol_list_t * const protocols;
|
||||
// const struct _prop_list_t * const properties;
|
||||
// const struct _prop_list_t * const class_properties;
|
||||
// }
|
||||
CategorynfABITy = llvm::StructType::create("struct._category_t",
|
||||
Int8PtrTy, ClassnfABIPtrTy,
|
||||
|
@ -5572,6 +5584,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
|
|||
MethodListnfABIPtrTy,
|
||||
ProtocolListnfABIPtrTy,
|
||||
PropertyListPtrTy,
|
||||
PropertyListPtrTy,
|
||||
nullptr);
|
||||
|
||||
// New types for nonfragile abi messaging.
|
||||
|
@ -6122,6 +6135,7 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
|
|||
/// const struct _method_list_t * const class_methods;
|
||||
/// const struct _protocol_list_t * const protocols;
|
||||
/// const struct _prop_list_t * const properties;
|
||||
/// const struct _prop_list_t * const class_properties;
|
||||
/// }
|
||||
///
|
||||
void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
||||
|
@ -6136,7 +6150,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
llvm::SmallString<64> ExtClassName(getClassSymbolPrefix());
|
||||
ExtClassName += Interface->getObjCRuntimeNameAsString();
|
||||
|
||||
llvm::Constant *Values[6];
|
||||
llvm::Constant *Values[7];
|
||||
Values[0] = GetClassName(OCD->getIdentifier()->getName());
|
||||
// meta-class entry symbol
|
||||
llvm::GlobalVariable *ClassGV =
|
||||
|
@ -6186,9 +6200,12 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
Category->protocol_end());
|
||||
Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
|
||||
OCD, Category, ObjCTypes, false);
|
||||
Values[6] = EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
|
||||
OCD, Category, ObjCTypes, true);
|
||||
} else {
|
||||
Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
|
||||
Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
|
||||
Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
|
||||
}
|
||||
|
||||
llvm::Constant *Init =
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck -check-prefix=CHECK-FRAGILE %s
|
||||
|
||||
// CHECK: @"\01l_OBJC_$_CLASS_PROP_LIST_Foo_$_Category" = private global {{.*}} section "__DATA, __objc_const", align 8
|
||||
// CHECK: @"\01l_OBJC_$_CATEGORY_Foo_$_Category" = private global %struct._category_t { {{.*}} @"\01l_OBJC_$_CLASS_PROP_LIST_Foo_$_Category" {{.*}} }, section "__DATA, __objc_const", align 8
|
||||
|
||||
// CHECK: !{i32 1, !"Objective-C Class Properties", i32 64}
|
||||
|
||||
// CHECK-FRAGILE: @"\01l_OBJC_$_CLASS_PROP_LIST_Foo_Category" = private global {{.*}} section "__OBJC,__property,regular,no_dead_strip", align 8
|
||||
// CHECK-FRAGILE: @OBJC_CATEGORY_Foo_Category = private global %struct._objc_category { {{.*}}, i32 64, {{.*}} @"\01l_OBJC_$_CLASS_PROP_LIST_Foo_Category" {{.*}} }, section "__OBJC,__category,regular,no_dead_strip", align 8
|
||||
|
||||
// CHECK-FRAGILE: !{i32 1, !"Objective-C Class Properties", i32 64}
|
||||
|
||||
@interface Foo @end
|
||||
|
||||
@protocol Proto
|
||||
@property (class, readonly) int proto_property;
|
||||
@end
|
||||
|
||||
@interface Foo (Category) <Proto> @end
|
||||
|
||||
@implementation Foo (Category)
|
||||
+(int)proto_property { return 0; }
|
||||
@end
|
Loading…
Reference in New Issue