@@ -188,7 +188,9 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {
188188 }
189189
190190 // Record identifier for the file.
191- unsigned getEmitFile (StringRef Filename);
191+ unsigned getEmitFile (
192+ SourceManager &SM, StringRef Filename, unsigned bufferID
193+ );
192194
193195 // Record identifier for the category.
194196 unsigned getEmitCategory (StringRef Category);
@@ -217,18 +219,21 @@ namespace serialized_diagnostics {
217219} // namespace serialized_diagnostics
218220} // namespace swift
219221
220- unsigned SerializedDiagnosticConsumer::getEmitFile (StringRef Filename) {
222+ unsigned SerializedDiagnosticConsumer::getEmitFile (
223+ SourceManager &SM, StringRef Filename, unsigned bufferID
224+ ) {
221225 // NOTE: Using Filename.data() here relies on SourceMgr using
222226 // const char* as buffer identifiers. This is fast, but may
223227 // be brittle. We can always switch over to using a StringMap.
224- unsigned &entry = State->Files [Filename.data ()];
225- if (entry )
226- return entry ;
228+ unsigned &existingEntry = State->Files [Filename.data ()];
229+ if (existingEntry )
230+ return existingEntry ;
227231
228232 // Lazily generate the record for the file. Note that in
229233 // practice we only expect there to be one file, but this is
230234 // general and is what the diagnostic file expects.
231- entry = State->Files .size ();
235+ unsigned entry = State->Files .size ();
236+ existingEntry = entry;
232237 RecordData Record;
233238 Record.push_back (RECORD_FILENAME);
234239 Record.push_back (entry);
@@ -238,6 +243,37 @@ unsigned SerializedDiagnosticConsumer::getEmitFile(StringRef Filename) {
238243 State->Stream .EmitRecordWithBlob (State->Abbrevs .get (RECORD_FILENAME),
239244 Record, Filename.data ());
240245
246+ // If the buffer contains code that was synthesized by the compiler,
247+ // emit the contents of the buffer.
248+ auto generatedInfo = SM.getGeneratedSourceInfo (bufferID);
249+ if (!generatedInfo)
250+ return entry;
251+
252+ Record.clear ();
253+ Record.push_back (RECORD_SOURCE_FILE_CONTENTS);
254+ Record.push_back (entry);
255+
256+ // The source range that this buffer was generated from, expressed as
257+ // offsets into the original buffer.
258+ if (generatedInfo->originalSourceRange .isValid ()) {
259+ auto originalFilename = SM.getDisplayNameForLoc (generatedInfo->originalSourceRange .Start );
260+ addRangeToRecord (
261+ Lexer::getCharSourceRangeFromSourceRange (
262+ SM, generatedInfo->originalSourceRange ),
263+ SM, originalFilename, Record
264+ );
265+ } else {
266+ addLocToRecord (SourceLoc (), SM, " " , Record); // Start
267+ addLocToRecord (SourceLoc (), SM, " " , Record); // End
268+ }
269+
270+ // Contents of the buffer.
271+ auto sourceText = SM.getEntireTextForBuffer (bufferID);
272+ Record.push_back (sourceText.size ());
273+ State->Stream .EmitRecordWithBlob (
274+ State->Abbrevs .get (RECORD_SOURCE_FILE_CONTENTS),
275+ Record, sourceText);
276+
241277 return entry;
242278}
243279
@@ -275,7 +311,7 @@ void SerializedDiagnosticConsumer::addLocToRecord(SourceLoc Loc,
275311 unsigned line, col;
276312 std::tie (line, col) = SM.getPresumedLineAndColumnForLoc (Loc);
277313
278- Record.push_back (getEmitFile (Filename));
314+ Record.push_back (getEmitFile (SM, Filename, bufferId ));
279315 Record.push_back (line);
280316 Record.push_back (col);
281317 Record.push_back (SM.getLocOffsetInBuffer (Loc, bufferId));
@@ -368,7 +404,7 @@ static void emitRecordID(unsigned ID, const char *Name,
368404static void
369405addSourceLocationAbbrev (std::shared_ptr<llvm::BitCodeAbbrev> Abbrev) {
370406 using namespace llvm ;
371- Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 10 )); // File ID.
407+ Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::VBR, 5 )); // File ID.
372408 Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Line.
373409 Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Column.
374410 Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Offset;
@@ -411,6 +447,8 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() {
411447 emitRecordID (RECORD_DIAG_FLAG, " DiagFlag" , Stream, Record);
412448 emitRecordID (RECORD_FILENAME, " FileName" , Stream, Record);
413449 emitRecordID (RECORD_FIXIT, " FixIt" , Stream, Record);
450+ emitRecordID (
451+ RECORD_SOURCE_FILE_CONTENTS, " SourceFileContents" , Stream, Record);
414452
415453 // Emit abbreviation for RECORD_DIAG.
416454 Abbrev = std::make_shared<BitCodeAbbrev>();
@@ -450,7 +488,7 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() {
450488 // Emit the abbreviation for RECORD_FILENAME.
451489 Abbrev = std::make_shared<BitCodeAbbrev>();
452490 Abbrev->Add (BitCodeAbbrevOp (RECORD_FILENAME));
453- Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 10 )); // Mapped file ID.
491+ Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::VBR, 5 )); // Mapped file ID.
454492 Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Size.
455493 Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Modification time.
456494 Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 16 )); // Text size.
@@ -467,6 +505,16 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() {
467505 Abbrevs.set (RECORD_FIXIT, Stream.EmitBlockInfoAbbrev (BLOCK_DIAG,
468506 Abbrev));
469507
508+ // Emit the abbreviation for RECORD_SOURCE_FILE_CONTENTS.
509+ Abbrev = std::make_shared<BitCodeAbbrev>();
510+ Abbrev->Add (BitCodeAbbrevOp (RECORD_SOURCE_FILE_CONTENTS));
511+ Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::VBR, 5 )); // File ID.
512+ addRangeLocationAbbrev (Abbrev);
513+ Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::VBR, 16 )); // File size.
514+ Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Blob)); // File contents.
515+ Abbrevs.set (RECORD_SOURCE_FILE_CONTENTS,
516+ Stream.EmitBlockInfoAbbrev (BLOCK_DIAG, Abbrev));
517+
470518 Stream.ExitBlock ();
471519}
472520
0 commit comments