SymbolGraph: Serialize decl and raw comment locations

- Add DocRangesLayout to the `.swiftsourceinfo`.
  This is a blob containing an array of `SingleRawComment`
  source locations.

- Add DocLocWriter for serializing `SingleRawComment` locs into the
  `DocLocsLayout` buffer.
  Serialize start line, start column, and length of `SingleRawComment`
  pieces in `.swiftsourceinfo`

- Read doc locs when loading basic declaration locs from a ModuleFile.
  - Load `DOC_LOCS` blob into ModuleFile::DocLocsData
  - Reconstitute RawComment ranges when available from .swiftsourceinfo

- Allow requesting serialized raw comment if available

rdar://problem/58339492
This commit is contained in:
Ashley Garland
2020-02-15 15:34:16 -08:00
parent 709c58ae8e
commit be77d57121
14 changed files with 358 additions and 55 deletions

View File

@@ -1460,6 +1460,9 @@ bool ModuleFile::readDeclLocsBlock(llvm::BitstreamCursor &cursor) {
case decl_locs_block::DECL_USRS:
DeclUSRsTable = readDeclUSRsTable(scratch, blobData);
break;
case decl_locs_block::DOC_RANGES:
DocRangesData = blobData;
break;
default:
// Unknown index kind, which this version of the compiler won't use.
break;
@@ -2661,7 +2664,10 @@ ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const {
// Size of BasicDeclLocs in the buffer.
// FilePathOffset + LocNum * LineColumn
uint32_t LineColumnCount = 3;
uint32_t RecordSize = NumSize + NumSize * 2 * LineColumnCount;
uint32_t RecordSize =
NumSize + // Offset into source filename blob
NumSize + // Offset into doc ranges blob
NumSize * 2 * LineColumnCount; // Line/column of: Loc, StartLoc, EndLoc
uint32_t RecordOffset = RecordSize * UsrId;
assert(RecordOffset < BasicDeclLocsData.size());
assert(BasicDeclLocsData.size() % RecordSize == 0);
@@ -2675,6 +2681,23 @@ ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const {
size_t TerminatorOffset = FilePath.find('\0');
assert(TerminatorOffset != StringRef::npos && "unterminated string data");
Result.SourceFilePath = FilePath.slice(0, TerminatorOffset);
const auto DocRangesOffset = ReadNext();
if (DocRangesOffset) {
assert(!DocRangesData.empty());
const auto *Data = DocRangesData.data() + DocRangesOffset;
const auto NumLocs = endian::readNext<uint32_t, little, unaligned>(Data);
assert(NumLocs);
for (uint32_t i = 0; i < NumLocs; ++i) {
LineColumn LC;
LC.Line = endian::readNext<uint32_t, little, unaligned>(Data);
LC.Column = endian::readNext<uint32_t, little, unaligned>(Data);
auto Length = endian::readNext<uint32_t, little, unaligned>(Data);
Result.DocRanges.push_back(std::make_pair(LC, Length));
}
}
#define READ_FIELD(X) \
Result.X.Line = ReadNext(); \
Result.X.Column = ReadNext();