summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h5
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h12
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp4
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp60
4 files changed, 77 insertions, 4 deletions
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 2a022657bd..94b7cf4f95 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -78,6 +78,11 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
public:
virtual ~TargetLoweringObjectFileMachO() {}
+ /// emitModuleFlags - Emit the module flags that specify the garbage
+ /// collection information.
+ virtual void emitModuleFlags(MCStreamer &Streamer, NamedMDNode *ModFlags,
+ Mangler *Mang, const TargetMachine &TM) const;
+
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 04fe2208b2..d1151a10d2 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -29,6 +29,7 @@ namespace llvm {
class MCSectionMachO;
class MCSymbol;
class MCStreamer;
+ class NamedMDNode;
class GlobalValue;
class TargetMachine;
@@ -53,7 +54,12 @@ public:
virtual void emitPersonalityValue(MCStreamer &Streamer,
const TargetMachine &TM,
const MCSymbol *Sym) const;
-
+
+ /// emitModuleFlags - Emit the module flags that the platform cares about.
+ virtual void emitModuleFlags(MCStreamer &, NamedMDNode *, Mangler *,
+ const TargetMachine &) const {
+ }
+
/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
/// decide not to emit the UsedDirective for some symbols in llvm.used.
/// FIXME: REMOVE this (rdar://7071300)
@@ -86,9 +92,7 @@ public:
const TargetMachine &TM) const {
return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM);
}
-
-
-
+
/// getExplicitSectionGlobal - Targets should implement this method to assign
/// a section to globals with an explicit section specfied. The
/// implementation of this method can assume that GV->hasSection() is true.
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 241f20097e..80d90d668d 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -857,6 +857,10 @@ bool AsmPrinter::doFinalization(Module &M) {
EmitVisibility(Name, V, false);
}
+ // Emit module flags.
+ if (NamedMDNode *ModFlags = M.getModuleFlagsMetadata())
+ getObjFileLowering().emitModuleFlags(OutStreamer, ModFlags, Mang, TM);
+
// Finalize debug and EH information.
if (DE) {
{
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 3a71f4f126..1b62419aab 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -17,6 +17,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
+#include "llvm/Module.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -370,6 +371,65 @@ TargetLoweringObjectFileELF::getStaticDtorSection(unsigned Priority) const {
// MachO
//===----------------------------------------------------------------------===//
+/// emitModuleFlags - Emit the module flags that specify the garbage collection
+/// information.
+void TargetLoweringObjectFileMachO::
+emitModuleFlags(MCStreamer &Streamer, NamedMDNode *ModFlags,
+ Mangler *Mang, const TargetMachine &TM) const {
+ StringRef Version("Objective-C Image Info Version");
+ StringRef SectionSpec("Objective-C Image Info Section");
+ StringRef GC("Objective-C Garbage Collection");
+ StringRef GCOnly("Objective-C GC Only");
+
+ unsigned VersionVal = 0;
+ unsigned GCFlags = 0;
+ StringRef Section;
+
+ for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) {
+ MDNode *Flag = ModFlags->getOperand(i);
+ Value *Behavior = Flag->getOperand(0);
+
+ // Ignore flags with 'Require' behavior.
+ if (cast<ConstantInt>(Behavior)->getZExtValue() == Module::Require)
+ continue;
+
+ Value *Key = Flag->getOperand(1);
+ Value *Val = Flag->getOperand(2);
+
+ StringRef KeyStr = cast<MDString>(Key)->getString();
+
+ if (KeyStr == Version)
+ VersionVal = cast<ConstantInt>(Val)->getZExtValue();
+ else if (KeyStr == GC || KeyStr == GCOnly)
+ GCFlags |= cast<ConstantInt>(Val)->getZExtValue();
+ else if (KeyStr == SectionSpec)
+ Section = cast<MDString>(Val)->getString();
+ }
+
+ // The section is mandatory. If we don't have it, then we don't have image
+ // info information.
+ if (Section.empty()) return;
+
+ uint32_t Values[2] = { VersionVal, GCFlags };
+ Module *M = ModFlags->getParent();
+ Constant *Init = ConstantDataArray::get(M->getContext(), Values);
+ GlobalVariable *GV = new GlobalVariable(*M, Init->getType(), false,
+ GlobalValue::InternalLinkage, Init,
+ "\01L_OBJC_IMAGE_INFO");
+ GV->setSection(Section);
+
+ MCSymbol *GVSym = Mang->getSymbol(GV);
+ SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
+ const MCSection *TheSection = SectionForGlobal(GV, GVKind, Mang, TM);
+
+ Streamer.SwitchSection(TheSection);
+ Streamer.EmitLabel(GVSym);
+
+ Streamer.EmitIntValue(VersionVal, 4);
+ Streamer.EmitIntValue(GCFlags, 4);
+ Streamer.AddBlankLine();
+}
+
const MCSection *TargetLoweringObjectFileMachO::
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {