X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FWinCodeViewLineTables.cpp;h=1e2f55b71151d4956fd44de40361e1ffa9fb0583;hb=da921ff605b31a92014857dc0f7c37edca5b8913;hp=11bfe767a27b25f16a8b564322602604545b39f2;hpb=cf0db29df20d9c665da7e82bb261bdd7cf7f1b2b;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp index 11bfe767a27..1e2f55b7115 100644 --- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp +++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp @@ -27,15 +27,15 @@ StringRef WinCodeViewLineTables::getFullFilepath(const MDNode *S) { auto *Scope = cast(S); StringRef Dir = Scope->getDirectory(), Filename = Scope->getFilename(); - char *&Result = DirAndFilenameToFilepathMap[std::make_pair(Dir, Filename)]; - if (Result) - return Result; + std::string &Filepath = + DirAndFilenameToFilepathMap[std::make_pair(Dir, Filename)]; + if (!Filepath.empty()) + return Filepath; // Clang emits directory and relative filename info into the IR, but CodeView // operates on full paths. We could change Clang to emit full paths too, but // that would increase the IR size and probably not needed for other users. // For now, just concatenate and canonicalize the path here. - std::string Filepath; if (Filename.find(':') == 1) Filepath = Filename; else @@ -74,8 +74,7 @@ StringRef WinCodeViewLineTables::getFullFilepath(const MDNode *S) { while ((Cursor = Filepath.find("\\\\", Cursor)) != std::string::npos) Filepath.erase(Cursor, 1); - Result = strdup(Filepath.c_str()); - return StringRef(Result); + return Filepath; } void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL, @@ -83,13 +82,24 @@ void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL, const MDNode *Scope = DL.getScope(); if (!Scope) return; + unsigned LineNumber = DL.getLine(); + // Skip this line if it is longer than the maximum we can record. + if (LineNumber > COFF::CVL_MaxLineNumber) + return; + + unsigned ColumnNumber = DL.getCol(); + // Truncate the column number if it is longer than the maximum we can record. + if (ColumnNumber > COFF::CVL_MaxColumnNumber) + ColumnNumber = 0; + StringRef Filename = getFullFilepath(Scope); // Skip this instruction if it has the same file:line as the previous one. assert(CurFn); if (!CurFn->Instrs.empty()) { const InstrInfoTy &LastInstr = InstrInfo[CurFn->Instrs.back()]; - if (LastInstr.Filename == Filename && LastInstr.LineNumber == DL.getLine()) + if (LastInstr.Filename == Filename && LastInstr.LineNumber == LineNumber && + LastInstr.ColumnNumber == ColumnNumber) return; } FileNameRegistry.add(Filename); @@ -97,7 +107,7 @@ void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL, MCSymbol *MCL = Asm->MMI->getContext().createTempSymbol(); Asm->OutStreamer->EmitLabel(MCL); CurFn->Instrs.push_back(MCL); - InstrInfo[MCL] = InstrInfoTy(Filename, DL.getLine()); + InstrInfo[MCL] = InstrInfoTy(Filename, LineNumber, ColumnNumber); } WinCodeViewLineTables::WinCodeViewLineTables(AsmPrinter *AP) @@ -253,7 +263,7 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) { } FilenameSegmentLengths[LastSegmentEnd] = FI.Instrs.size() - LastSegmentEnd; - // Emit a line table subsection, requred to do PC-to-file:line lookup. + // Emit a line table subsection, required to do PC-to-file:line lookup. Asm->OutStreamer->AddComment("Line table subsection for " + Twine(FuncName)); Asm->EmitInt32(COFF::DEBUG_LINE_TABLE_SUBSECTION); MCSymbol *LineTableBegin = Asm->MMI->getContext().createTempSymbol(), @@ -264,22 +274,39 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) { // Identify the function this subsection is for. Asm->OutStreamer->EmitCOFFSecRel32(Fn); Asm->OutStreamer->EmitCOFFSectionIndex(Fn); - // Insert padding after a 16-bit section index. - Asm->EmitInt16(0); + // Insert flags after a 16-bit section index. + Asm->EmitInt16(COFF::DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS); // Length of the function's code, in bytes. EmitLabelDiff(*Asm->OutStreamer, Fn, FI.End); // PC-to-linenumber lookup table: MCSymbol *FileSegmentEnd = nullptr; + + // The start of the last segment: + size_t LastSegmentStart = 0; + + auto FinishPreviousChunk = [&] { + if (!FileSegmentEnd) + return; + for (size_t ColSegI = LastSegmentStart, + ColSegEnd = ColSegI + FilenameSegmentLengths[LastSegmentStart]; + ColSegI != ColSegEnd; ++ColSegI) { + unsigned ColumnNumber = InstrInfo[FI.Instrs[ColSegI]].ColumnNumber; + assert(ColumnNumber <= COFF::CVL_MaxColumnNumber); + Asm->EmitInt16(ColumnNumber); // Start column + Asm->EmitInt16(0); // End column + } + Asm->OutStreamer->EmitLabel(FileSegmentEnd); + }; + for (size_t J = 0, F = FI.Instrs.size(); J != F; ++J) { MCSymbol *Instr = FI.Instrs[J]; assert(InstrInfo.count(Instr)); if (FilenameSegmentLengths.count(J)) { // We came to a beginning of a new filename segment. - if (FileSegmentEnd) - Asm->OutStreamer->EmitLabel(FileSegmentEnd); + FinishPreviousChunk(); StringRef CurFilename = InstrInfo[FI.Instrs[J]].Filename; assert(FileNameRegistry.Infos.count(CurFilename)); size_t IndexInStringTable = @@ -300,15 +327,18 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) { // records. FileSegmentEnd = Asm->MMI->getContext().createTempSymbol(); EmitLabelDiff(*Asm->OutStreamer, FileSegmentBegin, FileSegmentEnd); + LastSegmentStart = J; } // The first PC with the given linenumber and the linenumber itself. EmitLabelDiff(*Asm->OutStreamer, Fn, Instr); - Asm->EmitInt32(InstrInfo[Instr].LineNumber); + uint32_t LineNumber = InstrInfo[Instr].LineNumber; + assert(LineNumber <= COFF::CVL_MaxLineNumber); + uint32_t LineData = LineNumber | COFF::CVL_IsStatement; + Asm->EmitInt32(LineData); } - if (FileSegmentEnd) - Asm->OutStreamer->EmitLabel(FileSegmentEnd); + FinishPreviousChunk(); Asm->OutStreamer->EmitLabel(LineTableEnd); } @@ -378,4 +408,4 @@ void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) { return; maybeRecordLocation(DL, Asm->MF); } -} // namespace llvm +}