auto *Scope = cast<DIScope>(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
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,
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);
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)
}
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(),
// 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 =
// 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);
}
return;
maybeRecordLocation(DL, Asm->MF);
}
-} // namespace llvm
+}