[llvm] r313374 - Fix Bug 30978 by emitting cv file checksums.
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 15 14:11:24 PDT 2017
On Fri, Sep 15, 2017 at 11:20 AM, Eric Beckmann via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: ecbeckmann
> Date: Fri Sep 15 11:20:28 2017
> New Revision: 313374
>
> URL: http://llvm.org/viewvc/llvm-project?rev=313374&view=rev
> Log:
> Fix Bug 30978 by emitting cv file checksums.
>
> Summary:
> The checksums had already been placed in the IR, this patch allows
> MCCodeView to actually write it out to an MCStreamer.
>
> Subscribers: llvm-commits, hiraditya
>
> Differential Revision: https://reviews.llvm.org/D37157
>
> Modified:
> llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
> llvm/trunk/include/llvm/MC/MCCodeView.h
> llvm/trunk/include/llvm/MC/MCObjectStreamer.h
> llvm/trunk/include/llvm/MC/MCStreamer.h
> llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
> llvm/trunk/lib/IR/DebugInfoMetadata.cpp
> llvm/trunk/lib/MC/MCAsmStreamer.cpp
> llvm/trunk/lib/MC/MCCodeView.cpp
> llvm/trunk/lib/MC/MCObjectStreamer.cpp
> llvm/trunk/lib/MC/MCParser/AsmParser.cpp
> llvm/trunk/lib/MC/MCStreamer.cpp
> llvm/trunk/test/DebugInfo/COFF/inlining.ll
> llvm/trunk/test/DebugInfo/COFF/multifile.ll
> llvm/trunk/test/DebugInfo/COFF/simple.ll
> llvm/trunk/test/MC/AArch64/coff-debug.ll
> llvm/trunk/unittests/IR/MetadataTest.cpp
>
> Modified: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/IR/DebugInfoMetadata.h?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h (original)
> +++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h Fri Sep 15 11:20:28
> 2017
> @@ -473,10 +473,12 @@ class DIFile : public DIScope {
> friend class MDNode;
>
> public:
> + // These values must be explictly set, as they end up in the final
> object
> + // file.
>
This seems weird. Shouldn't we separate this from what we actually encode
and translate it to the codeview specific CHKSUM_TYPE_MD5/CHKSUM_TYPE_SHA1?
I know that the conversion would be trivial but this seems like a bit of a
layering violation, especially considering that we encode the ChecksumKind
in the bitcode itself...
> enum ChecksumKind {
> - CSK_None,
> - CSK_MD5,
> - CSK_SHA1,
> + CSK_None = 0,
> + CSK_MD5 = 1,
> + CSK_SHA1 = 2,
> CSK_Last = CSK_SHA1 // Should be last enumeration.
> };
>
> @@ -510,7 +512,7 @@ public:
> ChecksumKind CSK = CSK_None,
> StringRef CS = StringRef()),
> (Filename, Directory, CSK, CS))
> - DEFINE_MDNODE_GET(DIFile, (MDString *Filename, MDString *Directory,
> + DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
> ChecksumKind CSK = CSK_None,
> MDString *CS = nullptr),
> (Filename, Directory, CSK, CS))
>
> Modified: llvm/trunk/include/llvm/MC/MCCodeView.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/MC/MCCodeView.h?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/MC/MCCodeView.h (original)
> +++ llvm/trunk/include/llvm/MC/MCCodeView.h Fri Sep 15 11:20:28 2017
> @@ -161,8 +161,8 @@ public:
> ~CodeViewContext();
>
> bool isValidFileNumber(unsigned FileNumber) const;
> - bool addFile(unsigned FileNumber, StringRef Filename);
> - ArrayRef<StringRef> getFilenames() { return Filenames; }
> + bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
> + StringRef Checksum, uint8_t ChecksumKind);
>
> /// Records the function id of a normal function. Returns false if the
> /// function id has already been used, and true otherwise.
> @@ -273,6 +273,9 @@ public:
> /// Emits the file checksum substream.
> void emitFileChecksums(MCObjectStreamer &OS);
>
> + /// Emits the offset into the checksum table of the given file number.
> + void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
> +
> private:
> /// The current CodeView line information from the last .cv_loc
> directive.
> MCCVLoc CurrentCVLoc = MCCVLoc(0, 0, 0, 0, false, true);
> @@ -287,14 +290,30 @@ private:
>
> MCDataFragment *getStringTableFragment();
>
> - /// Add something to the string table.
> - StringRef addToStringTable(StringRef S);
> + /// Add something to the string table. Returns the final string as
> well as
> + /// offset into the string table.
> + std::pair<StringRef, unsigned> addToStringTable(StringRef S);
>
> /// Get a string table offset.
> unsigned getStringTableOffset(StringRef S);
>
> - /// An array of absolute paths. Eventually this may include the file
> checksum.
> - SmallVector<StringRef, 4> Filenames;
> + struct FileInfo {
> + unsigned StringTableOffset;
> +
> + // Checksum offset stored as a symbol because it might be requested
> + // before it has been calculated, so a fixup may be needed.
> + MCSymbol *ChecksumTableOffset;
> +
> + // Indicates if this FileInfo corresponds to an actual file, or
> hasn't been
> + // set yet.
> + bool Assigned = false;
> +
> + std::string Checksum;
> + uint8_t ChecksumKind;
> + };
> +
> + /// Array storing added file information.
> + SmallVector<FileInfo, 4> Files;
>
> /// The offset of the first and last .cv_loc directive for a given
> function
> /// id.
> @@ -305,6 +324,10 @@ private:
>
> /// All known functions and inlined call sites, indexed by function id.
> std::vector<MCCVFunctionInfo> Functions;
> +
> + /// Indicate whether we have already laid out the checksum table
> addresses or
> + /// not.
> + bool ChecksumOffsetsAssigned = false;
> };
>
> } // end namespace llvm
>
> Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/MC/MCObjectStreamer.h?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Fri Sep 15 11:20:28 2017
> @@ -140,6 +140,7 @@ public:
> StringRef FixedSizePortion) override;
> void EmitCVStringTableDirective() override;
> void EmitCVFileChecksumsDirective() override;
> + void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
> void EmitDTPRel32Value(const MCExpr *Value) override;
> void EmitDTPRel64Value(const MCExpr *Value) override;
> void EmitTPRel32Value(const MCExpr *Value) override;
>
> Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/MC/MCStreamer.h?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCStreamer.h Fri Sep 15 11:20:28 2017
> @@ -729,10 +729,11 @@ public:
> unsigned Isa, unsigned Discriminator,
> StringRef FileName);
>
> - /// \brief Associate a filename with a specified logical file number.
> This
> - /// implements the '.cv_file 4 "foo.c"' assembler directive. Returns
> true on
> - /// success.
> - virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename);
> + /// Associate a filename with a specified logical file number, and also
> + /// specify that file's checksum information. This implements the
> '.cv_file 4
> + /// "foo.c"' assembler directive. Returns true on success.
> + virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
> + StringRef Checksum, unsigned
> ChecksumKind);
>
> /// \brief Introduces a function id for use with .cv_loc.
> virtual bool EmitCVFuncIdDirective(unsigned FunctionId);
> @@ -774,6 +775,10 @@ public:
> /// \brief This implements the CodeView '.cv_filechecksums' assembler
> directive.
> virtual void EmitCVFileChecksumsDirective() {}
>
> + /// This implements the CodeView '.cv_filechecksumoffset' assembler
> + /// directive.
> + virtual void EmitCVFileChecksumOffsetDirective(unsigned FileNo) {}
> +
> /// Emit the absolute difference between two symbols.
> ///
> /// \pre Offset of \c Hi is greater than the offset \c Lo.
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=313374&
> r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri Sep 15
> 11:20:28 2017
> @@ -159,7 +159,10 @@ unsigned CodeViewDebug::maybeRecordFile(
> if (Insertion.second) {
> // We have to compute the full filepath and emit a .cv_file directive.
> StringRef FullPath = getFullFilepath(F);
> - bool Success = OS.EmitCVFileDirective(NextId, FullPath);
> + StringRef Checksum = F->getChecksum();
> + DIFile::ChecksumKind ChecksumKind = F->getChecksumKind();
> + bool Success = OS.EmitCVFileDirective(NextId, FullPath, Checksum,
> + static_cast<unsigned>(
> ChecksumKind));
> (void)Success;
> assert(Success && ".cv_file directive failed");
> }
> @@ -681,8 +684,10 @@ void CodeViewDebug::emitInlineeLinesSubs
> OS.AddComment("Inlinee lines subsection");
> MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::
> InlineeLines);
>
> - // We don't provide any extra file info.
> - // FIXME: Find out if debuggers use this info.
> + // We emit the checksum info for files. This is used by debuggers to
> + // determine if a pdb matches the source before loading it. Visual
> Studio,
> + // for instance, will display a warning that the breakpoints are not
> valid if
> + // the pdb does not match the source.
> OS.AddComment("Inlinee lines signature");
> OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);
>
> @@ -695,13 +700,10 @@ void CodeViewDebug::emitInlineeLinesSubs
> OS.AddComment("Inlined function " + SP->getName() + " starts at " +
> SP->getFilename() + Twine(':') + Twine(SP->getLine()));
> OS.AddBlankLine();
> - // The filechecksum table uses 8 byte entries for now, and file ids
> start at
> - // 1.
> - unsigned FileOffset = (FileId - 1) * 8;
> OS.AddComment("Type index of inlined function");
> OS.EmitIntValue(InlineeIdx.getIndex(), 4);
> OS.AddComment("Offset into filechecksum table");
> - OS.EmitIntValue(FileOffset, 4);
> + OS.EmitCVFileChecksumOffsetDirective(FileId);
> OS.AddComment("Starting line number");
> OS.EmitIntValue(SP->getLine(), 4);
> }
>
> Modified: llvm/trunk/lib/IR/DebugInfoMetadata.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/
> DebugInfoMetadata.cpp?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/IR/DebugInfoMetadata.cpp (original)
> +++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp Fri Sep 15 11:20:28 2017
> @@ -354,6 +354,8 @@ DISubroutineType *DISubroutineType::getI
> DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
> }
>
> +// FIXME: Implement this string-enum correspondence with a .def file and
> macros,
> +// so that the association is explicit rather than implied.
> static const char *ChecksumKindName[DIFile::CSK_Last + 1] = {
> "CSK_None",
> "CSK_MD5",
>
> Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCAsmStreamer.cpp?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Fri Sep 15 11:20:28 2017
> @@ -225,7 +225,8 @@ public:
> StringRef FileName) override;
> MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
>
> - bool EmitCVFileDirective(unsigned FileNo, StringRef Filename) override;
> + bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
> + StringRef Checksum, unsigned ChecksumKind)
> override;
> bool EmitCVFuncIdDirective(unsigned FuncId) override;
> bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
> unsigned IAFile, unsigned IALine,
> @@ -245,6 +246,7 @@ public:
> StringRef FixedSizePortion) override;
> void EmitCVStringTableDirective() override;
> void EmitCVFileChecksumsDirective() override;
> + void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
>
> void EmitIdent(StringRef IdentString) override;
> void EmitCFISections(bool EH, bool Debug) override;
> @@ -1120,13 +1122,25 @@ MCSymbol *MCAsmStreamer::getDwarfLineTab
> return MCStreamer::getDwarfLineTableSymbol(0);
> }
>
> -bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef
> Filename) {
> - if (!getContext().getCVContext().addFile(FileNo, Filename))
> +bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef
> Filename,
> + StringRef Checksum,
> + unsigned ChecksumKind) {
> + if (!getContext().getCVContext().addFile(*this, FileNo, Filename,
> Checksum,
> + ChecksumKind))
> return false;
>
> OS << "\t.cv_file\t" << FileNo << ' ';
> -
> PrintQuotedString(Filename, OS);
> +
> + if (!ChecksumKind) {
> + EmitEOL();
> + return true;
> + }
> +
> + OS << ' ';
> + PrintQuotedString(Checksum, OS);
> + OS << ' ' << ChecksumKind;
> +
> EmitEOL();
> return true;
> }
> @@ -1228,6 +1242,11 @@ void MCAsmStreamer::EmitCVFileChecksumsD
> EmitEOL();
> }
>
> +void MCAsmStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
> + OS << "\t.cv_filechecksumoffset\t" << FileNo;
> + EmitEOL();
> +}
> +
> void MCAsmStreamer::EmitIdent(StringRef IdentString) {
> assert(MAI->hasIdentDirective() && ".ident directive not supported");
> OS << "\t.ident\t";
>
> Modified: llvm/trunk/lib/MC/MCCodeView.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCCodeView.cpp?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCCodeView.cpp (original)
> +++ llvm/trunk/lib/MC/MCCodeView.cpp Fri Sep 15 11:20:28 2017
> @@ -39,29 +39,39 @@ CodeViewContext::~CodeViewContext() {
> /// for it.
> bool CodeViewContext::isValidFileNumber(unsigned FileNumber) const {
> unsigned Idx = FileNumber - 1;
> - if (Idx < Filenames.size())
> - return !Filenames[Idx].empty();
> + if (Idx < Files.size())
> + return Files[Idx].Assigned;
> return false;
> }
>
> -bool CodeViewContext::addFile(unsigned FileNumber, StringRef Filename) {
> +bool CodeViewContext::addFile(MCStreamer &OS, unsigned FileNumber,
> + StringRef Filename, StringRef Checksum,
> + uint8_t ChecksumKind) {
> assert(FileNumber > 0);
> - Filename = addToStringTable(Filename);
> + auto FilenameOffset = addToStringTable(Filename);
> + Filename = FilenameOffset.first;
> unsigned Idx = FileNumber - 1;
> - if (Idx >= Filenames.size())
> - Filenames.resize(Idx + 1);
> + if (Idx >= Files.size())
> + Files.resize(Idx + 1);
>
> if (Filename.empty())
> Filename = "<stdin>";
>
> - if (!Filenames[Idx].empty())
> + if (Files[Idx].Assigned)
> return false;
>
> - // FIXME: We should store the string table offset of the filename,
> rather than
> - // the filename itself for efficiency.
> - Filename = addToStringTable(Filename);
> + FilenameOffset = addToStringTable(Filename);
> + Filename = FilenameOffset.first;
> + unsigned Offset = FilenameOffset.second;
> +
> + auto ChecksumOffsetSymbol =
> + OS.getContext().createTempSymbol("checksum_offset", false);
> + Files[Idx].StringTableOffset = Offset;
> + Files[Idx].ChecksumTableOffset = ChecksumOffsetSymbol;
> + Files[Idx].Assigned = true;
> + Files[Idx].Checksum = Checksum.str();
> + Files[Idx].ChecksumKind = ChecksumKind;
>
> - Filenames[Idx] = Filename;
> return true;
> }
>
> @@ -118,17 +128,18 @@ MCDataFragment *CodeViewContext::getStri
> return StrTabFragment;
> }
>
> -StringRef CodeViewContext::addToStringTable(StringRef S) {
> +std::pair<StringRef, unsigned> CodeViewContext::addToStringTable(StringRef
> S) {
> SmallVectorImpl<char> &Contents = getStringTableFragment()->
> getContents();
> auto Insertion =
> StringTable.insert(std::make_pair(S, unsigned(Contents.size())));
> // Return the string from the table, since it is stable.
> - S = Insertion.first->first();
> + std::pair<StringRef, unsigned> Ret =
> + std::make_pair(Insertion.first->first(), Insertion.first->second);
> if (Insertion.second) {
> // The string map key is always null terminated.
> - Contents.append(S.begin(), S.end() + 1);
> + Contents.append(Ret.first.begin(), Ret.first.end() + 1);
> }
> - return S;
> + return Ret;
> }
>
> unsigned CodeViewContext::getStringTableOffset(StringRef S) {
> @@ -165,7 +176,7 @@ void CodeViewContext::emitStringTable(MC
> void CodeViewContext::emitFileChecksums(MCObjectStreamer &OS) {
> // Do nothing if there are no file checksums. Microsoft's linker
> rejects empty
> // CodeView substreams.
> - if (Filenames.empty())
> + if (Files.empty())
> return;
>
> MCContext &Ctx = OS.getContext();
> @@ -176,17 +187,63 @@ void CodeViewContext::emitFileChecksums(
> OS.emitAbsoluteSymbolDiff(FileEnd, FileBegin, 4);
> OS.EmitLabel(FileBegin);
>
> + unsigned CurrentOffset = 0;
> +
> // Emit an array of FileChecksum entries. We index into this table
> using the
> - // user-provided file number. Each entry is currently 8 bytes, as we
> don't
> - // emit checksums.
> - for (StringRef Filename : Filenames) {
> - OS.EmitIntValue(getStringTableOffset(Filename), 4);
> - // Zero the next two fields and align back to 4 bytes. This indicates
> that
> - // no checksum is present.
> - OS.EmitIntValue(0, 4);
> + // user-provided file number. Each entry may be a variable number of
> bytes
> + // determined by the checksum kind and size.
> + for (auto File : Files) {
> + OS.EmitAssignment(File.ChecksumTableOffset,
> + MCConstantExpr::create(CurrentOffset, Ctx));
> + CurrentOffset += 4; // String table offset.
> + if (!File.ChecksumKind) {
> + CurrentOffset +=
> + 4; // One byte each for checksum size and kind, then align to 4
> bytes.
> + } else {
> + CurrentOffset += 2; // One byte each for checksum size and kind.
> + CurrentOffset += File.Checksum.size();
> + CurrentOffset = alignTo(CurrentOffset, 4);
> + }
> +
> + OS.EmitIntValue(File.StringTableOffset, 4);
> +
> + if (!File.ChecksumKind) {
> + // There is no checksum. Therefore zero the next two fields and
> align
> + // back to 4 bytes.
> + OS.EmitIntValue(0, 4);
> + continue;
> + }
> + OS.EmitIntValue(static_cast<uint8_t>(File.Checksum.size()), 1);
> + OS.EmitIntValue(File.ChecksumKind, 1);
> + OS.EmitBytes(File.Checksum);
> + OS.EmitValueToAlignment(4);
> }
>
> OS.EmitLabel(FileEnd);
> +
> + ChecksumOffsetsAssigned = true;
> +}
> +
> +// Output checksum table offset of the given file number. It is possible
> that
> +// not all files have been registered yet, and so the offset cannot be
> +// calculated. In this case a symbol representing the offset is emitted,
> and
> +// the value of this symbol will be fixed up at a later time.
> +void CodeViewContext::emitFileChecksumOffset(MCObjectStreamer &OS,
> + unsigned FileNo) {
> + unsigned Idx = FileNo - 1;
> +
> + if (Idx >= Files.size())
> + Files.resize(Idx + 1);
> +
> + if (ChecksumOffsetsAssigned) {
> + OS.EmitSymbolValue(Files[Idx].ChecksumTableOffset, 4);
> + return;
> + }
> +
> + const MCSymbolRefExpr *SRE =
> + MCSymbolRefExpr::create(Files[Idx].ChecksumTableOffset,
> OS.getContext());
> +
> + OS.EmitValueImpl(SRE, 4);
> }
>
> void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
> @@ -219,9 +276,12 @@ void CodeViewContext::emitLineTableForFu
> return Loc.getFileNum() != CurFileNum;
> });
> unsigned EntryCount = FileSegEnd - I;
> - OS.AddComment("Segment for file '" + Twine(Filenames[CurFileNum - 1])
> +
> - "' begins");
> - OS.EmitIntValue(8 * (CurFileNum - 1), 4);
> + OS.AddComment(
> + "Segment for file '" +
> + Twine(getStringTableFragment()
> + ->getContents()[Files[CurFileNum -
> 1].StringTableOffset]) +
> + "' begins");
> + OS.EmitCVFileChecksumOffsetDirective(CurFileNum);
> OS.EmitIntValue(EntryCount, 4);
> uint32_t SegmentSize = 12;
> SegmentSize += 8 * EntryCount;
> @@ -401,9 +461,10 @@ void CodeViewContext::encodeInlineLineTa
> HaveOpenRange = true;
>
> if (CurSourceLoc.File != LastSourceLoc.File) {
> - // File ids are 1 based, and each file checksum table entry is 8
> bytes
> - // long. See emitFileChecksums above.
> - unsigned FileOffset = 8 * (CurSourceLoc.File - 1);
> + unsigned FileOffset = static_cast<const MCConstantExpr *>(
> + Files[CurSourceLoc.File - 1]
> + .ChecksumTableOffset->
> getVariableValue())
> + ->getValue();
> compressAnnotation(BinaryAnnotationsOpCode::ChangeFile, Buffer);
> compressAnnotation(FileOffset, Buffer);
> }
>
> Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCObjectStreamer.cpp?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Fri Sep 15 11:20:28 2017
> @@ -426,6 +426,9 @@ void MCObjectStreamer::EmitCVFileChecksu
> getContext().getCVContext().emitFileChecksums(*this);
> }
>
> +void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned
> FileNo) {
> + getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
> +}
>
> void MCObjectStreamer::EmitBytes(StringRef Data) {
> MCCVLineEntry::Make(this);
>
> Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCParser/AsmParser.cpp?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
> +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Fri Sep 15 11:20:28 2017
> @@ -501,6 +501,7 @@ private:
> DK_CV_DEF_RANGE,
> DK_CV_STRINGTABLE,
> DK_CV_FILECHECKSUMS,
> + DK_CV_FILECHECKSUM_OFFSET,
> DK_CFI_SECTIONS,
> DK_CFI_STARTPROC,
> DK_CFI_ENDPROC,
> @@ -576,6 +577,7 @@ private:
> bool parseDirectiveCVDefRange();
> bool parseDirectiveCVStringTable();
> bool parseDirectiveCVFileChecksums();
> + bool parseDirectiveCVFileChecksumOffset();
>
> // .cfi directives
> bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
> @@ -2030,6 +2032,8 @@ bool AsmParser::parseStatement(ParseStat
> return parseDirectiveCVStringTable();
> case DK_CV_FILECHECKSUMS:
> return parseDirectiveCVFileChecksums();
> + case DK_CV_FILECHECKSUM_OFFSET:
> + return parseDirectiveCVFileChecksumOffset();
> case DK_CFI_SECTIONS:
> return parseDirectiveCFISections();
> case DK_CFI_STARTPROC:
> @@ -3457,25 +3461,34 @@ bool AsmParser::parseDirectiveStabs() {
> }
>
> /// parseDirectiveCVFile
> -/// ::= .cv_file number filename
> +/// ::= .cv_file number filename [checksum] [checksumkind]
> bool AsmParser::parseDirectiveCVFile() {
> SMLoc FileNumberLoc = getTok().getLoc();
> int64_t FileNumber;
> std::string Filename;
> + std::string Checksum;
> + int64_t ChecksumKind = 0;
>
> if (parseIntToken(FileNumber,
> "expected file number in '.cv_file' directive") ||
> check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
> check(getTok().isNot(AsmToken::String),
> "unexpected token in '.cv_file' directive") ||
> - // Usually directory and filename are together, otherwise just
> - // directory. Allow the strings to have escaped octal character
> sequence.
> - parseEscapedString(Filename) ||
> - parseToken(AsmToken::EndOfStatement,
> - "unexpected token in '.cv_file' directive"))
> + parseEscapedString(Filename))
> return true;
> + if (!parseOptionalToken(AsmToken::EndOfStatement)) {
> + if (check(getTok().isNot(AsmToken::String),
> + "unexpected token in '.cv_file' directive") ||
> + parseEscapedString(Checksum) ||
> + parseIntToken(ChecksumKind,
> + "expected checksum kind in '.cv_file' directive") ||
> + parseToken(AsmToken::EndOfStatement,
> + "unexpected token in '.cv_file' directive"))
> + return true;
> + }
>
> - if (!getStreamer().EmitCVFileDirective(FileNumber, Filename))
> + if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, Checksum,
> + static_cast<uint8_t>(
> ChecksumKind)))
> return Error(FileNumberLoc, "file number already allocated");
>
> return false;
> @@ -3754,6 +3767,18 @@ bool AsmParser::parseDirectiveCVFileChec
> return false;
> }
>
> +/// parseDirectiveCVFileChecksumOffset
> +/// ::= .cv_filechecksumoffset fileno
> +bool AsmParser::parseDirectiveCVFileChecksumOffset() {
> + int64_t FileNo;
> + if (parseIntToken(FileNo, "expected identifier in directive"))
> + return true;
> + if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
> + return true;
> + getStreamer().EmitCVFileChecksumOffsetDirective(FileNo);
> + return false;
> +}
> +
> /// parseDirectiveCFISections
> /// ::= .cfi_sections section [, section]
> bool AsmParser::parseDirectiveCFISections() {
> @@ -5136,6 +5161,7 @@ void AsmParser::initializeDirectiveKindM
> DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
> DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
> DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
> + DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
> DirectiveKindMap[".sleb128"] = DK_SLEB128;
> DirectiveKindMap[".uleb128"] = DK_ULEB128;
> DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
>
> Modified: llvm/trunk/lib/MC/MCStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/
> MCStreamer.cpp?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/MC/MCStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCStreamer.cpp Fri Sep 15 11:20:28 2017
> @@ -224,8 +224,11 @@ void MCStreamer::EnsureValidDwarfFrame()
> report_fatal_error("No open frame");
> }
>
> -bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef
> Filename) {
> - return getContext().getCVContext().addFile(FileNo, Filename);
> +bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
> + StringRef Checksum,
> + unsigned ChecksumKind) {
> + return getContext().getCVContext().addFile(*this, FileNo, Filename,
> Checksum,
> + ChecksumKind);
> }
>
> bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
>
> Modified: llvm/trunk/test/DebugInfo/COFF/inlining.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> DebugInfo/COFF/inlining.ll?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/DebugInfo/COFF/inlining.ll (original)
> +++ llvm/trunk/test/DebugInfo/COFF/inlining.ll Fri Sep 15 11:20:28 2017
> @@ -49,11 +49,11 @@
> ; ASM: .long 0
> ; ASM: # Inlined function bar starts at t.cpp:8
> ; ASM: .long 4098 # Type index of inlined function
> -; ASM: .long 0 # Offset into filechecksum table
> +; ASM: .cv_filechecksumoffset 1 # Offset into filechecksum table
> ; ASM: .long 8 # Starting line number
> ; ASM: # Inlined function foo starts at t.cpp:2
> ; ASM: .long 4099
> -; ASM: .long 0
> +; ASM: .cv_filechecksumoffset 1 # Offset into filechecksum table
> ; ASM: .long 2
> ; ASM: [[inline_end]]:
>
> @@ -72,6 +72,8 @@
> ; ASM: .short 4430
> ; ASM: .short 4430
>
> +; ASM: .cv_filechecksums
> +
> ; ASM: .section .debug$T,"dr"
> ; ASM: .long 4 # Debug section magic
> ; ASM: # ArgList (0x1000) {
>
> Modified: llvm/trunk/test/DebugInfo/COFF/multifile.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> DebugInfo/COFF/multifile.ll?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/DebugInfo/COFF/multifile.ll (original)
> +++ llvm/trunk/test/DebugInfo/COFF/multifile.ll Fri Sep 15 11:20:28 2017
> @@ -18,10 +18,10 @@
>
> ; X86-LABEL: _f:
> ; X86: # BB
> -; X86: .cv_file 1 "D:\\one.c"
> +; X86: .cv_file 1 "D:\\one.c" "70b51f534d80639d033ae92c6a856af6" 1
> ; X86: .cv_loc 0 1 1 0 is_stmt 0 # one.c:1:0
> ; X86: calll _g
> -; X86: .cv_file 2 "D:\\two.c"
> +; X86: .cv_file 2 "D:\\two.c" "70b51f534d80639d033ae92c6a856af6" 1
> ; X86: .cv_loc 0 2 2 0 # two.c:2:0
> ; X86: calll _g
> ; X86: .cv_loc 0 1 7 0 # one.c:7:0
> @@ -51,6 +51,28 @@
> ; OBJ32-NEXT: ProcEnd {
> ; OBJ32: }
> ; OBJ32-NEXT: ]
> +; OBJ32: Subsection [
> +; OBJ32: SubSectionType: FileChecksums (0xF4)
> +; OBJ32-NEXT: SubSectionSize: 0x50
> +; OBJ32-NEXT: FileChecksum {
> +; OBJ32-NEXT: Filename: D:\one.c (0x1)
> +; OBJ32-NEXT: ChecksumSize: 0x20
> +; OBJ32-NEXT: ChecksumKind: MD5 (0x1)
> +; OBJ32-NEXT: ChecksumBytes (
> +; OBJ32-NEXT: 0000: 37306235 31663533 34643830 36333964
> |70b51f534d80639d|
> +; OBJ32-NEXT: 0010: 30333361 65393263 36613835 36616636
> |033ae92c6a856af6|
> +; OBJ32-NEXT: )
> +; OBJ32-NEXT: }
> +; OBJ32-NEXT: FileChecksum {
> +; OBJ32-NEXT: Filename: D:\two.c (0xA)
> +; OBJ32-NEXT: ChecksumSize: 0x20
> +; OBJ32-NEXT: ChecksumKind: MD5 (0x1)
> +; OBJ32-NEXT: ChecksumBytes (
> +; OBJ32-NEXT: 0000: 37306235 31663533 34643830 36333964
> |70b51f534d80639d|
> +; OBJ32-NEXT: 0010: 30333361 65393263 36613835 36616636
> |033ae92c6a856af6|
> +; OBJ32-NEXT: )
> +; OBJ32-NEXT: }
> +; OBJ32-NEXT: ]
> ; OBJ32: FunctionLineTable [
> ; OBJ32-NEXT: Name: _f
> ; OBJ32-NEXT: Flags: 0x0
> @@ -88,14 +110,14 @@
>
> ; X64-LABEL: f:
> ; X64-NEXT: .L{{.*}}:{{$}}
> -; X64: .cv_file 1 "D:\\input.c"
> +; X64: .cv_file 1 "D:\\input.c" "70b51f534d80639d033ae92c6a856af6" 1
> ; X64: .cv_loc 0 1 3 0 is_stmt 0 # input.c:3:0
> ; X64: # BB
> ; X64: subq $40, %rsp
> -; X64: .cv_file 2 "D:\\one.c"
> +; X64: .cv_file 2 "D:\\one.c" "70b51f534d80639d033ae92c6a856af6" 1
> ; X64: .cv_loc 0 2 1 0 # one.c:1:0
> ; X64: callq g
> -; X64: .cv_file 3 "D:\\two.c"
> +; X64: .cv_file 3 "D:\\two.c" "70b51f534d80639d033ae92c6a856af6" 1
> ; X64: .cv_loc 0 3 2 0 # two.c:2:0
> ; X64: callq g
> ; X64: .cv_loc 0 2 7 0 # one.c:7:0
> @@ -123,6 +145,37 @@
> ; OBJ64-NEXT: ProcEnd {
> ; OBJ64: }
> ; OBJ64-NEXT: ]
> +; OBJ64: Subsection [
> +; OBJ64: SubSectionType: FileChecksums (0xF4)
> +; OBJ64-NEXT: SubSectionSize: 0x78
> +; OBJ64-NEXT: FileChecksum {
> +; OBJ64-NEXT: Filename: D:\input.c (0x1)
> +; OBJ64-NEXT: ChecksumSize: 0x20
> +; OBJ64-NEXT: ChecksumKind: MD5 (0x1)
> +; OBJ64-NEXT: ChecksumBytes (
> +; OBJ64-NEXT: 0000: 37306235 31663533 34643830 36333964
> |70b51f534d80639d|
> +; OBJ64-NEXT: 0010: 30333361 65393263 36613835 36616636
> |033ae92c6a856af6|
> +; OBJ64-NEXT: )
> +; OBJ64-NEXT: }
> +; OBJ64-NEXT: FileChecksum {
> +; OBJ64-NEXT: Filename: D:\one.c (0xC)
> +; OBJ64-NEXT: ChecksumSize: 0x20
> +; OBJ64-NEXT: ChecksumKind: MD5 (0x1)
> +; OBJ64-NEXT: ChecksumBytes (
> +; OBJ64-NEXT: 0000: 37306235 31663533 34643830 36333964
> |70b51f534d80639d|
> +; OBJ64-NEXT: 0010: 30333361 65393263 36613835 36616636
> |033ae92c6a856af6|
> +; OBJ64-NEXT: )
> +; OBJ64-NEXT: }
> +; OBJ64-NEXT: FileChecksum {
> +; OBJ64-NEXT: Filename: D:\two.c (0x15)
> +; OBJ64-NEXT: ChecksumSize: 0x20
> +; OBJ64-NEXT: ChecksumKind: MD5 (0x1)
> +; OBJ64-NEXT: ChecksumBytes (
> +; OBJ64-NEXT: 0000: 37306235 31663533 34643830 36333964
> |70b51f534d80639d|
> +; OBJ64-NEXT: 0010: 30333361 65393263 36613835 36616636
> |033ae92c6a856af6|
> +; OBJ64-NEXT: )
> +; OBJ64-NEXT: }
> +; OBJ64-NEXT: ]
> ; OBJ64: FunctionLineTable [
> ; OBJ64-NEXT: Name: f
> ; OBJ64-NEXT: Flags: 0x0
> @@ -185,11 +238,11 @@ attributes #1 = { "less-precise-fpmad"="
> !llvm.ident = !{!11}
>
> !0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang
> version 3.5 ", isOptimized: false, emissionKind: FullDebug, file: !1,
> enums: !2, retainedTypes: !2, globals: !2, imports: !2)
> -!1 = !DIFile(filename: "<unknown>", directory: "D:\5C")
> +!1 = !DIFile(filename: "<unknown>", directory: "D:\5C", checksumkind:
> CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
> !2 = !{}
> !4 = distinct !DISubprogram(name: "f", line: 3, isLocal: false,
> isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized:
> false, unit: !0, scopeLine: 3, file: !5, scope: !6, type: !7, variables: !2)
> -!5 = !DIFile(filename: "input.c", directory: "D:\5C")
> -!6 = !DIFile(filename: "input.c", directory: "D:C")
> +!5 = !DIFile(filename: "input.c", directory: "D:\5C", checksumkind:
> CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
> +!6 = !DIFile(filename: "input.c", directory: "D:C", checksumkind:
> CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
> !7 = !DISubroutineType(types: !8)
> !8 = !{null}
> !9 = !{i32 2, !"CodeView", i32 1}
> @@ -197,9 +250,9 @@ attributes #1 = { "less-precise-fpmad"="
> !11 = !{!"clang version 3.5 "}
> !12 = !DILocation(line: 1, scope: !13)
> !13 = !DILexicalBlockFile(discriminator: 0, file: !14, scope: !4)
> -!14 = !DIFile(filename: "one.c", directory: "D:\5C")
> +!14 = !DIFile(filename: "one.c", directory: "D:\5C", checksumkind:
> CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
> !15 = !DILocation(line: 2, scope: !16)
> !16 = !DILexicalBlockFile(discriminator: 0, file: !17, scope: !4)
> -!17 = !DIFile(filename: "two.c", directory: "D:\5C")
> +!17 = !DIFile(filename: "two.c", directory: "D:\5C", checksumkind:
> CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
> !18 = !DILocation(line: 7, scope: !13)
> !19 = !DILocation(line: 8, scope: !13)
>
> Modified: llvm/trunk/test/DebugInfo/COFF/simple.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> DebugInfo/COFF/simple.ll?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/DebugInfo/COFF/simple.ll (original)
> +++ llvm/trunk/test/DebugInfo/COFF/simple.ll Fri Sep 15 11:20:28 2017
> @@ -17,7 +17,7 @@
>
> ; X86-LABEL: _f:
> ; X86: # BB
> -; X86: .cv_file 1 "D:\\test.c"
> +; X86: .cv_file 1 "D:\\test.c" "f310ab26998ca831cbdf169e4eecacfa" 1
> ; X86: .cv_loc 0 1 4 2 is_stmt 0 # test.c:4:2
> ; X86: calll _g
> ; X86: .cv_loc 0 1 5 0 # test.c:5:0
> @@ -85,6 +85,19 @@
> ; OBJ32-NEXT: ProcEnd {
> ; OBJ32: }
> ; OBJ32-NEXT: ]
> +; OBJ32: Subsection [
> +; OBJ32: SubSectionType: FileChecksums (0xF4)
> +; OBJ32-NEXT: SubSectionSize: 0x28
> +; OBJ32-NEXT: FileChecksum {
> +; OBJ32-NEXT: Filename: D:\test.c (0x1)
> +; OBJ32-NEXT: ChecksumSize: 0x20
> +; OBJ32-NEXT: ChecksumKind: MD5 (0x1)
> +; OBJ32-NEXT: ChecksumBytes (
> +; OBJ32-NEXT: 0000: 66333130 61623236 39393863 61383331
> |f310ab26998ca831|
> +; OBJ32-NEXT: 0010: 63626466 31363965 34656563 61636661
> |cbdf169e4eecacfa|
> +; OBJ32-NEXT: )
> +; OBJ32-NEXT: }
> +; OBJ32-NEXT: ]
> ; OBJ32: FunctionLineTable [
> ; OBJ32-NEXT: Name: _f
> ; OBJ32-NEXT: Flags: 0x1
> @@ -110,7 +123,7 @@
>
> ; X64-LABEL: f:
> ; X64-NEXT: .L{{.*}}:{{$}}
> -; X64: .cv_file 1 "D:\\test.c"
> +; X64: .cv_file 1 "D:\\test.c" "f310ab26998ca831cbdf169e4eecacfa" 1
> ; X64: .cv_loc 0 1 3 0 is_stmt 0 # test.c:3:0
> ; X64: # BB
> ; X64: subq $40, %rsp
> @@ -182,6 +195,19 @@
> ; OBJ64-NEXT: ProcEnd {
> ; OBJ64: }
> ; OBJ64-NEXT: ]
> +; OBJ64: Subsection [
> +; OBJ64: SubSectionType: FileChecksums (0xF4)
> +; OBJ64-NEXT: SubSectionSize: 0x28
> +; OBJ64-NEXT: FileChecksum {
> +; OBJ64-NEXT: Filename: D:\test.c (0x1)
> +; OBJ64-NEXT: ChecksumSize: 0x20
> +; OBJ64-NEXT: ChecksumKind: MD5 (0x1)
> +; OBJ64-NEXT: ChecksumBytes (
> +; OBJ64-NEXT: 0000: 66333130 61623236 39393863 61383331
> |f310ab26998ca831|
> +; OBJ64-NEXT: 0010: 63626466 31363965 34656563 61636661
> |cbdf169e4eecacfa|
> +; OBJ64-NEXT: )
> +; OBJ64-NEXT: }
> +; OBJ64-NEXT: ]
> ; OBJ64: FunctionLineTable [
> ; OBJ64-NEXT: Name: f
> ; OBJ64-NEXT: Flags: 0x1
> @@ -232,8 +258,8 @@ attributes #1 = { "less-precise-fpmad"="
> !1 = !DIFile(filename: "<unknown>", directory: "D:\5C")
> !2 = !{}
> !4 = distinct !DISubprogram(name: "f", line: 3, isLocal: false,
> isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized:
> false, unit: !0, scopeLine: 3, file: !5, scope: !6, type: !7, variables: !2)
> -!5 = !DIFile(filename: "test.c", directory: "D:\5C")
> -!6 = !DIFile(filename: "test.c", directory: "D:C")
> +!5 = !DIFile(filename: "test.c", directory: "D:\5C", checksumkind:
> CSK_MD5, checksum: "f310ab26998ca831cbdf169e4eecacfa")
> +!6 = !DIFile(filename: "test.c", directory: "D:C", checksumkind: CSK_MD5,
> checksum: "f310ab26998ca831cbdf169e4eecacfa")
> !7 = !DISubroutineType(types: !8)
> !8 = !{null}
> !9 = !{i32 2, !"CodeView", i32 1}
>
> Modified: llvm/trunk/test/MC/AArch64/coff-debug.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/
> AArch64/coff-debug.ll?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/MC/AArch64/coff-debug.ll (original)
> +++ llvm/trunk/test/MC/AArch64/coff-debug.ll Fri Sep 15 11:20:28 2017
> @@ -103,7 +103,7 @@ attributes #0 = { noinline nounwind optn
> ; CHECK: SubSectionType: FileChecksums (0xF4)
> ; CHECK: FileChecksum {
> ; CHECK: ChecksumSize: 0x0
> -; CHECK: ChecksumKind: None (0x0)
> +; CHECK: ChecksumKind: MD5 (0x1)
> ; CHECK: ChecksumBytes: ()
> ; CHECK: }
> ; CHECK: ]
>
> Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/
> IR/MetadataTest.cpp?rev=313374&r1=313373&r2=313374&view=diff
> ============================================================
> ==================
> --- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
> +++ llvm/trunk/unittests/IR/MetadataTest.cpp Fri Sep 15 11:20:28 2017
> @@ -1383,7 +1383,8 @@ TEST_F(DIFileTest, get) {
>
> EXPECT_NE(N, DIFile::get(Context, "other", Directory, CSKind,
> Checksum));
> EXPECT_NE(N, DIFile::get(Context, Filename, "other", CSKind, Checksum));
> - EXPECT_NE(N, DIFile::get(Context, Filename, Directory,
> DIFile::CSK_SHA1, Checksum));
> + EXPECT_NE(
> + N, DIFile::get(Context, Filename, Directory, DIFile::CSK_SHA1,
> Checksum));
> EXPECT_NE(N, DIFile::get(Context, Filename, Directory));
>
> TempDIFile Temp = N->clone();
>
>
> _______________________________________________
> 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/20170915/678fd282/attachment-0001.html>
More information about the llvm-commits
mailing list