Skip to content

Commit a51f1dd

Browse files
committed
[ParseableInterface] Pass down the module name and import source loc
- Use the name for the cached module, so that we don't end up with a zillion "x86_64-XXXXXXXX.swiftmodule" files in the cache when we're working with architecture-specific swiftmodules. - Diagnose if the expected name is different from the name specified in the swiftinterface. - Emit all diagnostics at the location of the import, instead of without any location at all.
1 parent 06f3c11 commit a51f1dd

File tree

6 files changed

+82
-47
lines changed

6 files changed

+82
-47
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,9 +630,9 @@ ERROR(serialization_circular_dependency,Fatal,
630630
ERROR(serialization_missing_shadowed_module,Fatal,
631631
"cannot load underlying module for %0", (Identifier))
632632
ERROR(serialization_name_mismatch,Fatal,
633-
"cannot load module '%0' as %1", (StringRef, Identifier))
633+
"cannot load module '%0' as '%1'", (StringRef, StringRef))
634634
ERROR(serialization_name_mismatch_repl,none,
635-
"cannot load module '%0' as %1", (StringRef, Identifier))
635+
"cannot load module '%0' as '%1'", (StringRef, StringRef))
636636
ERROR(serialization_target_incompatible,Fatal,
637637
"module %0 was created for incompatible target %1: %2",
638638
(Identifier, StringRef, StringRef))

include/swift/Frontend/ParseableInterfaceSupport.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ class ParseableInterfaceModuleLoader : public SerializedModuleLoaderBase {
7171

7272
void
7373
configureSubInvocationAndOutputPaths(CompilerInvocation &SubInvocation,
74-
StringRef InPath,
74+
Identifier ModuleName, StringRef InPath,
7575
llvm::SmallString<128> &OutPath);
7676

7777
std::error_code
78-
openModuleFiles(StringRef DirName, StringRef ModuleFilename,
79-
StringRef ModuleDocFilename,
78+
openModuleFiles(AccessPathElem ModuleID, StringRef DirName,
79+
StringRef ModuleFilename, StringRef ModuleDocFilename,
8080
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
8181
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
8282
llvm::SmallVectorImpl<char> &Scratch) override;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
5252
bool &isFramework);
5353

5454
virtual std::error_code
55-
openModuleFiles(StringRef DirName, StringRef ModuleFilename,
56-
StringRef ModuleDocFilename,
55+
openModuleFiles(AccessPathElem ModuleID, StringRef DirName,
56+
StringRef ModuleFilename, StringRef ModuleDocFilename,
5757
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
5858
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
5959
llvm::SmallVectorImpl<char> &Scratch);
@@ -129,8 +129,8 @@ class SerializedModuleLoader : public SerializedModuleLoaderBase {
129129
{}
130130

131131
std::error_code
132-
openModuleFiles(StringRef DirName, StringRef ModuleFilename,
133-
StringRef ModuleDocFilename,
132+
openModuleFiles(AccessPathElem ModuleID, StringRef DirName,
133+
StringRef ModuleFilename, StringRef ModuleDocFilename,
134134
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
135135
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
136136
llvm::SmallVectorImpl<char> &Scratch) override;

lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "swift/AST/ASTContext.h"
1515
#include "swift/AST/Decl.h"
1616
#include "swift/AST/DiagnosticsFrontend.h"
17+
#include "swift/AST/DiagnosticsSema.h"
1718
#include "swift/AST/ExistentialLayout.h"
1819
#include "swift/AST/FileSystem.h"
1920
#include "swift/AST/Module.h"
@@ -47,15 +48,15 @@ using FileDependency = SerializationOptions::FileDependency;
4748
static swift::version::Version InterfaceFormatVersion({1, 0});
4849

4950
static bool
50-
extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
51+
extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags, SourceLoc DiagLoc,
5152
clang::vfs::FileSystem &FS,
5253
StringRef SwiftInterfacePathIn,
5354
swift::version::Version &Vers,
5455
llvm::StringSaver &SubArgSaver,
5556
SmallVectorImpl<const char *> &SubArgs) {
5657
auto FileOrError = swift::vfs::getFileOrSTDIN(FS, SwiftInterfacePathIn);
5758
if (!FileOrError) {
58-
Diags.diagnose(SourceLoc(), diag::error_open_input_file,
59+
Diags.diagnose(DiagLoc, diag::error_open_input_file,
5960
SwiftInterfacePathIn, FileOrError.getError().message());
6061
return true;
6162
}
@@ -64,12 +65,12 @@ extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
6465
auto FlagRe = getSwiftInterfaceModuleFlagsRegex();
6566
SmallVector<StringRef, 1> VersMatches, FlagMatches;
6667
if (!VersRe.match(SB, &VersMatches)) {
67-
Diags.diagnose(SourceLoc(),
68+
Diags.diagnose(DiagLoc,
6869
diag::error_extracting_version_from_parseable_interface);
6970
return true;
7071
}
7172
if (!FlagRe.match(SB, &FlagMatches)) {
72-
Diags.diagnose(SourceLoc(),
73+
Diags.diagnose(DiagLoc,
7374
diag::error_extracting_flags_from_parseable_interface);
7475
return true;
7576
}
@@ -83,11 +84,11 @@ extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
8384
static std::unique_ptr<llvm::MemoryBuffer>
8485
getBufferOfDependency(clang::vfs::FileSystem &FS,
8586
StringRef ModulePath, StringRef DepPath,
86-
DiagnosticEngine &Diags) {
87+
DiagnosticEngine &Diags, SourceLoc DiagLoc) {
8788
auto DepBuf = FS.getBufferForFile(DepPath, /*FileSize=*/-1,
8889
/*RequiresNullTerminator=*/false);
8990
if (!DepBuf) {
90-
Diags.diagnose(SourceLoc(),
91+
Diags.diagnose(DiagLoc,
9192
diag::missing_dependency_of_parseable_module_interface,
9293
DepPath, ModulePath, DepBuf.getError().message());
9394
return nullptr;
@@ -130,6 +131,7 @@ static std::string getCacheHash(ASTContext &Ctx,
130131
void
131132
ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths(
132133
CompilerInvocation &SubInvocation,
134+
Identifier ModuleName,
133135
StringRef InPath,
134136
llvm::SmallString<128> &OutPath) {
135137

@@ -145,37 +147,42 @@ ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths(
145147
SubInvocation.setRuntimeResourcePath(SearchPathOpts.RuntimeResourcePath);
146148
SubInvocation.setTargetTriple(LangOpts.Target);
147149
SubInvocation.setClangModuleCachePath(CacheDir);
150+
SubInvocation.setModuleName(ModuleName.str());
148151

149152
// Inhibit warnings from the SubInvocation since we are assuming the user
150153
// is not in a position to fix them.
151154
SubInvocation.getDiagnosticOptions().SuppressWarnings = true;
152155

156+
// Inherit this setting down so that it can affect error diagnostics (mostly
157+
// by making them non-fatal).
158+
SubInvocation.getLangOptions().DebuggerSupport = LangOpts.DebuggerSupport;
159+
153160
// Calculate an output filename that includes a hash of relevant key data, and
154161
// wire up the SubInvocation's InputsAndOutputs to contain both input and
155162
// output filenames.
156163
OutPath = CacheDir;
157-
llvm::sys::path::append(OutPath, llvm::sys::path::stem(InPath));
164+
llvm::sys::path::append(OutPath, ModuleName.str());
158165
OutPath.append("-");
159166
OutPath.append(getCacheHash(Ctx, SubInvocation, InPath));
160167
OutPath.append(".");
161168
auto OutExt = file_types::getExtension(file_types::TY_SwiftModuleFile);
162169
OutPath.append(OutExt);
163170

164-
auto &FEOpts = SubInvocation.getFrontendOptions();
165-
FEOpts.RequestedAction = FrontendOptions::ActionType::EmitModuleOnly;
166-
FEOpts.EnableParseableModuleInterface = true;
167-
FEOpts.InputsAndOutputs.addPrimaryInputFile(InPath);
171+
auto &SubFEOpts = SubInvocation.getFrontendOptions();
172+
SubFEOpts.RequestedAction = FrontendOptions::ActionType::EmitModuleOnly;
173+
SubFEOpts.EnableParseableModuleInterface = true;
174+
SubFEOpts.InputsAndOutputs.addPrimaryInputFile(InPath);
168175
SupplementaryOutputPaths SOPs;
169176
SOPs.ModuleOutputPath = OutPath.str();
170177
StringRef MainOut = "/dev/null";
171-
FEOpts.InputsAndOutputs.setMainAndSupplementaryOutputs({MainOut}, {SOPs});
178+
SubFEOpts.InputsAndOutputs.setMainAndSupplementaryOutputs({MainOut}, {SOPs});
172179
}
173180

174181
// Check that the output .swiftmodule file is at least as new as all the
175182
// dependencies it read when it was built last time.
176183
static bool
177184
swiftModuleIsUpToDate(clang::vfs::FileSystem &FS,
178-
StringRef ModuleCachePath,
185+
std::pair<Identifier, SourceLoc> ModuleID,
179186
StringRef OutPath,
180187
DiagnosticEngine &Diags,
181188
DependencyTracker *OuterTracker) {
@@ -193,10 +200,14 @@ swiftModuleIsUpToDate(clang::vfs::FileSystem &FS,
193200
if (VI.status != serialization::Status::Valid)
194201
return false;
195202

203+
assert(VI.name == ModuleID.first.str() &&
204+
"we built a module at this path with a different name?");
205+
196206
for (auto In : AllDeps) {
197207
if (OuterTracker)
198208
OuterTracker->addDependency(In.Path, /*IsSystem=*/false);
199-
auto DepBuf = getBufferOfDependency(FS, OutPath, In.Path, Diags);
209+
auto DepBuf = getBufferOfDependency(FS, OutPath, In.Path, Diags,
210+
ModuleID.second);
200211
if (!DepBuf ||
201212
DepBuf->getBufferSize() != In.Size ||
202213
xxHash64(DepBuf->getBuffer()) != In.Hash) {
@@ -225,7 +236,7 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
225236
CompilerInstance &SubInstance,
226237
StringRef InPath, StringRef ModuleCachePath,
227238
SmallVectorImpl<FileDependency> &Deps,
228-
DiagnosticEngine &Diags,
239+
DiagnosticEngine &Diags, SourceLoc DiagLoc,
229240
DependencyTracker *OuterTracker) {
230241
auto DTDeps = SubInstance.getDependencyTracker()->getDependencies();
231242
SmallVector<StringRef, 16> InitialDepNames(DTDeps.begin(), DTDeps.end());
@@ -235,7 +246,7 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
235246
if (AllDepNames.insert(DepName).second && OuterTracker) {
236247
OuterTracker->addDependency(DepName, /*IsSystem=*/false);
237248
}
238-
auto DepBuf = getBufferOfDependency(FS, InPath, DepName, Diags);
249+
auto DepBuf = getBufferOfDependency(FS, InPath, DepName, Diags, DiagLoc);
239250
if (!DepBuf) {
240251
return true;
241252
}
@@ -256,7 +267,7 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
256267
DepBuf->getBuffer(),
257268
/*ExtendedValidationInfo=*/nullptr, &SubDeps);
258269
if (VI.status != serialization::Status::Valid) {
259-
Diags.diagnose(SourceLoc(),
270+
Diags.diagnose(DiagLoc,
260271
diag::error_extracting_dependencies_from_cached_module,
261272
DepName);
262273
return true;
@@ -274,7 +285,7 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
274285
}
275286

276287
static bool buildSwiftModuleFromSwiftInterface(
277-
clang::vfs::FileSystem &FS, DiagnosticEngine &Diags,
288+
clang::vfs::FileSystem &FS, DiagnosticEngine &Diags, SourceLoc DiagLoc,
278289
CompilerInvocation &SubInvocation, StringRef InPath, StringRef OutPath,
279290
StringRef ModuleCachePath, DependencyTracker *OuterTracker) {
280291
bool SubError = false;
@@ -285,7 +296,7 @@ static bool buildSwiftModuleFromSwiftInterface(
285296
llvm::StringSaver SubArgSaver(SubArgsAlloc);
286297
SmallVector<const char *, 16> SubArgs;
287298
swift::version::Version Vers;
288-
if (extractSwiftInterfaceVersionAndArgs(Diags, FS, InPath, Vers,
299+
if (extractSwiftInterfaceVersionAndArgs(Diags, DiagLoc, FS, InPath, Vers,
289300
SubArgSaver, SubArgs)) {
290301
SubError = true;
291302
return;
@@ -295,18 +306,29 @@ static bool buildSwiftModuleFromSwiftInterface(
295306
// minor versions might be interesting for debugging, or special-casing a
296307
// compatible field variant.
297308
if (Vers.asMajorVersion() != InterfaceFormatVersion.asMajorVersion()) {
298-
Diags.diagnose(SourceLoc(),
309+
Diags.diagnose(DiagLoc,
299310
diag::unsupported_version_of_parseable_interface,
300311
InPath, Vers);
301312
SubError = true;
302313
return;
303314
}
304315

316+
SmallString<32> ExpectedModuleName = SubInvocation.getModuleName();
305317
if (SubInvocation.parseArgs(SubArgs, Diags)) {
306318
SubError = true;
307319
return;
308320
}
309321

322+
if (SubInvocation.getModuleName() != ExpectedModuleName) {
323+
auto DiagKind = diag::serialization_name_mismatch;
324+
if (SubInvocation.getLangOptions().DebuggerSupport)
325+
DiagKind = diag::serialization_name_mismatch_repl;
326+
Diags.diagnose(DiagLoc, DiagKind, SubInvocation.getModuleName(),
327+
ExpectedModuleName);
328+
SubError = true;
329+
return;
330+
}
331+
310332
// Optimize emitted modules. This has to happen after we parse arguments,
311333
// because parseSILOpts would override the current optimization mode.
312334
SubInvocation.getSILOptions().OptMode = OptimizationMode::ForSpeed;
@@ -353,7 +375,7 @@ static bool buildSwiftModuleFromSwiftInterface(
353375
SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName;
354376
SmallVector<FileDependency, 16> Deps;
355377
if (collectDepsForSerialization(FS, SubInstance, InPath, ModuleCachePath,
356-
Deps, Diags, OuterTracker)) {
378+
Deps, Diags, DiagLoc, OuterTracker)) {
357379
SubError = true;
358380
return;
359381
}
@@ -389,7 +411,8 @@ static bool serializedASTLooksValidOrCannotBeRead(clang::vfs::FileSystem &FS,
389411
/// cache or by converting it in a subordinate \c CompilerInstance, caching
390412
/// the results.
391413
std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
392-
StringRef DirName, StringRef ModuleFilename, StringRef ModuleDocFilename,
414+
AccessPathElem ModuleID, StringRef DirName, StringRef ModuleFilename,
415+
StringRef ModuleDocFilename,
393416
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
394417
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
395418
llvm::SmallVectorImpl<char> &Scratch) {
@@ -430,12 +453,14 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
430453
// Set up a _potential_ sub-invocation to consume the .swiftinterface and emit
431454
// the .swiftmodule.
432455
CompilerInvocation SubInvocation;
433-
configureSubInvocationAndOutputPaths(SubInvocation, InPath, OutPath);
456+
configureSubInvocationAndOutputPaths(SubInvocation, ModuleID.first, InPath,
457+
OutPath);
434458

435459
// Evaluate if we need to run this sub-invocation, and if so run it.
436-
if (!swiftModuleIsUpToDate(FS, CacheDir, OutPath, Diags, dependencyTracker)) {
437-
if (buildSwiftModuleFromSwiftInterface(FS, Diags, SubInvocation, InPath,
438-
OutPath, CacheDir, dependencyTracker))
460+
if (!swiftModuleIsUpToDate(FS, ModuleID, OutPath, Diags, dependencyTracker)) {
461+
if (buildSwiftModuleFromSwiftInterface(FS, Diags, ModuleID.second,
462+
SubInvocation, InPath, OutPath,
463+
CacheDir, dependencyTracker))
439464
return std::make_error_code(std::errc::invalid_argument);
440465
}
441466

@@ -444,8 +469,8 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
444469
LLVM_DEBUG(llvm::dbgs() << "Loading " << OutPath
445470
<< " via normal module loader\n");
446471
auto ErrorCode = SerializedModuleLoaderBase::openModuleFiles(
447-
CacheDir, llvm::sys::path::filename(OutPath), ModuleDocFilename,
448-
ModuleBuffer, ModuleDocBuffer, Scratch);
472+
ModuleID, CacheDir, llvm::sys::path::filename(OutPath),
473+
ModuleDocFilename, ModuleBuffer, ModuleDocBuffer, Scratch);
449474
LLVM_DEBUG(llvm::dbgs() << "Loaded " << OutPath
450475
<< " via normal module loader");
451476
if (ErrorCode) {

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ SerializedModuleLoaderBase::~SerializedModuleLoaderBase() = default;
4343
SerializedModuleLoader::~SerializedModuleLoader() = default;
4444

4545
std::error_code SerializedModuleLoaderBase::openModuleFiles(
46-
StringRef DirName, StringRef ModuleFilename, StringRef ModuleDocFilename,
46+
AccessPathElem ModuleID, StringRef DirName, StringRef ModuleFilename,
47+
StringRef ModuleDocFilename,
4748
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
4849
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
4950
llvm::SmallVectorImpl<char> &Scratch) {
@@ -94,14 +95,16 @@ std::error_code SerializedModuleLoaderBase::openModuleFiles(
9495
}
9596

9697
std::error_code SerializedModuleLoader::openModuleFiles(
97-
StringRef DirName, StringRef ModuleFilename, StringRef ModuleDocFilename,
98+
AccessPathElem ModuleID, StringRef DirName, StringRef ModuleFilename,
99+
StringRef ModuleDocFilename,
98100
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
99101
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
100102
llvm::SmallVectorImpl<char> &Scratch) {
101103
if (LoadMode == ModuleLoadingMode::OnlyParseable)
102104
return std::make_error_code(std::errc::not_supported);
103105

104-
return SerializedModuleLoaderBase::openModuleFiles(DirName, ModuleFilename,
106+
return SerializedModuleLoaderBase::openModuleFiles(ModuleID, DirName,
107+
ModuleFilename,
105108
ModuleDocFilename,
106109
ModuleBuffer,
107110
ModuleDocBuffer, Scratch);
@@ -204,14 +207,14 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
204207

205208
if (statResult && statResult->isDirectory()) {
206209
// A .swiftmodule directory contains architecture-specific files.
207-
result = openModuleFiles(currPath,
210+
result = openModuleFiles(moduleID, currPath,
208211
archFileNames.first, archFileNames.second,
209212
moduleBuffer, moduleDocBuffer,
210213
scratch);
211214

212215
if (result == std::errc::no_such_file_or_directory &&
213216
!alternateArchName.empty()) {
214-
result = openModuleFiles(currPath,
217+
result = openModuleFiles(moduleID, currPath,
215218
alternateArchFileNames.first,
216219
alternateArchFileNames.second,
217220
moduleBuffer, moduleDocBuffer,
@@ -228,7 +231,7 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
228231
} else {
229232
// We can't just return the error; the path we're looking for might not
230233
// be "Foo.swiftmodule".
231-
result = openModuleFiles(path,
234+
result = openModuleFiles(moduleID, path,
232235
moduleFilename.str(), moduleDocFilename.str(),
233236
moduleBuffer, moduleDocBuffer,
234237
scratch);
@@ -254,13 +257,13 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
254257
// Frameworks always use architecture-specific files within a .swiftmodule
255258
// directory.
256259
llvm::sys::path::append(currPath, "Modules", moduleFilename.str());
257-
auto err = openModuleFiles(currPath,
260+
auto err = openModuleFiles(moduleID, currPath,
258261
archFileNames.first, archFileNames.second,
259262
moduleBuffer, moduleDocBuffer, scratch);
260263

261264
if (err == std::errc::no_such_file_or_directory &&
262265
!alternateArchName.empty()) {
263-
err = openModuleFiles(currPath,
266+
err = openModuleFiles(moduleID, currPath,
264267
alternateArchFileNames.first,
265268
alternateArchFileNames.second,
266269
moduleBuffer, moduleDocBuffer, scratch);
@@ -302,7 +305,7 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
302305

303306
// Search the runtime import path.
304307
isFramework = false;
305-
return !openModuleFiles(Ctx.SearchPathOpts.RuntimeLibraryImportPath,
308+
return !openModuleFiles(moduleID, Ctx.SearchPathOpts.RuntimeLibraryImportPath,
306309
moduleFilename.str(), moduleDocFilename.str(),
307310
moduleBuffer, moduleDocBuffer, scratch);
308311
}
@@ -543,7 +546,7 @@ void swift::serialization::diagnoseSerializedASTLoadFailure(
543546
auto diagKind = diag::serialization_name_mismatch;
544547
if (Ctx.LangOpts.DebuggerSupport)
545548
diagKind = diag::serialization_name_mismatch_repl;
546-
Ctx.Diags.diagnose(diagLoc, diagKind, loadInfo.name, ModuleName);
549+
Ctx.Diags.diagnose(diagLoc, diagKind, loadInfo.name, ModuleName.str());
547550
break;
548551
}
549552

0 commit comments

Comments
 (0)