[llvm] r246554 - [MC] Allow MCObjectWriter's output stream to be swapped out
Yaron Keren via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 1 15:48:02 PDT 2015
MCAssembler also has raw_ostream &OS and now it may diverge from
underlying MCObjectWriter &Writer mutable stream. Would it make sense for
MCAssembler to use Writer.getStream() instead of OS?
2015-09-01 19:19 GMT+03:00 David Majnemer via llvm-commits <
llvm-commits at lists.llvm.org>:
> Author: majnemer
> Date: Tue Sep 1 11:19:03 2015
> New Revision: 246554
>
> URL: http://llvm.org/viewvc/llvm-project?rev=246554&view=rev
> Log:
> [MC] Allow MCObjectWriter's output stream to be swapped out
>
> There are occasions where it is useful to consider the entirety of the
> contents of a section. For example, compressed debug info needs the
> entire section available before it can compress it and write it out.
> The compressed debug info scenario was previously implemented by
> mirroring the implementation of writeSectionData in the ELFObjectWriter.
>
> Instead, allow the output stream to be swapped on demand. This lets
> callers redirect the output stream to a more convenient location before
> it hits the object file.
>
> No functionality change is intended.
>
> Differential Revision: http://reviews.llvm.org/D12509
>
> Modified:
> llvm/trunk/include/llvm/MC/MCObjectWriter.h
> llvm/trunk/lib/MC/ELFObjectWriter.cpp
> llvm/trunk/lib/MC/MachObjectWriter.cpp
> llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
>
> Modified: llvm/trunk/include/llvm/MC/MCObjectWriter.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectWriter.h?rev=246554&r1=246553&r2=246554&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCObjectWriter.h (original)
> +++ llvm/trunk/include/llvm/MC/MCObjectWriter.h Tue Sep 1 11:19:03 2015
> @@ -40,14 +40,14 @@ class MCObjectWriter {
> MCObjectWriter(const MCObjectWriter &) = delete;
> void operator=(const MCObjectWriter &) = delete;
>
> -protected:
> - raw_pwrite_stream &OS;
> + raw_pwrite_stream *OS;
>
> +protected:
> unsigned IsLittleEndian : 1;
>
> protected: // Can only create subclasses.
> MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian)
> - : OS(OS), IsLittleEndian(IsLittleEndian) {}
> + : OS(&OS), IsLittleEndian(IsLittleEndian) {}
>
> public:
> virtual ~MCObjectWriter();
> @@ -57,7 +57,8 @@ public:
>
> bool isLittleEndian() const { return IsLittleEndian; }
>
> - raw_ostream &getStream() { return OS; }
> + raw_pwrite_stream &getStream() { return *OS; }
> + void setStream(raw_pwrite_stream &NewOS) { OS = &NewOS; }
>
> /// \name High-Level API
> /// @{
> @@ -113,30 +114,30 @@ public:
> /// \name Binary Output
> /// @{
>
> - void write8(uint8_t Value) { OS << char(Value); }
> + void write8(uint8_t Value) { *OS << char(Value); }
>
> void writeLE16(uint16_t Value) {
> - support::endian::Writer<support::little>(OS).write(Value);
> + support::endian::Writer<support::little>(*OS).write(Value);
> }
>
> void writeLE32(uint32_t Value) {
> - support::endian::Writer<support::little>(OS).write(Value);
> + support::endian::Writer<support::little>(*OS).write(Value);
> }
>
> void writeLE64(uint64_t Value) {
> - support::endian::Writer<support::little>(OS).write(Value);
> + support::endian::Writer<support::little>(*OS).write(Value);
> }
>
> void writeBE16(uint16_t Value) {
> - support::endian::Writer<support::big>(OS).write(Value);
> + support::endian::Writer<support::big>(*OS).write(Value);
> }
>
> void writeBE32(uint32_t Value) {
> - support::endian::Writer<support::big>(OS).write(Value);
> + support::endian::Writer<support::big>(*OS).write(Value);
> }
>
> void writeBE64(uint64_t Value) {
> - support::endian::Writer<support::big>(OS).write(Value);
> + support::endian::Writer<support::big>(*OS).write(Value);
> }
>
> void write16(uint16_t Value) {
> @@ -164,9 +165,9 @@ public:
> const char Zeros[16] = {0};
>
> for (unsigned i = 0, e = N / 16; i != e; ++i)
> - OS << StringRef(Zeros, 16);
> + *OS << StringRef(Zeros, 16);
>
> - OS << StringRef(Zeros, N % 16);
> + *OS << StringRef(Zeros, N % 16);
> }
>
> void writeBytes(const SmallVectorImpl<char> &ByteVec,
> @@ -180,7 +181,7 @@ public:
> assert(
> (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) &&
> "data size greater than fill size, unexpected large write will
> occur");
> - OS << Str;
> + *OS << Str;
> if (ZeroFillSize)
> WriteZeros(ZeroFillSize - Str.size());
> }
>
> Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=246554&r1=246553&r2=246554&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Tue Sep 1 11:19:03 2015
> @@ -157,9 +157,9 @@ class ELFObjectWriter : public MCObjectW
>
> template <typename T> void write(T Val) {
> if (IsLittleEndian)
> - support::endian::Writer<support::little>(OS).write(Val);
> + support::endian::Writer<support::little>(getStream()).write(Val);
> else
> - support::endian::Writer<support::big>(OS).write(Val);
> + support::endian::Writer<support::big>(getStream()).write(Val);
> }
>
> void writeHeader(const MCAssembler &Asm);
> @@ -232,7 +232,7 @@ class ELFObjectWriter : public MCObjectW
> }
>
> void ELFObjectWriter::align(unsigned Alignment) {
> - uint64_t Padding = OffsetToAlignment(OS.tell(), Alignment);
> + uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment);
> WriteZeros(Padding);
> }
>
> @@ -764,7 +764,7 @@ void ELFObjectWriter::computeSymbolTable
> SymbolTableIndex = addToSectionTable(SymtabSection);
>
> align(SymtabSection->getAlignment());
> - uint64_t SecStart = OS.tell();
> + uint64_t SecStart = getStream().tell();
>
> // The first entry is the undefined symbol entry.
> Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
> @@ -911,7 +911,7 @@ void ELFObjectWriter::computeSymbolTable
> assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
> }
>
> - uint64_t SecEnd = OS.tell();
> + uint64_t SecEnd = getStream().tell();
> SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
>
> ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
> @@ -921,12 +921,12 @@ void ELFObjectWriter::computeSymbolTable
> }
> assert(SymtabShndxSectionIndex != 0);
>
> - SecStart = OS.tell();
> + SecStart = getStream().tell();
> const MCSectionELF *SymtabShndxSection =
> SectionTable[SymtabShndxSectionIndex - 1];
> for (uint32_t Index : ShndxIndexes)
> write(Index);
> - SecEnd = OS.tell();
> + SecEnd = getStream().tell();
> SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
> }
>
> @@ -957,31 +957,6 @@ ELFObjectWriter::createRelocationSection
> return RelaSection;
> }
>
> -static SmallVector<char, 128>
> -getUncompressedData(const MCAsmLayout &Layout,
> - const MCSection::FragmentListType &Fragments) {
> - SmallVector<char, 128> UncompressedData;
> - for (const MCFragment &F : Fragments) {
> - const SmallVectorImpl<char> *Contents;
> - switch (F.getKind()) {
> - case MCFragment::FT_Data:
> - Contents = &cast<MCDataFragment>(F).getContents();
> - break;
> - case MCFragment::FT_Dwarf:
> - Contents = &cast<MCDwarfLineAddrFragment>(F).getContents();
> - break;
> - case MCFragment::FT_DwarfFrame:
> - Contents = &cast<MCDwarfCallFrameFragment>(F).getContents();
> - break;
> - default:
> - llvm_unreachable(
> - "Not expecting any other fragment types in a debug_* section");
> - }
> - UncompressedData.append(Contents->begin(), Contents->end());
> - }
> - return UncompressedData;
> -}
> -
> // Include the debug info compression header:
> // "ZLIB" followed by 8 bytes representing the uncompressed size of the
> section,
> // useful for consumers to preallocate a buffer to decompress into.
> @@ -1016,27 +991,29 @@ void ELFObjectWriter::writeSectionData(c
> return;
> }
>
> - // Gather the uncompressed data from all the fragments.
> - const MCSection::FragmentListType &Fragments =
> Section.getFragmentList();
> - SmallVector<char, 128> UncompressedData =
> - getUncompressedData(Layout, Fragments);
> + SmallVector<char, 128> UncompressedData;
> + raw_svector_ostream VecOS(UncompressedData);
> + raw_pwrite_stream &OldStream = getStream();
> + setStream(VecOS);
> + Asm.writeSectionData(&Section, Layout);
> + setStream(OldStream);
>
> SmallVector<char, 128> CompressedContents;
> zlib::Status Success = zlib::compress(
> StringRef(UncompressedData.data(), UncompressedData.size()),
> CompressedContents);
> if (Success != zlib::StatusOK) {
> - Asm.writeSectionData(&Section, Layout);
> + getStream() << UncompressedData;
> return;
> }
>
> if (!prependCompressionHeader(UncompressedData.size(),
> CompressedContents)) {
> - Asm.writeSectionData(&Section, Layout);
> + getStream() << UncompressedData;
> return;
> }
> Asm.getContext().renameELFSection(&Section,
> (".z" +
> SectionName.drop_front(1)).str());
> - OS << CompressedContents;
> + getStream() << CompressedContents;
> }
>
> void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
> @@ -1100,7 +1077,7 @@ void ELFObjectWriter::writeRelocations(c
>
> const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) {
> const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
> - OS << StrTabBuilder.data();
> + getStream() << StrTabBuilder.data();
> return StrtabSection;
> }
>
> @@ -1209,12 +1186,12 @@ void ELFObjectWriter::writeObject(MCAsse
> align(Section.getAlignment());
>
> // Remember the offset into the file for this section.
> - uint64_t SecStart = OS.tell();
> + uint64_t SecStart = getStream().tell();
>
> const MCSymbolELF *SignatureSymbol = Section.getGroup();
> writeSectionData(Asm, Section, Layout);
>
> - uint64_t SecEnd = OS.tell();
> + uint64_t SecEnd = getStream().tell();
> SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
>
> MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
> @@ -1246,7 +1223,7 @@ void ELFObjectWriter::writeObject(MCAsse
> align(Group->getAlignment());
>
> // Remember the offset into the file for this section.
> - uint64_t SecStart = OS.tell();
> + uint64_t SecStart = getStream().tell();
>
> const MCSymbol *SignatureSymbol = Group->getGroup();
> assert(SignatureSymbol);
> @@ -1256,7 +1233,7 @@ void ELFObjectWriter::writeObject(MCAsse
> write(SecIndex);
> }
>
> - uint64_t SecEnd = OS.tell();
> + uint64_t SecEnd = getStream().tell();
> SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
> }
>
> @@ -1267,25 +1244,25 @@ void ELFObjectWriter::writeObject(MCAsse
> align(RelSection->getAlignment());
>
> // Remember the offset into the file for this section.
> - uint64_t SecStart = OS.tell();
> + uint64_t SecStart = getStream().tell();
>
> writeRelocations(Asm, *RelSection->getAssociatedSection());
>
> - uint64_t SecEnd = OS.tell();
> + uint64_t SecEnd = getStream().tell();
> SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
> }
>
> {
> - uint64_t SecStart = OS.tell();
> + uint64_t SecStart = getStream().tell();
> const MCSectionELF *Sec = createStringTable(Ctx);
> - uint64_t SecEnd = OS.tell();
> + uint64_t SecEnd = getStream().tell();
> SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
> }
>
> uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
> align(NaturalAlignment);
>
> - const unsigned SectionHeaderOffset = OS.tell();
> + const unsigned SectionHeaderOffset = getStream().tell();
>
> // ... then the section header table ...
> writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
> @@ -1301,19 +1278,19 @@ void ELFObjectWriter::writeObject(MCAsse
> uint64_t Val = SectionHeaderOffset;
> if (sys::IsLittleEndianHost != IsLittleEndian)
> sys::swapByteOrder(Val);
> - OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
> - offsetof(ELF::Elf64_Ehdr, e_shoff));
> + getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
> + offsetof(ELF::Elf64_Ehdr, e_shoff));
> NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
> } else {
> uint32_t Val = SectionHeaderOffset;
> if (sys::IsLittleEndianHost != IsLittleEndian)
> sys::swapByteOrder(Val);
> - OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
> - offsetof(ELF::Elf32_Ehdr, e_shoff));
> + getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
> + offsetof(ELF::Elf32_Ehdr, e_shoff));
> NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
> }
> - OS.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
> - NumSectionsOffset);
> + getStream().pwrite(reinterpret_cast<char *>(&NumSections),
> + sizeof(NumSections), NumSectionsOffset);
> }
>
> bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
>
> Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=246554&r1=246553&r2=246554&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Tue Sep 1 11:19:03 2015
> @@ -129,7 +129,7 @@ void MachObjectWriter::writeHeader(MachO
> // struct mach_header (28 bytes) or
> // struct mach_header_64 (32 bytes)
>
> - uint64_t Start = OS.tell();
> + uint64_t Start = getStream().tell();
> (void) Start;
>
> write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
> @@ -144,8 +144,9 @@ void MachObjectWriter::writeHeader(MachO
> if (is64Bit())
> write32(0); // reserved
>
> - assert(OS.tell() - Start ==
> - (is64Bit()?sizeof(MachO::mach_header_64):
> sizeof(MachO::mach_header)));
> + assert(
> + getStream().tell() - Start ==
> + (is64Bit() ? sizeof(MachO::mach_header_64) :
> sizeof(MachO::mach_header)));
> }
>
> /// writeSegmentLoadCommand - Write a segment load command.
> @@ -159,7 +160,7 @@ void MachObjectWriter::writeSegmentLoadC
> // struct segment_command (56 bytes) or
> // struct segment_command_64 (72 bytes)
>
> - uint64_t Start = OS.tell();
> + uint64_t Start = getStream().tell();
> (void) Start;
>
> unsigned SegmentLoadCommandSize =
> @@ -190,7 +191,7 @@ void MachObjectWriter::writeSegmentLoadC
> write32(NumSections);
> write32(0); // flags
>
> - assert(OS.tell() - Start == SegmentLoadCommandSize);
> + assert(getStream().tell() - Start == SegmentLoadCommandSize);
> }
>
> void MachObjectWriter::writeSection(const MCAsmLayout &Layout,
> @@ -210,7 +211,7 @@ void MachObjectWriter::writeSection(cons
> // struct section (68 bytes) or
> // struct section_64 (80 bytes)
>
> - uint64_t Start = OS.tell();
> + uint64_t Start = getStream().tell();
> (void) Start;
>
> writeBytes(Section.getSectionName(), 16);
> @@ -234,8 +235,8 @@ void MachObjectWriter::writeSection(cons
> if (is64Bit())
> write32(0); // reserved3
>
> - assert(OS.tell() - Start == (is64Bit() ? sizeof(MachO::section_64) :
> - sizeof(MachO::section)));
> + assert(getStream().tell() - Start ==
> + (is64Bit() ? sizeof(MachO::section_64) :
> sizeof(MachO::section)));
> }
>
> void MachObjectWriter::writeSymtabLoadCommand(uint32_t SymbolOffset,
> @@ -244,7 +245,7 @@ void MachObjectWriter::writeSymtabLoadCo
> uint32_t StringTableSize) {
> // struct symtab_command (24 bytes)
>
> - uint64_t Start = OS.tell();
> + uint64_t Start = getStream().tell();
> (void) Start;
>
> write32(MachO::LC_SYMTAB);
> @@ -254,7 +255,7 @@ void MachObjectWriter::writeSymtabLoadCo
> write32(StringTableOffset);
> write32(StringTableSize);
>
> - assert(OS.tell() - Start == sizeof(MachO::symtab_command));
> + assert(getStream().tell() - Start == sizeof(MachO::symtab_command));
> }
>
> void MachObjectWriter::writeDysymtabLoadCommand(uint32_t FirstLocalSymbol,
> @@ -267,7 +268,7 @@ void MachObjectWriter::writeDysymtabLoad
> uint32_t
> NumIndirectSymbols) {
> // struct dysymtab_command (80 bytes)
>
> - uint64_t Start = OS.tell();
> + uint64_t Start = getStream().tell();
> (void) Start;
>
> write32(MachO::LC_DYSYMTAB);
> @@ -291,7 +292,7 @@ void MachObjectWriter::writeDysymtabLoad
> write32(0); // locreloff
> write32(0); // nlocrel
>
> - assert(OS.tell() - Start == sizeof(MachO::dysymtab_command));
> + assert(getStream().tell() - Start == sizeof(MachO::dysymtab_command));
> }
>
> MachObjectWriter::MachSymbolData *
> @@ -387,7 +388,7 @@ void MachObjectWriter::writeNlist(MachSy
> void MachObjectWriter::writeLinkeditLoadCommand(uint32_t Type,
> uint32_t DataOffset,
> uint32_t DataSize) {
> - uint64_t Start = OS.tell();
> + uint64_t Start = getStream().tell();
> (void) Start;
>
> write32(Type);
> @@ -395,7 +396,7 @@ void MachObjectWriter::writeLinkeditLoad
> write32(DataOffset);
> write32(DataSize);
>
> - assert(OS.tell() - Start == sizeof(MachO::linkedit_data_command));
> + assert(getStream().tell() - Start ==
> sizeof(MachO::linkedit_data_command));
> }
>
> static unsigned ComputeLinkerOptionsLoadCommandSize(
> @@ -411,7 +412,7 @@ void MachObjectWriter::writeLinkerOption
> const std::vector<std::string> &Options)
> {
> unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
> - uint64_t Start = OS.tell();
> + uint64_t Start = getStream().tell();
> (void) Start;
>
> write32(MachO::LC_LINKER_OPTION);
> @@ -427,7 +428,7 @@ void MachObjectWriter::writeLinkerOption
> // Pad to a multiple of the pointer size.
> writeBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
>
> - assert(OS.tell() - Start == Size);
> + assert(getStream().tell() - Start == Size);
> }
>
> void MachObjectWriter::recordRelocation(MCAssembler &Asm,
> @@ -906,12 +907,12 @@ void MachObjectWriter::writeObject(MCAss
> // Write out the loh commands, if there is one.
> if (LOHSize) {
> #ifndef NDEBUG
> - unsigned Start = OS.tell();
> + unsigned Start = getStream().tell();
> #endif
> Asm.getLOHContainer().emit(*this, Layout);
> // Pad to a multiple of the pointer size.
> writeBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
> - assert(OS.tell() - Start == LOHSize);
> + assert(getStream().tell() - Start == LOHSize);
> }
>
> // Write the symbol table data, if used.
> @@ -947,7 +948,7 @@ void MachObjectWriter::writeObject(MCAss
> writeNlist(Entry, Layout);
>
> // Write the string table.
> - OS << StringTable.data();
> + getStream() << StringTable.data();
> }
> }
>
>
> Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=246554&r1=246553&r2=246554&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Tue Sep 1 11:19:03 2015
> @@ -1037,10 +1037,11 @@ void WinCOFFObjectWriter::writeObject(MC
> continue;
>
> if ((*i)->Header.PointerToRawData != 0) {
> - assert(OS.tell() <= (*i)->Header.PointerToRawData &&
> + assert(getStream().tell() <= (*i)->Header.PointerToRawData &&
> "Section::PointerToRawData is insane!");
>
> - unsigned SectionDataPadding = (*i)->Header.PointerToRawData -
> OS.tell();
> + unsigned SectionDataPadding =
> + (*i)->Header.PointerToRawData - getStream().tell();
> assert(SectionDataPadding < 4 &&
> "Should only need at most three bytes of padding!");
>
> @@ -1050,7 +1051,7 @@ void WinCOFFObjectWriter::writeObject(MC
> }
>
> if ((*i)->Relocations.size() > 0) {
> - assert(OS.tell() == (*i)->Header.PointerToRelocations &&
> + assert(getStream().tell() == (*i)->Header.PointerToRelocations &&
> "Section::PointerToRelocations is insane!");
>
> if ((*i)->Relocations.size() >= 0xffff) {
> @@ -1071,14 +1072,14 @@ void WinCOFFObjectWriter::writeObject(MC
> }
> }
>
> - assert(OS.tell() == Header.PointerToSymbolTable &&
> + assert(getStream().tell() == Header.PointerToSymbolTable &&
> "Header::PointerToSymbolTable is insane!");
>
> for (auto &Symbol : Symbols)
> if (Symbol->getIndex() != -1)
> WriteSymbol(*Symbol);
>
> - OS.write(Strings.data().data(), Strings.data().size());
> + getStream().write(Strings.data().data(), Strings.data().size());
> }
>
> MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned
> Machine_)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150902/91f04a71/attachment.html>
More information about the llvm-commits
mailing list