@@ -188,7 +188,9 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {
188
188
}
189
189
190
190
// Record identifier for the file.
191
- unsigned getEmitFile (StringRef Filename);
191
+ unsigned getEmitFile (
192
+ SourceManager &SM, StringRef Filename, unsigned bufferID
193
+ );
192
194
193
195
// Record identifier for the category.
194
196
unsigned getEmitCategory (StringRef Category);
@@ -217,18 +219,21 @@ namespace serialized_diagnostics {
217
219
} // namespace serialized_diagnostics
218
220
} // namespace swift
219
221
220
- unsigned SerializedDiagnosticConsumer::getEmitFile (StringRef Filename) {
222
+ unsigned SerializedDiagnosticConsumer::getEmitFile (
223
+ SourceManager &SM, StringRef Filename, unsigned bufferID
224
+ ) {
221
225
// NOTE: Using Filename.data() here relies on SourceMgr using
222
226
// const char* as buffer identifiers. This is fast, but may
223
227
// 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 ;
227
231
228
232
// Lazily generate the record for the file. Note that in
229
233
// practice we only expect there to be one file, but this is
230
234
// general and is what the diagnostic file expects.
231
- entry = State->Files .size ();
235
+ unsigned entry = State->Files .size ();
236
+ existingEntry = entry;
232
237
RecordData Record;
233
238
Record.push_back (RECORD_FILENAME);
234
239
Record.push_back (entry);
@@ -238,6 +243,37 @@ unsigned SerializedDiagnosticConsumer::getEmitFile(StringRef Filename) {
238
243
State->Stream .EmitRecordWithBlob (State->Abbrevs .get (RECORD_FILENAME),
239
244
Record, Filename.data ());
240
245
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
+
241
277
return entry;
242
278
}
243
279
@@ -275,7 +311,7 @@ void SerializedDiagnosticConsumer::addLocToRecord(SourceLoc Loc,
275
311
unsigned line, col;
276
312
std::tie (line, col) = SM.getPresumedLineAndColumnForLoc (Loc);
277
313
278
- Record.push_back (getEmitFile (Filename));
314
+ Record.push_back (getEmitFile (SM, Filename, bufferId ));
279
315
Record.push_back (line);
280
316
Record.push_back (col);
281
317
Record.push_back (SM.getLocOffsetInBuffer (Loc, bufferId));
@@ -368,7 +404,7 @@ static void emitRecordID(unsigned ID, const char *Name,
368
404
static void
369
405
addSourceLocationAbbrev (std::shared_ptr<llvm::BitCodeAbbrev> Abbrev) {
370
406
using namespace llvm ;
371
- Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 10 )); // File ID.
407
+ Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::VBR, 5 )); // File ID.
372
408
Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Line.
373
409
Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Column.
374
410
Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Offset;
@@ -411,6 +447,8 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() {
411
447
emitRecordID (RECORD_DIAG_FLAG, " DiagFlag" , Stream, Record);
412
448
emitRecordID (RECORD_FILENAME, " FileName" , Stream, Record);
413
449
emitRecordID (RECORD_FIXIT, " FixIt" , Stream, Record);
450
+ emitRecordID (
451
+ RECORD_SOURCE_FILE_CONTENTS, " SourceFileContents" , Stream, Record);
414
452
415
453
// Emit abbreviation for RECORD_DIAG.
416
454
Abbrev = std::make_shared<BitCodeAbbrev>();
@@ -450,7 +488,7 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() {
450
488
// Emit the abbreviation for RECORD_FILENAME.
451
489
Abbrev = std::make_shared<BitCodeAbbrev>();
452
490
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.
454
492
Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Size.
455
493
Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 32 )); // Modification time.
456
494
Abbrev->Add (BitCodeAbbrevOp (BitCodeAbbrevOp::Fixed, 16 )); // Text size.
@@ -467,6 +505,16 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() {
467
505
Abbrevs.set (RECORD_FIXIT, Stream.EmitBlockInfoAbbrev (BLOCK_DIAG,
468
506
Abbrev));
469
507
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
+
470
518
Stream.ExitBlock ();
471
519
}
472
520
0 commit comments