@@ -45,6 +45,7 @@ class Deserializer {
45
45
public:
46
46
Deserializer (llvm::MemoryBufferRef Data) : Cursor(Data) {}
47
47
bool readFineGrainedDependencyGraph (SourceFileDepGraph &g);
48
+ bool readFineGrainedDependencyGraphFromSwiftModule (SourceFileDepGraph &g);
48
49
};
49
50
50
51
} // end namespace
@@ -485,3 +486,106 @@ bool swift::fine_grained_dependencies::writeFineGrainedDependencyGraphToPath(
485
486
return false ;
486
487
});
487
488
}
489
+
490
+ static bool checkModuleSignature (llvm::BitstreamCursor &cursor,
491
+ ArrayRef<unsigned char > signature) {
492
+ for (unsigned char byte : signature) {
493
+ if (cursor.AtEndOfStream ())
494
+ return false ;
495
+ if (llvm::Expected<llvm::SimpleBitstreamCursor::word_t > maybeRead =
496
+ cursor.Read (8 )) {
497
+ if (maybeRead.get () != byte)
498
+ return false ;
499
+ } else {
500
+ consumeError (maybeRead.takeError ());
501
+ return false ;
502
+ }
503
+ }
504
+ return true ;
505
+ }
506
+
507
+ static bool enterTopLevelModuleBlock (llvm::BitstreamCursor &cursor, unsigned ID,
508
+ bool shouldReadBlockInfo = true ) {
509
+ llvm::Expected<llvm::BitstreamEntry> maybeNext = cursor.advance ();
510
+ if (!maybeNext) {
511
+ consumeError (maybeNext.takeError ());
512
+ return false ;
513
+ }
514
+ llvm::BitstreamEntry next = maybeNext.get ();
515
+
516
+ if (next.Kind != llvm::BitstreamEntry::SubBlock)
517
+ return false ;
518
+
519
+ if (next.ID == RECORD_BLOCK_ID) {
520
+ if (shouldReadBlockInfo) {
521
+ if (!cursor.ReadBlockInfoBlock ())
522
+ return false ;
523
+ } else {
524
+ if (cursor.SkipBlock ())
525
+ return false ;
526
+ }
527
+ return enterTopLevelModuleBlock (cursor, ID, false );
528
+ }
529
+
530
+ if (next.ID != ID)
531
+ return false ;
532
+
533
+ if (llvm::Error Err = cursor.EnterSubBlock (ID)) {
534
+ // FIXME this drops the error on the floor.
535
+ consumeError (std::move (Err));
536
+ return false ;
537
+ }
538
+
539
+ return true ;
540
+ }
541
+
542
+ bool swift::fine_grained_dependencies::
543
+ readFineGrainedDependencyGraphFromSwiftModule (llvm::MemoryBuffer &buffer,
544
+ SourceFileDepGraph &g) {
545
+ Deserializer deserializer (buffer.getMemBufferRef ());
546
+ return deserializer.readFineGrainedDependencyGraphFromSwiftModule (g);
547
+ }
548
+
549
+ bool Deserializer::readFineGrainedDependencyGraphFromSwiftModule (
550
+ SourceFileDepGraph &g) {
551
+ if (!checkModuleSignature (Cursor, {0xE2 , 0x9C , 0xA8 , 0x0E }) ||
552
+ !enterTopLevelModuleBlock (Cursor, RECORD_BLOCK_ID, false )) {
553
+ return false ;
554
+ }
555
+
556
+ llvm::BitstreamEntry topLevelEntry;
557
+
558
+ while (!Cursor.AtEndOfStream ()) {
559
+ llvm::Expected<llvm::BitstreamEntry> maybeEntry =
560
+ Cursor.advance (llvm::BitstreamCursor::AF_DontPopBlockAtEnd);
561
+ if (!maybeEntry) {
562
+ consumeError (maybeEntry.takeError ());
563
+ return false ;
564
+ }
565
+ topLevelEntry = maybeEntry.get ();
566
+ if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
567
+ break ;
568
+
569
+ switch (topLevelEntry.ID ) {
570
+ case INCREMENTAL_INFORMATION_BLOCK_ID: {
571
+ if (llvm::Error Err =
572
+ Cursor.EnterSubBlock (INCREMENTAL_INFORMATION_BLOCK_ID)) {
573
+ consumeError (std::move (Err));
574
+ return false ;
575
+ }
576
+ readFineGrainedDependencyGraph (g);
577
+ break ;
578
+ }
579
+
580
+ default :
581
+ // Unknown top-level block, possibly for use by a future version of the
582
+ // module format.
583
+ if (Cursor.SkipBlock ()) {
584
+ return false ;
585
+ }
586
+ break ;
587
+ }
588
+ }
589
+
590
+ return false ;
591
+ }
0 commit comments