Skip to content

Commit e01f4c5

Browse files
committed
---
yaml --- r: 346070 b: refs/heads/master c: 4e9e3a1 h: refs/heads/master
1 parent 6a251b4 commit e01f4c5

File tree

13 files changed

+456
-78
lines changed

13 files changed

+456
-78
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 3a211233113543229b4ad546c8fc368090216e48
2+
refs/heads/master: 4e9e3a1a3ee2b99727d876cf7b28af42af9f1561
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/DiagnosticsFrontend.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ ERROR(missing_dependency_of_parseable_module_interface,none,
276276
ERROR(error_extracting_dependencies_from_cached_module,none,
277277
"error extracting dependencies from cached module '%0'",
278278
(StringRef))
279+
ERROR(unknown_forced_module_loading_mode,none,
280+
"unknown value for SWIFT_FORCE_MODULE_LOADING variable: '%0'",
281+
(StringRef))
279282

280283
#ifndef DIAG_NO_UNDEF
281284
# if defined(DIAG)

trunk/include/swift/Frontend/ParseableInterfaceSupport.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ getModuleCachePathFromClang(const clang::CompilerInstance &Instance);
6161
/// directory, and loading the serialized .swiftmodules from there.
6262
class ParseableInterfaceModuleLoader : public SerializedModuleLoaderBase {
6363
explicit ParseableInterfaceModuleLoader(ASTContext &ctx, StringRef cacheDir,
64-
DependencyTracker *tracker)
65-
: SerializedModuleLoaderBase(ctx, tracker),
64+
DependencyTracker *tracker,
65+
ModuleLoadingMode loadMode)
66+
: SerializedModuleLoaderBase(ctx, tracker, loadMode),
6667
CacheDir(cacheDir)
6768
{}
6869

@@ -83,9 +84,10 @@ class ParseableInterfaceModuleLoader : public SerializedModuleLoaderBase {
8384
public:
8485
static std::unique_ptr<ParseableInterfaceModuleLoader>
8586
create(ASTContext &ctx, StringRef cacheDir,
86-
DependencyTracker *tracker = nullptr) {
87+
DependencyTracker *tracker,
88+
ModuleLoadingMode loadMode) {
8789
return std::unique_ptr<ParseableInterfaceModuleLoader>(
88-
new ParseableInterfaceModuleLoader(ctx, cacheDir, tracker));
90+
new ParseableInterfaceModuleLoader(ctx, cacheDir, tracker, loadMode));
8991
}
9092
};
9193

trunk/include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@
2020
namespace swift {
2121
class ModuleFile;
2222

23+
/// Spceifies how to load modules when both a parseable interface and serialized
24+
/// AST are present, or whether to disallow one format or the other altogether.
25+
enum class ModuleLoadingMode {
26+
PreferParseable,
27+
PreferSerialized,
28+
OnlyParseable,
29+
OnlySerialized
30+
};
31+
2332
/// Common functionality shared between \c SerializedModuleLoader and
2433
/// \c ParseableInterfaceModuleLoader.
2534
class SerializedModuleLoaderBase : public ModuleLoader {
@@ -32,7 +41,9 @@ class SerializedModuleLoaderBase : public ModuleLoader {
3241
protected:
3342
llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> MemoryBuffers;
3443
ASTContext &Ctx;
35-
SerializedModuleLoaderBase(ASTContext &ctx, DependencyTracker *tracker);
44+
ModuleLoadingMode LoadMode;
45+
SerializedModuleLoaderBase(ASTContext &ctx, DependencyTracker *tracker,
46+
ModuleLoadingMode LoadMode);
3647

3748
using AccessPathElem = std::pair<Identifier, SourceLoc>;
3849
bool findModule(AccessPathElem moduleID,
@@ -47,6 +58,18 @@ class SerializedModuleLoaderBase : public ModuleLoader {
4758
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
4859
llvm::SmallVectorImpl<char> &Scratch);
4960

61+
/// If the module loader subclass knows that all options have been tried for
62+
/// loading an architecture-specific file out of a swiftmodule bundle, try
63+
/// to list the architectures that \e are present.
64+
///
65+
/// \returns true if an error diagnostic was emitted
66+
virtual bool maybeDiagnoseArchitectureMismatch(SourceLoc sourceLocation,
67+
StringRef moduleName,
68+
StringRef archName,
69+
StringRef directoryPath) {
70+
return false;
71+
}
72+
5073
public:
5174
virtual ~SerializedModuleLoaderBase();
5275
SerializedModuleLoaderBase(const SerializedModuleLoaderBase &) = delete;
@@ -100,10 +123,23 @@ class SerializedModuleLoaderBase : public ModuleLoader {
100123
/// Imports serialized Swift modules into an ASTContext.
101124
class SerializedModuleLoader : public SerializedModuleLoaderBase {
102125

103-
SerializedModuleLoader(ASTContext &ctx, DependencyTracker *tracker)
104-
: SerializedModuleLoaderBase(ctx, tracker)
126+
SerializedModuleLoader(ASTContext &ctx, DependencyTracker *tracker,
127+
ModuleLoadingMode loadMode)
128+
: SerializedModuleLoaderBase(ctx, tracker, loadMode)
105129
{}
106130

131+
std::error_code
132+
openModuleFiles(StringRef DirName, StringRef ModuleFilename,
133+
StringRef ModuleDocFilename,
134+
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
135+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
136+
llvm::SmallVectorImpl<char> &Scratch) override;
137+
138+
bool maybeDiagnoseArchitectureMismatch(SourceLoc sourceLocation,
139+
StringRef moduleName,
140+
StringRef archName,
141+
StringRef directoryPath) override;
142+
107143
public:
108144
virtual ~SerializedModuleLoader();
109145

@@ -120,9 +156,10 @@ class SerializedModuleLoader : public SerializedModuleLoaderBase {
120156
/// Create a new importer that can load serialized Swift modules
121157
/// into the given ASTContext.
122158
static std::unique_ptr<SerializedModuleLoader>
123-
create(ASTContext &ctx, DependencyTracker *tracker = nullptr) {
159+
create(ASTContext &ctx, DependencyTracker *tracker = nullptr,
160+
ModuleLoadingMode loadMode = ModuleLoadingMode::PreferSerialized) {
124161
return std::unique_ptr<SerializedModuleLoader>{
125-
new SerializedModuleLoader(ctx, tracker)
162+
new SerializedModuleLoader(ctx, tracker, loadMode)
126163
};
127164
}
128165
};

trunk/lib/Frontend/Frontend.cpp

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "llvm/Support/CommandLine.h"
3737
#include "llvm/Support/MemoryBuffer.h"
3838
#include "llvm/Support/Path.h"
39+
#include "llvm/Support/Process.h"
3940

4041
using namespace swift;
4142

@@ -288,33 +289,54 @@ bool CompilerInstance::setUpModuleLoaders() {
288289
enableResilience,
289290
getDependencyTracker()));
290291
}
291-
{
292-
auto SML = SerializedModuleLoader::create(*Context, getDependencyTracker());
293-
this->SML = SML.get();
294-
Context->addModuleLoader(std::move(SML));
292+
auto MLM = ModuleLoadingMode::OnlySerialized;
293+
if (Invocation.getFrontendOptions().EnableParseableModuleInterface) {
294+
MLM = ModuleLoadingMode::PreferSerialized;
295295
}
296-
std::string ModuleCachePath;
297-
{
298-
// Wire up the Clang importer. If the user has specified an SDK, use it.
299-
// Otherwise, we just keep it around as our interface to Clang's ABI
300-
// knowledge.
301-
auto clangImporter =
302-
ClangImporter::create(*Context, Invocation.getClangImporterOptions(),
303-
Invocation.getPCHHash(), getDependencyTracker());
304-
if (!clangImporter) {
305-
Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
296+
if (auto forceModuleLoadingMode =
297+
llvm::sys::Process::GetEnv("SWIFT_FORCE_MODULE_LOADING")) {
298+
if (*forceModuleLoadingMode == "prefer-parseable")
299+
MLM = ModuleLoadingMode::PreferParseable;
300+
else if (*forceModuleLoadingMode == "prefer-serialized")
301+
MLM = ModuleLoadingMode::PreferSerialized;
302+
else if (*forceModuleLoadingMode == "only-parseable")
303+
MLM = ModuleLoadingMode::OnlyParseable;
304+
else if (*forceModuleLoadingMode == "only-serialized")
305+
MLM = ModuleLoadingMode::OnlySerialized;
306+
else {
307+
Diagnostics.diagnose(SourceLoc(),
308+
diag::unknown_forced_module_loading_mode,
309+
*forceModuleLoadingMode);
306310
return true;
307311
}
308-
auto const &Clang = clangImporter->getClangInstance();
309-
ModuleCachePath = getModuleCachePathFromClang(Clang);
310-
Context->addModuleLoader(std::move(clangImporter), /*isClang*/ true);
311312
}
312-
if (Invocation.getFrontendOptions().EnableParseableModuleInterface) {
313+
314+
std::unique_ptr<SerializedModuleLoader> SML =
315+
SerializedModuleLoader::create(*Context, getDependencyTracker(), MLM);
316+
this->SML = SML.get();
317+
318+
// Wire up the Clang importer. If the user has specified an SDK, use it.
319+
// Otherwise, we just keep it around as our interface to Clang's ABI
320+
// knowledge.
321+
std::unique_ptr<ClangImporter> clangImporter =
322+
ClangImporter::create(*Context, Invocation.getClangImporterOptions(),
323+
Invocation.getPCHHash(), getDependencyTracker());
324+
if (!clangImporter) {
325+
Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
326+
return true;
327+
}
328+
329+
if (MLM != ModuleLoadingMode::OnlySerialized) {
330+
auto const &Clang = clangImporter->getClangInstance();
331+
std::string ModuleCachePath = getModuleCachePathFromClang(Clang);
313332
auto PIML = ParseableInterfaceModuleLoader::create(*Context,
314333
ModuleCachePath,
315-
getDependencyTracker());
334+
getDependencyTracker(),
335+
MLM);
316336
Context->addModuleLoader(std::move(PIML));
317337
}
338+
Context->addModuleLoader(std::move(SML));
339+
Context->addModuleLoader(std::move(clangImporter), /*isClang*/ true);
318340
return false;
319341
}
320342

trunk/lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ static bool buildSwiftModuleFromSwiftInterface(
279279
StringRef ModuleCachePath, DependencyTracker *OuterTracker) {
280280
bool SubError = false;
281281
bool RunSuccess = llvm::CrashRecoveryContext().RunSafelyOnThread([&] {
282+
(void)llvm::sys::fs::create_directory(ModuleCachePath);
282283

283284
llvm::BumpPtrAllocator SubArgsAlloc;
284285
llvm::StringSaver SubArgSaver(SubArgsAlloc);
@@ -366,6 +367,17 @@ static bool buildSwiftModuleFromSwiftInterface(
366367
return !RunSuccess || SubError;
367368
}
368369

370+
static bool serializedASTLooksValidOrCannotBeRead(clang::vfs::FileSystem &FS,
371+
StringRef ModPath) {
372+
auto ModBuf = FS.getBufferForFile(ModPath, /*FileSize=*/-1,
373+
/*RequiresNullTerminator=*/false);
374+
if (!ModBuf)
375+
return ModBuf.getError() != std::errc::no_such_file_or_directory;
376+
377+
auto VI = serialization::validateSerializedAST(ModBuf.get()->getBuffer());
378+
return VI.status == serialization::Status::Valid;
379+
}
380+
369381
/// Load a .swiftmodule associated with a .swiftinterface either from a
370382
/// cache or by converting it in a subordinate \c CompilerInstance, caching
371383
/// the results.
@@ -375,18 +387,39 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
375387
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
376388
llvm::SmallVectorImpl<char> &Scratch) {
377389

390+
// If running in OnlySerialized mode, ParseableInterfaceModuleLoader
391+
// should not have been constructed at all.
392+
assert(LoadMode != ModuleLoadingMode::OnlySerialized);
393+
378394
auto &FS = *Ctx.SourceMgr.getFileSystem();
379395
auto &Diags = Ctx.Diags;
380-
llvm::SmallString<128> InPath, OutPath;
396+
llvm::SmallString<128> ModPath, InPath, OutPath;
381397

382398
// First check to see if the .swiftinterface exists at all. Bail if not.
383-
InPath = DirName;
384-
llvm::sys::path::append(InPath, ModuleFilename);
399+
ModPath = DirName;
400+
llvm::sys::path::append(ModPath, ModuleFilename);
401+
385402
auto Ext = file_types::getExtension(file_types::TY_SwiftParseableInterfaceFile);
403+
InPath = ModPath;
386404
llvm::sys::path::replace_extension(InPath, Ext);
387405
if (!FS.exists(InPath))
388406
return std::make_error_code(std::errc::no_such_file_or_directory);
389407

408+
// Next, if we're in the load mode that prefers .swiftmodules, see if there's
409+
// one here we can _likely_ load (validates OK). If so, bail early with
410+
// errc::not_supported, so the next (serialized) loader in the chain will load
411+
// it. Alternately, if there's a .swiftmodule present but we can't even read
412+
// it (for whatever reason), we should let the other module loader diagnose
413+
// it.
414+
if (LoadMode == ModuleLoadingMode::PreferSerialized &&
415+
serializedASTLooksValidOrCannotBeRead(FS, ModPath)) {
416+
return std::make_error_code(std::errc::not_supported);
417+
}
418+
419+
// At this point we're either in PreferParseable mode or there's no credible
420+
// adjacent .swiftmodule so we'll go ahead and start trying to convert the
421+
// .swiftinterface.
422+
390423
// Set up a _potential_ sub-invocation to consume the .swiftinterface and emit
391424
// the .swiftmodule.
392425
CompilerInvocation SubInvocation;

0 commit comments

Comments
 (0)