Use the new method for specifying garbage collection metadata in the module.

The garbage collection metadata needs to be merged "intelligently", when two or
more modules are linked together, and not merely appended. (Appending creates a
section which is too large.) The module flags metadata method is the way to do
this.
<rdar://problem/8198537>

llvm-svn: 150648
This commit is contained in:
Bill Wendling 2012-02-16 01:13:30 +00:00
parent 3454d444dc
commit b6f795eee6
4 changed files with 48 additions and 26 deletions

View File

@ -3568,33 +3568,48 @@ enum ImageInfoFlags {
void CGObjCCommonMac::EmitImageInfo() {
unsigned version = 0; // Version is unused?
unsigned flags = 0;
const char *Section = (ObjCABI == 1) ?
"__OBJC, __image_info,regular" :
"__DATA, __objc_imageinfo, regular, no_dead_strip";
// FIXME: Fix and continue?
if (CGM.getLangOptions().getGC() != LangOptions::NonGC)
flags |= eImageInfo_GarbageCollected;
if (CGM.getLangOptions().getGC() == LangOptions::GCOnly)
flags |= eImageInfo_GCOnly;
// Generate module-level named metadata to convey this information to the
// linker and code-gen.
llvm::Module &Mod = CGM.getModule();
// We never allow @synthesize of a superclass property.
flags |= eImageInfo_CorrectedSynthesize;
// Add the ObjC ABI version to the module flags.
Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
version);
Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
llvm::MDString::get(VMContext,Section));
// Emitted as int[2];
uint32_t Values[2] = { version, flags };
if (CGM.getLangOptions().getGC() == LangOptions::NonGC) {
// Non-GC overrides those files which specify GC.
Mod.addModuleFlag(llvm::Module::Override,
"Objective-C Garbage Collection", (uint32_t)0);
} else {
// Add the ObjC garbage collection value.
Mod.addModuleFlag(llvm::Module::Error,
"Objective-C Garbage Collection",
eImageInfo_GarbageCollected);
const char *Section;
if (ObjCABI == 1)
Section = "__OBJC, __image_info,regular";
else
Section = "__DATA, __objc_imageinfo, regular, no_dead_strip";
llvm::GlobalVariable *GV =
CreateMetadataVar("\01L_OBJC_IMAGE_INFO",
llvm::ConstantDataArray::get(VMContext, Values),
Section, 0, true);
GV->setConstant(true);
if (CGM.getLangOptions().getGC() == LangOptions::GCOnly) {
// Add the ObjC GC Only value.
Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
eImageInfo_GCOnly);
// Require that GC be specified and set to eImageInfo_GarbageCollected.
llvm::Value *Ops[2] = {
llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
eImageInfo_GarbageCollected)
};
Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
llvm::MDNode::get(VMContext, Ops));
}
}
}
// struct objc_module {
// unsigned long version;
// unsigned long size;

View File

@ -2,7 +2,7 @@
// RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-fragile-abi %s -o - | FileCheck %s
extern void foo(void(^)(void));
// CHECK: !36 = metadata !{i32 {{.*}}, i32 0, metadata !6, metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata !6, i32 24, metadata !37, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !39} ; [ DW_TAG_subprogram ]
// CHECK: !40 = metadata !{i32 {{.*}}, i32 0, metadata !10, metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata !10, i32 24, metadata !41, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !43} ; [ DW_TAG_subprogram ]
@interface NSObject {
struct objc_object *isa;

View File

@ -4,5 +4,14 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
// RUN: FileCheck --check-prefix CHECK-NONFRAGILE < %t %s
// CHECK-FRAGILE: @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__OBJC, __image_info,regular"
// CHECK-NONFRAGILE: @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
// CHECK-FRAGILE: !llvm.module.flags = !{!0, !1, !2, !3}
// CHECK-FRAGILE: !0 = metadata !{i32 1, metadata !"Objective-C Version", i32 1}
// CHECK-FRAGILE-NEXT: !1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
// CHECK-FRAGILE-NEXT: !2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__OBJC, __image_info,regular"}
// CHECK-FRAGILE-NEXT: !3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
// CHECK-NONFRAGILE: !llvm.module.flags = !{!0, !1, !2, !3}
// CHECK-NONFRAGILE: !0 = metadata !{i32 1, metadata !"Objective-C Version", i32 2}
// CHECK-NONFRAGILE-NEXT: !1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
// CHECK-NONFRAGILE-NEXT: !2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
// CHECK-NONFRAGILE-NEXT: !3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}

View File

@ -6,7 +6,6 @@
// RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_CLASS_C" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_CLASS_PROTOCOLS_C" = internal global .*, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_IMAGE_INFO" = internal constant .*, section "__OBJC, __image_info,regular"' %t
// RUN: grep '@"\\01L_OBJC_METACLASS_A" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_METACLASS_C" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_MODULES" = internal global .*, section "__OBJC,__module_info,regular,no_dead_strip", align 4' %t
@ -20,7 +19,6 @@
// RUNX: grep '@"OBJC_METACLASS_$_A" = global' %t &&
// RUNX: grep '@"OBJC_METACLASS_$_C" = global' %t &&
// RUNX: grep '@"\\01L_OBJC_CLASSLIST_REFERENCES_$_0" = internal global .*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8' %t &&
// RUNX: grep '@"\\01L_OBJC_IMAGE_INFO" = internal constant .*, section "__DATA, __objc_imageinfo, regular, no_dead_strip"' %t &&
// RUNX: grep '@"\\01L_OBJC_LABEL_CATEGORY_$" = internal global .*, section "__DATA, __objc_catlist, regular, no_dead_strip", align 8' %t &&
// RUNX: grep '@"\\01L_OBJC_LABEL_CLASS_$" = internal global .*, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8' %t &&
// RUNX: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global .*, section "__DATA, __objc_const", align 8' %t &&