Skip to content

Commit b244b09

Browse files
committed
Factor out the pre-registered MemoryBuffer functionality
form SerializedModuleLoader into its own ModuleLoader class. (NFC-ish) This gives better control over the order in which the various module load mechanisms are applied.
1 parent 007fbb6 commit b244b09

File tree

8 files changed

+163
-64
lines changed

8 files changed

+163
-64
lines changed

Diff for: include/swift/ASTSectionImporter/ASTSectionImporter.h

+8-10
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,16 @@
2121
#include <string>
2222

2323
namespace swift {
24-
class SerializedModuleLoader;
24+
class MemoryBufferSerializedModuleLoader;
2525

26-
/// Provided a memory buffer with an entire Mach-O __apple_ast
27-
/// section, this function makes memory buffer copies of all swift
28-
/// modules found in it and registers them using
29-
/// registerMemoryBuffer() so they can be found by loadModule(). The
30-
/// access path of all modules found in the section is appended to
31-
/// the vector foundModules.
26+
/// Provided a memory buffer with an entire Mach-O __swift_ast section, this
27+
/// function makes memory buffer copies of all swift modules found in it and
28+
/// registers them using registerMemoryBuffer() so they can be found by
29+
/// loadModule(). The access path of all modules found in the section is
30+
/// appended to the vector foundModules.
3231
/// \return true if successful.
33-
bool parseASTSection(SerializedModuleLoader* SML, StringRef Data,
32+
bool parseASTSection(MemoryBufferSerializedModuleLoader &Loader,
33+
StringRef Data,
3434
SmallVectorImpl<std::string> &foundModules);
35-
36-
3735
}
3836
#endif

Diff for: include/swift/Basic/LangOptions.h

+4
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ namespace swift {
104104
/// Enable features useful for running in the debugger.
105105
bool DebuggerSupport = false;
106106

107+
/// Enable the MemoryBufferSerializedModuleImporter.
108+
/// Only used by lldb-moduleimport-test.
109+
bool EnableMemoryBufferImporter = false;
110+
107111
/// Enable the DWARFImporter. Only used by lldb-moduleimport-test.
108112
bool EnableDWARFImporter = false;
109113

Diff for: include/swift/Frontend/Frontend.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
namespace swift {
5353

5454
class SerializedModuleLoader;
55+
class MemoryBufferSerializedModuleLoader;
5556
class SILModule;
5657

5758
/// The abstract configuration of the compiler, including:
@@ -372,6 +373,7 @@ class CompilerInstance {
372373

373374
ModuleDecl *MainModule = nullptr;
374375
SerializedModuleLoader *SML = nullptr;
376+
MemoryBufferSerializedModuleLoader *MemoryBufferLoader = nullptr;
375377

376378
/// Contains buffer IDs for input source code files.
377379
std::vector<unsigned> InputSourceCodeBufferIDs;
@@ -465,7 +467,10 @@ class CompilerInstance {
465467

466468
ModuleDecl *getMainModule();
467469

468-
SerializedModuleLoader *getSerializedModuleLoader() const { return SML; }
470+
MemoryBufferSerializedModuleLoader *
471+
getMemoryBufferSerializedModuleLoader() const {
472+
return MemoryBufferLoader;
473+
}
469474

470475
ArrayRef<unsigned> getInputBufferIDs() const {
471476
return InputSourceCodeBufferIDs;

Diff for: include/swift/Serialization/SerializedModuleLoader.h

+49-9
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class SerializedModuleLoaderBase : public ModuleLoader {
3939
SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 2> OrphanedMemoryBuffers;
4040

4141
protected:
42-
llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> MemoryBuffers;
4342
ASTContext &Ctx;
4443
ModuleLoadingMode LoadMode;
4544
SerializedModuleLoaderBase(ASTContext &ctx, DependencyTracker *tracker,
@@ -170,10 +169,51 @@ class SerializedModuleLoader : public SerializedModuleLoaderBase {
170169
public:
171170
virtual ~SerializedModuleLoader();
172171

173-
/// Register a memory buffer that contains the serialized
174-
/// module for the given access path. This API is intended to be
175-
/// used by LLDB to add swiftmodules discovered in the __apple_ast
176-
/// section of a Mach-O file to the search path.
172+
/// Create a new importer that can load serialized Swift modules
173+
/// into the given ASTContext.
174+
static std::unique_ptr<SerializedModuleLoader>
175+
create(ASTContext &ctx, DependencyTracker *tracker = nullptr,
176+
ModuleLoadingMode loadMode = ModuleLoadingMode::PreferSerialized) {
177+
return std::unique_ptr<SerializedModuleLoader>{
178+
new SerializedModuleLoader(ctx, tracker, loadMode)
179+
};
180+
}
181+
};
182+
183+
/// Imports serialized Swift modules from a MemoryBuffer into an ASTContext.
184+
/// This interface is primarily used by LLDB.
185+
class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
186+
llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> MemoryBuffers;
187+
188+
MemoryBufferSerializedModuleLoader(ASTContext &ctx,
189+
DependencyTracker *tracker,
190+
ModuleLoadingMode loadMode)
191+
: SerializedModuleLoaderBase(ctx, tracker, loadMode) {}
192+
193+
std::error_code findModuleFilesInDirectory(
194+
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
195+
StringRef ModuleDocFilename,
196+
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
197+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) override;
198+
199+
bool maybeDiagnoseTargetMismatch(SourceLoc sourceLocation,
200+
StringRef moduleName,
201+
StringRef archName,
202+
StringRef directoryPath) override;
203+
204+
public:
205+
virtual ~MemoryBufferSerializedModuleLoader();
206+
207+
bool canImportModule(std::pair<Identifier, SourceLoc> named) override;
208+
ModuleDecl *
209+
loadModule(SourceLoc importLoc,
210+
ArrayRef<std::pair<Identifier, SourceLoc>> path) override;
211+
212+
/// Register a memory buffer that contains the serialized module for the given
213+
/// access path. This API is intended to be used by LLDB to add swiftmodules
214+
/// discovered in the __swift_ast section of a Mach-O file (or the .swift_ast
215+
/// section of an ELF file) to the search path.
216+
///
177217
/// FIXME: make this an actual access *path* once submodules are designed.
178218
void registerMemoryBuffer(StringRef AccessPath,
179219
std::unique_ptr<llvm::MemoryBuffer> input) {
@@ -182,15 +222,15 @@ class SerializedModuleLoader : public SerializedModuleLoaderBase {
182222

183223
/// Create a new importer that can load serialized Swift modules
184224
/// into the given ASTContext.
185-
static std::unique_ptr<SerializedModuleLoader>
225+
static std::unique_ptr<MemoryBufferSerializedModuleLoader>
186226
create(ASTContext &ctx, DependencyTracker *tracker = nullptr,
187227
ModuleLoadingMode loadMode = ModuleLoadingMode::PreferSerialized) {
188-
return std::unique_ptr<SerializedModuleLoader>{
189-
new SerializedModuleLoader(ctx, tracker, loadMode)
190-
};
228+
return std::unique_ptr<MemoryBufferSerializedModuleLoader>{
229+
new MemoryBufferSerializedModuleLoader(ctx, tracker, loadMode)};
191230
}
192231
};
193232

233+
194234
/// A file-unit loaded from a serialized AST file.
195235
class SerializedASTFile final : public LoadedFile {
196236
friend class SerializedModuleLoaderBase;

Diff for: lib/ASTSectionImporter/ASTSectionImporter.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424

2525
using namespace swift;
2626

27-
bool swift::parseASTSection(SerializedModuleLoader *SML, StringRef buf,
27+
bool swift::parseASTSection(MemoryBufferSerializedModuleLoader &Loader,
28+
StringRef buf,
2829
SmallVectorImpl<std::string> &foundModules) {
2930
if (!serialization::isSerializedAST(buf))
3031
return false;
@@ -44,7 +45,7 @@ bool swift::parseASTSection(SerializedModuleLoader *SML, StringRef buf,
4445
llvm::MemoryBuffer::getMemBuffer(moduleData, info.name, false));
4546

4647
// Register the memory buffer.
47-
SML->registerMemoryBuffer(info.name, std::move(bitstream));
48+
Loader.registerMemoryBuffer(info.name, std::move(bitstream));
4849
foundModules.push_back(info.name);
4950
}
5051
} else {

Diff for: lib/Frontend/Frontend.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,13 @@ bool CompilerInstance::setUpModuleLoaders() {
315315
}
316316
}
317317

318+
if (Invocation.getLangOptions().EnableMemoryBufferImporter) {
319+
auto MemoryBufferLoader = MemoryBufferSerializedModuleLoader::create(
320+
*Context, getDependencyTracker());
321+
this->MemoryBufferLoader = MemoryBufferLoader.get();
322+
Context->addModuleLoader(std::move(MemoryBufferLoader));
323+
}
324+
318325
std::unique_ptr<SerializedModuleLoader> SML =
319326
SerializedModuleLoader::create(*Context, getDependencyTracker(), MLM);
320327
this->SML = SML.get();
@@ -1067,6 +1074,7 @@ void CompilerInstance::freeASTContext() {
10671074
Context.reset();
10681075
MainModule = nullptr;
10691076
SML = nullptr;
1077+
MemoryBufferLoader = nullptr;
10701078
PrimaryBufferIDs.clear();
10711079
PrimarySourceFiles.clear();
10721080
}

Diff for: lib/Serialization/SerializedModuleLoader.cpp

+83-41
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,14 @@ namespace {
3535
} // end unnamed namespace
3636

3737
// Defined out-of-line so that we can see ~ModuleFile.
38-
SerializedModuleLoaderBase::SerializedModuleLoaderBase(ASTContext &ctx,
39-
DependencyTracker *tracker,
40-
ModuleLoadingMode loadMode)
41-
: ModuleLoader(tracker), Ctx(ctx), LoadMode(loadMode) {}
42-
SerializedModuleLoaderBase::~SerializedModuleLoaderBase() = default;
38+
SerializedModuleLoaderBase::SerializedModuleLoaderBase(
39+
ASTContext &ctx, DependencyTracker *tracker, ModuleLoadingMode loadMode)
40+
: ModuleLoader(tracker), Ctx(ctx), LoadMode(loadMode) {}
4341

42+
SerializedModuleLoaderBase::~SerializedModuleLoaderBase() = default;
4443
SerializedModuleLoader::~SerializedModuleLoader() = default;
44+
MemoryBufferSerializedModuleLoader::~MemoryBufferSerializedModuleLoader() =
45+
default;
4546

4647
std::error_code SerializedModuleLoaderBase::openModuleDocFile(
4748
AccessPathElem ModuleID, StringRef ModuleDocPath,
@@ -607,23 +608,22 @@ void swift::serialization::diagnoseSerializedASTLoadFailure(
607608
}
608609
}
609610

610-
bool
611-
SerializedModuleLoaderBase::canImportModule(std::pair<Identifier, SourceLoc> mID) {
612-
// First see if we find it in the registered memory buffers.
613-
if (!MemoryBuffers.empty()) {
614-
auto bufIter = MemoryBuffers.find(mID.first.str());
615-
if (bufIter != MemoryBuffers.end()) {
616-
return true;
617-
}
618-
}
619-
620-
// Otherwise look on disk.
611+
bool SerializedModuleLoaderBase::canImportModule(
612+
std::pair<Identifier, SourceLoc> mID) {
613+
// Look on disk.
621614
bool isFramework = false;
622615
return findModule(mID, nullptr, nullptr, isFramework);
623616
}
624617

625-
ModuleDecl *SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
626-
ModuleDecl::AccessPathTy path) {
618+
bool MemoryBufferSerializedModuleLoader::canImportModule(
619+
std::pair<Identifier, SourceLoc> mID) {
620+
// See if we find it in the registered memory buffers.
621+
return MemoryBuffers.count(mID.first.str());
622+
}
623+
624+
ModuleDecl *
625+
SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
626+
ModuleDecl::AccessPathTy path) {
627627
// FIXME: Swift submodules?
628628
if (path.size() > 1)
629629
return nullptr;
@@ -633,30 +633,17 @@ ModuleDecl *SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
633633

634634
std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer;
635635
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer;
636-
// First see if we find it in the registered memory buffers.
637-
if (!MemoryBuffers.empty()) {
638-
// FIXME: Right now this works only with access paths of length 1.
639-
// Once submodules are designed, this needs to support suffix
640-
// matching and a search path.
641-
auto bufIter = MemoryBuffers.find(moduleID.first.str());
642-
if (bufIter != MemoryBuffers.end()) {
643-
moduleInputBuffer = std::move(bufIter->second);
644-
MemoryBuffers.erase(bufIter);
645-
}
646-
}
647636

648-
// Otherwise look on disk.
649-
if (!moduleInputBuffer) {
650-
if (!findModule(moduleID, &moduleInputBuffer, &moduleDocInputBuffer,
651-
isFramework)) {
652-
return nullptr;
653-
}
654-
if (dependencyTracker) {
655-
// Don't record cached artifacts as dependencies.
656-
StringRef DepPath = moduleInputBuffer->getBufferIdentifier();
657-
if (!isCached(DepPath)) {
658-
dependencyTracker->addDependency(DepPath, /*isSystem=*/false);
659-
}
637+
// Look on disk.
638+
if (!findModule(moduleID, &moduleInputBuffer, &moduleDocInputBuffer,
639+
isFramework)) {
640+
return nullptr;
641+
}
642+
if (dependencyTracker) {
643+
// Don't record cached artifacts as dependencies.
644+
StringRef DepPath = moduleInputBuffer->getBufferIdentifier();
645+
if (!isCached(DepPath)) {
646+
dependencyTracker->addDependency(DepPath, /*isSystem=*/false);
660647
}
661648
}
662649

@@ -675,6 +662,43 @@ ModuleDecl *SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
675662
return M;
676663
}
677664

665+
ModuleDecl *
666+
MemoryBufferSerializedModuleLoader::loadModule(SourceLoc importLoc,
667+
ModuleDecl::AccessPathTy path) {
668+
// FIXME: Swift submodules?
669+
if (path.size() > 1)
670+
return nullptr;
671+
672+
auto moduleID = path[0];
673+
674+
// See if we find it in the registered memory buffers.
675+
676+
// FIXME: Right now this works only with access paths of length 1.
677+
// Once submodules are designed, this needs to support suffix
678+
// matching and a search path.
679+
auto bufIter = MemoryBuffers.find(moduleID.first.str());
680+
if (bufIter == MemoryBuffers.end())
681+
return nullptr;
682+
683+
bool isFramework = false;
684+
bool treatAsPartialModule = false;
685+
std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer;
686+
moduleInputBuffer = std::move(bufIter->second);
687+
MemoryBuffers.erase(bufIter);
688+
assert(moduleInputBuffer);
689+
690+
auto *M = ModuleDecl::create(moduleID.first, Ctx);
691+
SWIFT_DEFER { M->setHasResolvedImports(); };
692+
693+
if (!loadAST(*M, moduleID.second, std::move(moduleInputBuffer), {},
694+
isFramework, treatAsPartialModule)) {
695+
return nullptr;
696+
}
697+
698+
Ctx.LoadedModules[moduleID.first] = M;
699+
return M;
700+
}
701+
678702
void SerializedModuleLoaderBase::loadExtensions(NominalTypeDecl *nominal,
679703
unsigned previousGeneration) {
680704
for (auto &modulePair : LoadedModuleFiles) {
@@ -698,6 +722,24 @@ void SerializedModuleLoaderBase::loadObjCMethods(
698722
}
699723
}
700724

725+
std::error_code MemoryBufferSerializedModuleLoader::findModuleFilesInDirectory(
726+
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
727+
StringRef ModuleDocFilename,
728+
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
729+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) {
730+
// This is a soft error instead of an llvm_unreachable because this API is
731+
// primarily used by LLDB which makes it more likely that unwitting changes to
732+
// the Swift compiler accidentally break the contract.
733+
assert(false && "not supported");
734+
return std::make_error_code(std::errc::not_supported);
735+
}
736+
737+
bool MemoryBufferSerializedModuleLoader::maybeDiagnoseTargetMismatch(
738+
SourceLoc sourceLocation, StringRef moduleName, StringRef archName,
739+
StringRef directoryPath) {
740+
return false;
741+
}
742+
701743
void SerializedModuleLoaderBase::verifyAllModules() {
702744
#ifndef NDEBUG
703745
for (const LoadedModulePair &loaded : LoadedModuleFiles)

Diff for: tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ int main(int argc, char **argv) {
282282

283283
Invocation.setModuleName("lldbtest");
284284
Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
285+
Invocation.getLangOptions().EnableMemoryBufferImporter = true;
285286
Invocation.getLangOptions().EnableDWARFImporter = EnableDWARFImporter;
286287

287288
if (!ResourceDir.empty()) {
@@ -292,7 +293,7 @@ int main(int argc, char **argv) {
292293
return 1;
293294

294295
for (auto &Module : Modules)
295-
if (!parseASTSection(CI.getSerializedModuleLoader(),
296+
if (!parseASTSection(*CI.getMemoryBufferSerializedModuleLoader(),
296297
StringRef(Module.first, Module.second), modules))
297298
return 1;
298299

0 commit comments

Comments
 (0)