diff options
author | Bill Wendling <isanbard@gmail.com> | 2012-02-16 01:13:30 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2012-02-16 01:13:30 +0000 |
commit | 3973accabc855b81b55bcc1945a98b2adb2ce72a (patch) | |
tree | e984a8bb25ce4f1c0292bb8de2443bfa15e4e8ac /lib | |
parent | f8490eeb966103516da4e3ecb05e1a36b3e6e3ec (diff) |
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>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150648 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index edef754b15..b4896920b4 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -3568,33 +3568,48 @@ enum ImageInfoFlags { void CGObjCCommonMac::EmitImageInfo() { unsigned version = 0; // Version is unused? - unsigned flags = 0; - - // FIXME: Fix and continue? - if (CGM.getLangOptions().getGC() != LangOptions::NonGC) - flags |= eImageInfo_GarbageCollected; - if (CGM.getLangOptions().getGC() == LangOptions::GCOnly) - flags |= eImageInfo_GCOnly; - - // We never allow @synthesize of a superclass property. - flags |= eImageInfo_CorrectedSynthesize; - - // Emitted as int[2]; - uint32_t Values[2] = { version, flags }; - - 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); + const char *Section = (ObjCABI == 1) ? + "__OBJC, __image_info,regular" : + "__DATA, __objc_imageinfo, regular, no_dead_strip"; + + // Generate module-level named metadata to convey this information to the + // linker and code-gen. + llvm::Module &Mod = CGM.getModule(); + + // 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)); + + 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); + + 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; |