@@ -45,6 +45,7 @@ class Deserializer {
4545public:
4646 Deserializer (llvm::MemoryBufferRef Data) : Cursor(Data) {}
4747 bool readFineGrainedDependencyGraph (SourceFileDepGraph &g);
48+ bool readFineGrainedDependencyGraphFromSwiftModule (SourceFileDepGraph &g);
4849};
4950
5051} // end namespace
@@ -485,3 +486,106 @@ bool swift::fine_grained_dependencies::writeFineGrainedDependencyGraphToPath(
485486 return false ;
486487 });
487488}
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