@@ -173,30 +173,40 @@ class DiscoveredModule {
173
173
// / The kind of module that's been discovered.
174
174
const Kind kind;
175
175
176
- DiscoveredModule (StringRef path, Kind kind): kind(kind), path(path) {}
176
+ DiscoveredModule (StringRef path, Kind kind,
177
+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer)
178
+ : kind(kind), moduleBuffer(std::move(moduleBuffer)), path(path) {}
179
+
177
180
public:
181
+ // / The contents of the .swiftmodule, if we've read it while validating
182
+ // / dependencies.
183
+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
184
+
178
185
// / The path to the discovered serialized .swiftmodule on disk.
179
186
const std::string path;
180
187
181
188
// / Creates a \c Normal discovered module.
182
- static DiscoveredModule normal (StringRef path) {
183
- return { path, Kind::Normal };
189
+ static DiscoveredModule normal (StringRef path,
190
+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer) {
191
+ return { path, Kind::Normal, std::move (moduleBuffer) };
184
192
}
185
193
186
194
// / Creates a \c Prebuilt discovered module.
187
- static DiscoveredModule prebuilt (StringRef path) {
188
- return { path, Kind::Prebuilt };
195
+ static DiscoveredModule prebuilt (
196
+ StringRef path, std::unique_ptr<llvm::MemoryBuffer> moduleBuffer) {
197
+ return { path, Kind::Prebuilt, std::move (moduleBuffer) };
189
198
}
190
199
191
200
// / Creates a \c Forwarded discovered module, whose dependencies have been
192
201
// / externally validated by a \c ForwardingModule.
193
- static DiscoveredModule forwarded (StringRef path) {
194
- return { path, Kind::Forwarded };
202
+ static DiscoveredModule forwarded (
203
+ StringRef path, std::unique_ptr<llvm::MemoryBuffer> moduleBuffer) {
204
+ return { path, Kind::Forwarded, std::move (moduleBuffer) };
195
205
}
196
206
197
207
bool isNormal () const { return kind == Kind::Normal; }
198
208
bool isPrebuilt () const { return kind == Kind::Prebuilt; }
199
- bool isForwarding () const { return kind == Kind::Forwarded; }
209
+ bool isForwarded () const { return kind == Kind::Forwarded; }
200
210
};
201
211
202
212
} // end anonymous namespace
@@ -453,7 +463,8 @@ class swift::ParseableInterfaceBuilder {
453
463
return subInvocation;
454
464
}
455
465
456
- bool buildSwiftModule (StringRef OutPath, bool ShouldSerializeDeps) {
466
+ bool buildSwiftModule (StringRef OutPath, bool ShouldSerializeDeps,
467
+ std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer) {
457
468
bool SubError = false ;
458
469
bool RunSuccess = llvm::CrashRecoveryContext ().RunSafelyOnThread ([&] {
459
470
// Note that we don't assume cachePath is the same as the Clang
@@ -559,7 +570,10 @@ class swift::ParseableInterfaceBuilder {
559
570
if (ShouldSerializeDeps)
560
571
SerializationOpts.Dependencies = Deps;
561
572
SILMod->setSerializeSILAction ([&]() {
562
- serialize (Mod, SerializationOpts, SILMod.get ());
573
+ // We don't want to serialize module docs in the cache -- they
574
+ // will be serialized beside the interface file.
575
+ serializeToBuffers (Mod, SerializationOpts, ModuleBuffer,
576
+ /* ModuleDocBuffer*/ nullptr , SILMod.get ());
563
577
});
564
578
565
579
LLVM_DEBUG (llvm::dbgs () << " Running SIL processing passes\n " );
@@ -717,22 +731,23 @@ class ParseableInterfaceModuleLoaderImpl {
717
731
718
732
// Check that the output .swiftmodule file is at least as new as all the
719
733
// dependencies it read when it was built last time.
720
- bool swiftModuleIsUpToDate (StringRef modulePath,
721
- SmallVectorImpl<FileDependency> &AllDeps) {
734
+ bool swiftModuleIsUpToDate (
735
+ StringRef modulePath, SmallVectorImpl<FileDependency> &AllDeps,
736
+ std::unique_ptr<llvm::MemoryBuffer> &moduleBuffer) {
722
737
auto OutBuf = fs.getBufferForFile (modulePath);
723
738
if (!OutBuf)
724
739
return false ;
725
- return serializedASTBufferIsUpToDate (*OutBuf.get (), AllDeps);
740
+ moduleBuffer = std::move (*OutBuf);
741
+ return serializedASTBufferIsUpToDate (*moduleBuffer, AllDeps);
726
742
}
727
743
728
744
// Check that a "forwarding" .swiftmodule file is at least as new as all the
729
745
// dependencies it read when it was built last time. Requires that the
730
746
// forwarding module has been loaded from disk.
731
- bool forwardingModuleIsUpToDate (const ForwardingModule &fwd,
732
- SmallVectorImpl<FileDependency> &deps) {
747
+ bool forwardingModuleIsUpToDate (
748
+ const ForwardingModule &fwd, SmallVectorImpl<FileDependency> &deps,
749
+ std::unique_ptr<llvm::MemoryBuffer> &moduleBuffer) {
733
750
// First, make sure the underlying module path exists and is valid.
734
- // FIXME: We should preserve this buffer, rather than opening it again
735
- // when loading the module.
736
751
auto modBuf = fs.getBufferForFile (fwd.underlyingModulePath );
737
752
if (!modBuf || !serializedASTLooksValid (*modBuf.get ()))
738
753
return false ;
@@ -743,7 +758,11 @@ class ParseableInterfaceModuleLoaderImpl {
743
758
FileDependency::modTimeBased (
744
759
dep.path , dep.size , dep.lastModificationTime ));
745
760
}
746
- return dependenciesAreUpToDate (deps);
761
+ if (!dependenciesAreUpToDate (deps))
762
+ return false ;
763
+
764
+ moduleBuffer = std::move (*modBuf);
765
+ return true ;
747
766
}
748
767
749
768
Optional<StringRef>
@@ -809,22 +828,25 @@ class ParseableInterfaceModuleLoaderImpl {
809
828
// First, check the cached module path. Whatever's in this cache represents
810
829
// the most up-to-date knowledge we have about the module.
811
830
if (auto cachedBufOrError = fs.getBufferForFile (cachedOutputPath)) {
812
- auto & buf = *cachedBufOrError. get ( );
831
+ auto buf = std::move ( *cachedBufOrError);
813
832
814
833
// Check to see if the module is a serialized AST. If it's not, then we're
815
834
// probably dealing with a Forwarding Module, which is a YAML file.
816
835
bool isForwardingModule =
817
- !serialization::isSerializedAST (buf. getBuffer ());
836
+ !serialization::isSerializedAST (buf-> getBuffer ());
818
837
819
838
// If it's a forwarding module, load the YAML file from disk and check
820
839
// if it's up-to-date.
821
840
if (isForwardingModule) {
822
- auto modOrErr = ForwardingModule::load (buf);
823
- if (modOrErr && forwardingModuleIsUpToDate (*modOrErr, deps))
824
- return DiscoveredModule::forwarded (modOrErr->underlyingModulePath );
841
+ if (auto forwardingModule = ForwardingModule::load (*buf)) {
842
+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
843
+ if (forwardingModuleIsUpToDate (*forwardingModule, deps, moduleBuffer))
844
+ return DiscoveredModule::forwarded (
845
+ forwardingModule->underlyingModulePath , std::move (moduleBuffer));
846
+ }
825
847
// Otherwise, check if the AST buffer itself is up to date.
826
- } else if (serializedASTBufferIsUpToDate (buf, deps)) {
827
- return DiscoveredModule::normal (cachedOutputPath);
848
+ } else if (serializedASTBufferIsUpToDate (* buf, deps)) {
849
+ return DiscoveredModule::normal (cachedOutputPath, std::move (buf) );
828
850
}
829
851
}
830
852
@@ -835,9 +857,10 @@ class ParseableInterfaceModuleLoaderImpl {
835
857
// from the SDK.
836
858
if (!prebuiltCacheDir.empty ()) {
837
859
llvm::SmallString<256 > scratch;
860
+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
838
861
auto path = computePrebuiltModulePath (scratch);
839
- if (path && swiftModuleIsUpToDate (*path, deps))
840
- return DiscoveredModule::prebuilt (*path);
862
+ if (path && swiftModuleIsUpToDate (*path, deps, moduleBuffer ))
863
+ return DiscoveredModule::prebuilt (*path, std::move (moduleBuffer) );
841
864
}
842
865
843
866
// Finally, if there's a module adjacent to the .swiftinterface that we can
@@ -899,10 +922,12 @@ class ParseableInterfaceModuleLoaderImpl {
899
922
});
900
923
}
901
924
902
- // / Looks up the best module to load for a given interface. See the main
903
- // / comment in \c ParseableInterfaceModuleLoader.h for an explanation of
904
- // / the module loading strategy.
905
- llvm::ErrorOr<std::string> findOrBuildLoadableModule () {
925
+ // / Looks up the best module to load for a given interface, and returns a
926
+ // / buffer of the module's contents. See the main comment in
927
+ // / \c ParseableInterfaceModuleLoader.h for an explanation of the module
928
+ // / loading strategy.
929
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
930
+ findOrBuildLoadableModule () {
906
931
907
932
// Set up a builder if we need to build the module. It'll also set up
908
933
// the subinvocation we'll need to use to compute the cache paths.
@@ -927,24 +952,27 @@ class ParseableInterfaceModuleLoaderImpl {
927
952
moduleOrErr.getError () != std::errc::no_such_file_or_directory)
928
953
return moduleOrErr.getError ();
929
954
930
- // We discovered a module! Return the module's path so we know what to load.
955
+ // We discovered a module! Return that module's buffer so we can load it .
931
956
if (moduleOrErr) {
932
- auto &module = *moduleOrErr;
957
+ auto module = std::move (moduleOrErr.get ());
958
+
933
959
// If it's prebuilt, use this time to generate a forwarding module.
934
960
if (module .isPrebuilt ())
935
961
if (writeForwardingModule (module , cachedOutputPath, allDeps))
936
962
return std::make_error_code (std::errc::not_supported);
937
963
938
- // FIXME: return and load module buffer directly
939
- return module .path ;
964
+ return std::move (module .moduleBuffer );
940
965
}
941
966
967
+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
942
968
// We didn't discover a module corresponding to this interface. Build one.
943
- if (builder.buildSwiftModule (cachedOutputPath, /* shouldSerializeDeps*/ true ))
969
+ if (builder.buildSwiftModule (cachedOutputPath, /* shouldSerializeDeps*/ true ,
970
+ &moduleBuffer))
944
971
return std::make_error_code (std::errc::invalid_argument);
945
972
946
- // FIXME: return and load module buffer directly
947
- return cachedOutputPath.str ();
973
+ assert (moduleBuffer &&
974
+ " failed to write module buffer but returned success?" );
975
+ return std::move (moduleBuffer);
948
976
}
949
977
};
950
978
@@ -984,26 +1012,24 @@ std::error_code ParseableInterfaceModuleLoader::findModuleFilesInDirectory(
984
1012
985
1013
// Ask the impl to find us a module that we can load or give us an error
986
1014
// telling us that we couldn't load it.
987
- auto PathOrErr = Impl.findOrBuildLoadableModule ();
988
- if (!PathOrErr )
989
- return PathOrErr .getError ();
990
- std::string FinalPath = std::move (*PathOrErr);
991
-
992
- // Finish off by delegating back up to the SerializedModuleLoaderBase
993
- // routine that can load the recently-manufactured serialized module.
994
- LLVM_DEBUG ( llvm::dbgs () << " Loading " << FinalPath
995
- << " via normal module loader \n " );
1015
+ auto ModuleBufferOrErr = Impl.findOrBuildLoadableModule ();
1016
+ if (!ModuleBufferOrErr )
1017
+ return ModuleBufferOrErr .getError ();
1018
+
1019
+ if (ModuleBuffer) {
1020
+ *ModuleBuffer = std::move (*ModuleBufferOrErr);
1021
+ }
1022
+
1023
+ // Delegate back to the serialized module loader to load the module doc.
996
1024
llvm::SmallString<256 > DocPath{DirPath};
997
1025
path::append (DocPath, ModuleDocFilename);
998
- auto ErrorCode = SerializedModuleLoaderBase::openModuleFiles (
999
- ModuleID, FinalPath, DocPath, ModuleBuffer, ModuleDocBuffer);
1000
- LLVM_DEBUG (llvm::dbgs () << " Loaded " << FinalPath
1001
- << " via normal module loader" );
1002
- if (ErrorCode) {
1003
- LLVM_DEBUG (llvm::dbgs () << " with error: " << ErrorCode.message ());
1004
- }
1005
- LLVM_DEBUG (llvm::dbgs () << " \n " );
1006
- return ErrorCode;
1026
+ auto DocLoadErr =
1027
+ SerializedModuleLoaderBase::openModuleDocFile (ModuleID, DocPath,
1028
+ ModuleDocBuffer);
1029
+ if (DocLoadErr)
1030
+ return DocLoadErr;
1031
+
1032
+ return std::error_code ();
1007
1033
}
1008
1034
1009
1035
@@ -1018,5 +1044,6 @@ bool ParseableInterfaceModuleLoader::buildSwiftModuleFromSwiftInterface(
1018
1044
// make them relocatable (SDK-relative) if we want to ship the built
1019
1045
// swiftmodules to another machine. Just track them as absolute paths
1020
1046
// for now, so we can test the dependency tracking locally.
1021
- return builder.buildSwiftModule (OutPath, /* shouldSerializeDeps*/ true );
1047
+ return builder.buildSwiftModule (OutPath, /* shouldSerializeDeps*/ true ,
1048
+ /* ModuleBuffer*/ nullptr );
1022
1049
}
0 commit comments