diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 94b7cf4f95b..5a4213625ba 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -15,9 +15,9 @@ #ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H #define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H -#include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" #include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/ADT/StringRef.h" namespace llvm { class MachineModuleInfo; @@ -80,7 +80,8 @@ public: /// emitModuleFlags - Emit the module flags that specify the garbage /// collection information. - virtual void emitModuleFlags(MCStreamer &Streamer, NamedMDNode *ModFlags, + virtual void emitModuleFlags(MCStreamer &Streamer, + ArrayRef ModuleFlags, Mangler *Mang, const TargetMachine &TM) const; virtual const MCSection * diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index d1151a10d2e..88f28a6c80a 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -15,9 +15,11 @@ #ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H -#include "llvm/ADT/StringRef.h" +#include "llvm/Module.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/SectionKind.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" namespace llvm { class MachineModuleInfo; @@ -56,8 +58,9 @@ public: const MCSymbol *Sym) const; /// emitModuleFlags - Emit the module flags that the platform cares about. - virtual void emitModuleFlags(MCStreamer &, NamedMDNode *, Mangler *, - const TargetMachine &) const { + virtual void emitModuleFlags(MCStreamer &, + ArrayRef, + Mangler *, const TargetMachine &) const { } /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 80d90d668de..5ebce50b1a8 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -858,8 +858,10 @@ bool AsmPrinter::doFinalization(Module &M) { } // Emit module flags. - if (NamedMDNode *ModFlags = M.getModuleFlagsMetadata()) - getObjFileLowering().emitModuleFlags(OutStreamer, ModFlags, Mang, TM); + SmallVector ModuleFlags; + M.getModuleFlagsMetadata(ModuleFlags); + if (!ModuleFlags.empty()) + getObjFileLowering().emitModuleFlags(OutStreamer, ModuleFlags, Mang, TM); // Finalize debug and EH information. if (DE) { diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 1b62419aabd..90487d91661 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -374,57 +374,55 @@ TargetLoweringObjectFileELF::getStaticDtorSection(unsigned Priority) const { /// emitModuleFlags - Emit the module flags that specify the garbage collection /// information. void TargetLoweringObjectFileMachO:: -emitModuleFlags(MCStreamer &Streamer, NamedMDNode *ModFlags, +emitModuleFlags(MCStreamer &Streamer, + ArrayRef ModuleFlags, 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; + StringRef SectionVal; - for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) { - MDNode *Flag = ModFlags->getOperand(i); - Value *Behavior = Flag->getOperand(0); + for (ArrayRef::iterator + i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) { + const Module::ModuleFlagEntry &MFE = *i; // Ignore flags with 'Require' behavior. - if (cast(Behavior)->getZExtValue() == Module::Require) + if (MFE.Behavior == Module::Require) continue; - Value *Key = Flag->getOperand(1); - Value *Val = Flag->getOperand(2); + StringRef Key = MFE.Key->getString(); + Value *Val = MFE.Val; - StringRef KeyStr = cast(Key)->getString(); - - if (KeyStr == Version) + if (Key == "Objective-C Image Info Version") VersionVal = cast(Val)->getZExtValue(); - else if (KeyStr == GC || KeyStr == GCOnly) + else if (Key == "Objective-C Garbage Collection" || + Key == "Objective-C GC Only") GCFlags |= cast(Val)->getZExtValue(); - else if (KeyStr == SectionSpec) - Section = cast(Val)->getString(); + else if (Key == "Objective-C Image Info Section") + SectionVal = cast(Val)->getString(); } - // The section is mandatory. If we don't have it, then we don't have image - // info information. - if (Section.empty()) return; + // The section is mandatory. If we don't have it, then we don't have GC info. + if (SectionVal.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); + StringRef Segment, Section; + unsigned TAA = 0, StubSize = 0; + bool TAAParsed; + std::string ErrorCode = + MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, + TAA, TAAParsed, StubSize); + if (!ErrorCode.empty()) { + // If invalid, report the error with report_fatal_error. + report_fatal_error("Invalid section specifier '" + + Section + "': " + ErrorCode + "."); + } + // Get the section. + const MCSectionMachO *S = + getContext().getMachOSection(Segment, Section, TAA, StubSize, + SectionKind::getDataRel()); + Streamer.SwitchSection(S); + Streamer.EmitLabel(getContext(). + GetOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(VersionVal, 4); Streamer.EmitIntValue(GCFlags, 4); Streamer.AddBlankLine();