Skip to content

Commit ecebf70

Browse files
Merge pull request #24173 from adrian-prantl/memorybufferloader
Factor out the pre-registered MemoryBuffer functionality
2 parents 502a7bf + b244b09 commit ecebf70

File tree

8 files changed

+163
-64
lines changed

8 files changed

+163
-64
lines changed

include/swift/ASTSectionImporter/ASTSectionImporter.h

Lines changed: 8 additions & 10 deletions
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

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 0 deletions
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

include/swift/Frontend/Frontend.h

Lines changed: 6 additions & 1 deletion
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;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 49 additions & 9 deletions
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;

lib/ASTSectionImporter/ASTSectionImporter.cpp

Lines changed: 3 additions & 2 deletions
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 {

lib/Frontend/Frontend.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ bool CompilerInstance::setUpModuleLoaders() {
314314
}
315315
}
316316

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

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 83 additions & 41 deletions
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,
@@ -608,23 +609,22 @@ void swift::serialization::diagnoseSerializedASTLoadFailure(
608609
}
609610
}
610611

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

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

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

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

@@ -676,6 +663,43 @@ ModuleDecl *SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
676663
return M;
677664
}
678665

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

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

tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp

Lines changed: 2 additions & 1 deletion
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)