14
14
#include " swift/AST/ASTContext.h"
15
15
#include " swift/AST/Decl.h"
16
16
#include " swift/AST/DiagnosticsFrontend.h"
17
+ #include " swift/AST/DiagnosticsSema.h"
17
18
#include " swift/AST/ExistentialLayout.h"
18
19
#include " swift/AST/FileSystem.h"
19
20
#include " swift/AST/Module.h"
@@ -47,15 +48,15 @@ using FileDependency = SerializationOptions::FileDependency;
47
48
static swift::version::Version InterfaceFormatVersion ({1 , 0 });
48
49
49
50
static bool
50
- extractSwiftInterfaceVersionAndArgs (DiagnosticEngine &Diags,
51
+ extractSwiftInterfaceVersionAndArgs (DiagnosticEngine &Diags, SourceLoc DiagLoc,
51
52
clang::vfs::FileSystem &FS,
52
53
StringRef SwiftInterfacePathIn,
53
54
swift::version::Version &Vers,
54
55
llvm::StringSaver &SubArgSaver,
55
56
SmallVectorImpl<const char *> &SubArgs) {
56
57
auto FileOrError = swift::vfs::getFileOrSTDIN (FS, SwiftInterfacePathIn);
57
58
if (!FileOrError) {
58
- Diags.diagnose (SourceLoc () , diag::error_open_input_file,
59
+ Diags.diagnose (DiagLoc , diag::error_open_input_file,
59
60
SwiftInterfacePathIn, FileOrError.getError ().message ());
60
61
return true ;
61
62
}
@@ -64,12 +65,12 @@ extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
64
65
auto FlagRe = getSwiftInterfaceModuleFlagsRegex ();
65
66
SmallVector<StringRef, 1 > VersMatches, FlagMatches;
66
67
if (!VersRe.match (SB, &VersMatches)) {
67
- Diags.diagnose (SourceLoc () ,
68
+ Diags.diagnose (DiagLoc ,
68
69
diag::error_extracting_version_from_parseable_interface);
69
70
return true ;
70
71
}
71
72
if (!FlagRe.match (SB, &FlagMatches)) {
72
- Diags.diagnose (SourceLoc () ,
73
+ Diags.diagnose (DiagLoc ,
73
74
diag::error_extracting_flags_from_parseable_interface);
74
75
return true ;
75
76
}
@@ -83,11 +84,11 @@ extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
83
84
static std::unique_ptr<llvm::MemoryBuffer>
84
85
getBufferOfDependency (clang::vfs::FileSystem &FS,
85
86
StringRef ModulePath, StringRef DepPath,
86
- DiagnosticEngine &Diags) {
87
+ DiagnosticEngine &Diags, SourceLoc DiagLoc ) {
87
88
auto DepBuf = FS.getBufferForFile (DepPath, /* FileSize=*/ -1 ,
88
89
/* RequiresNullTerminator=*/ false );
89
90
if (!DepBuf) {
90
- Diags.diagnose (SourceLoc () ,
91
+ Diags.diagnose (DiagLoc ,
91
92
diag::missing_dependency_of_parseable_module_interface,
92
93
DepPath, ModulePath, DepBuf.getError ().message ());
93
94
return nullptr ;
@@ -130,6 +131,7 @@ static std::string getCacheHash(ASTContext &Ctx,
130
131
void
131
132
ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths (
132
133
CompilerInvocation &SubInvocation,
134
+ Identifier ModuleName,
133
135
StringRef InPath,
134
136
llvm::SmallString<128 > &OutPath) {
135
137
@@ -145,37 +147,46 @@ ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths(
145
147
SubInvocation.setRuntimeResourcePath (SearchPathOpts.RuntimeResourcePath );
146
148
SubInvocation.setTargetTriple (LangOpts.Target );
147
149
SubInvocation.setClangModuleCachePath (CacheDir);
150
+ SubInvocation.setModuleName (ModuleName.str ());
148
151
149
152
// Inhibit warnings from the SubInvocation since we are assuming the user
150
153
// is not in a position to fix them.
151
154
SubInvocation.getDiagnosticOptions ().SuppressWarnings = true ;
152
155
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
+
160
+ // Disable this; deinitializers always get printed with `@objc` even in
161
+ // modules that don't import Foundation.
162
+ SubInvocation.getLangOptions ().EnableObjCAttrRequiresFoundation = false ;
163
+
153
164
// Calculate an output filename that includes a hash of relevant key data, and
154
165
// wire up the SubInvocation's InputsAndOutputs to contain both input and
155
166
// output filenames.
156
167
OutPath = CacheDir;
157
- llvm::sys::path::append (OutPath, llvm::sys::path::stem (InPath ));
168
+ llvm::sys::path::append (OutPath, ModuleName. str ( ));
158
169
OutPath.append (" -" );
159
170
OutPath.append (getCacheHash (Ctx, SubInvocation, InPath));
160
171
OutPath.append (" ." );
161
172
auto OutExt = file_types::getExtension (file_types::TY_SwiftModuleFile);
162
173
OutPath.append (OutExt);
163
174
164
- auto &FEOpts = SubInvocation.getFrontendOptions ();
165
- FEOpts .RequestedAction = FrontendOptions::ActionType::EmitModuleOnly;
166
- FEOpts .EnableParseableModuleInterface = true ;
167
- FEOpts .InputsAndOutputs .addPrimaryInputFile (InPath);
175
+ auto &SubFEOpts = SubInvocation.getFrontendOptions ();
176
+ SubFEOpts .RequestedAction = FrontendOptions::ActionType::EmitModuleOnly;
177
+ SubFEOpts .EnableParseableModuleInterface = true ;
178
+ SubFEOpts .InputsAndOutputs .addPrimaryInputFile (InPath);
168
179
SupplementaryOutputPaths SOPs;
169
180
SOPs.ModuleOutputPath = OutPath.str ();
170
181
StringRef MainOut = " /dev/null" ;
171
- FEOpts .InputsAndOutputs .setMainAndSupplementaryOutputs ({MainOut}, {SOPs});
182
+ SubFEOpts .InputsAndOutputs .setMainAndSupplementaryOutputs ({MainOut}, {SOPs});
172
183
}
173
184
174
185
// Check that the output .swiftmodule file is at least as new as all the
175
186
// dependencies it read when it was built last time.
176
187
static bool
177
188
swiftModuleIsUpToDate (clang::vfs::FileSystem &FS,
178
- StringRef ModuleCachePath ,
189
+ std::pair<Identifier, SourceLoc> ModuleID ,
179
190
StringRef OutPath,
180
191
DiagnosticEngine &Diags,
181
192
DependencyTracker *OuterTracker) {
@@ -193,10 +204,14 @@ swiftModuleIsUpToDate(clang::vfs::FileSystem &FS,
193
204
if (VI.status != serialization::Status::Valid)
194
205
return false ;
195
206
207
+ assert (VI.name == ModuleID.first .str () &&
208
+ " we built a module at this path with a different name?" );
209
+
196
210
for (auto In : AllDeps) {
197
211
if (OuterTracker)
198
212
OuterTracker->addDependency (In.Path , /* IsSystem=*/ false );
199
- auto DepBuf = getBufferOfDependency (FS, OutPath, In.Path , Diags);
213
+ auto DepBuf = getBufferOfDependency (FS, OutPath, In.Path , Diags,
214
+ ModuleID.second );
200
215
if (!DepBuf ||
201
216
DepBuf->getBufferSize () != In.Size ||
202
217
xxHash64 (DepBuf->getBuffer ()) != In.Hash ) {
@@ -225,7 +240,7 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
225
240
CompilerInstance &SubInstance,
226
241
StringRef InPath, StringRef ModuleCachePath,
227
242
SmallVectorImpl<FileDependency> &Deps,
228
- DiagnosticEngine &Diags,
243
+ DiagnosticEngine &Diags, SourceLoc DiagLoc,
229
244
DependencyTracker *OuterTracker) {
230
245
auto DTDeps = SubInstance.getDependencyTracker ()->getDependencies ();
231
246
SmallVector<StringRef, 16 > InitialDepNames (DTDeps.begin (), DTDeps.end ());
@@ -235,7 +250,7 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
235
250
if (AllDepNames.insert (DepName).second && OuterTracker) {
236
251
OuterTracker->addDependency (DepName, /* IsSystem=*/ false );
237
252
}
238
- auto DepBuf = getBufferOfDependency (FS, InPath, DepName, Diags);
253
+ auto DepBuf = getBufferOfDependency (FS, InPath, DepName, Diags, DiagLoc );
239
254
if (!DepBuf) {
240
255
return true ;
241
256
}
@@ -256,7 +271,7 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
256
271
DepBuf->getBuffer (),
257
272
/* ExtendedValidationInfo=*/ nullptr , &SubDeps);
258
273
if (VI.status != serialization::Status::Valid) {
259
- Diags.diagnose (SourceLoc () ,
274
+ Diags.diagnose (DiagLoc ,
260
275
diag::error_extracting_dependencies_from_cached_module,
261
276
DepName);
262
277
return true ;
@@ -274,7 +289,7 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
274
289
}
275
290
276
291
static bool buildSwiftModuleFromSwiftInterface (
277
- clang::vfs::FileSystem &FS, DiagnosticEngine &Diags,
292
+ clang::vfs::FileSystem &FS, DiagnosticEngine &Diags, SourceLoc DiagLoc,
278
293
CompilerInvocation &SubInvocation, StringRef InPath, StringRef OutPath,
279
294
StringRef ModuleCachePath, DependencyTracker *OuterTracker) {
280
295
bool SubError = false ;
@@ -285,7 +300,7 @@ static bool buildSwiftModuleFromSwiftInterface(
285
300
llvm::StringSaver SubArgSaver (SubArgsAlloc);
286
301
SmallVector<const char *, 16 > SubArgs;
287
302
swift::version::Version Vers;
288
- if (extractSwiftInterfaceVersionAndArgs (Diags, FS, InPath, Vers,
303
+ if (extractSwiftInterfaceVersionAndArgs (Diags, DiagLoc, FS, InPath, Vers,
289
304
SubArgSaver, SubArgs)) {
290
305
SubError = true ;
291
306
return ;
@@ -295,18 +310,29 @@ static bool buildSwiftModuleFromSwiftInterface(
295
310
// minor versions might be interesting for debugging, or special-casing a
296
311
// compatible field variant.
297
312
if (Vers.asMajorVersion () != InterfaceFormatVersion.asMajorVersion ()) {
298
- Diags.diagnose (SourceLoc () ,
313
+ Diags.diagnose (DiagLoc ,
299
314
diag::unsupported_version_of_parseable_interface,
300
315
InPath, Vers);
301
316
SubError = true ;
302
317
return ;
303
318
}
304
319
320
+ SmallString<32 > ExpectedModuleName = SubInvocation.getModuleName ();
305
321
if (SubInvocation.parseArgs (SubArgs, Diags)) {
306
322
SubError = true ;
307
323
return ;
308
324
}
309
325
326
+ if (SubInvocation.getModuleName () != ExpectedModuleName) {
327
+ auto DiagKind = diag::serialization_name_mismatch;
328
+ if (SubInvocation.getLangOptions ().DebuggerSupport )
329
+ DiagKind = diag::serialization_name_mismatch_repl;
330
+ Diags.diagnose (DiagLoc, DiagKind, SubInvocation.getModuleName (),
331
+ ExpectedModuleName);
332
+ SubError = true ;
333
+ return ;
334
+ }
335
+
310
336
// Optimize emitted modules. This has to happen after we parse arguments,
311
337
// because parseSILOpts would override the current optimization mode.
312
338
SubInvocation.getSILOptions ().OptMode = OptimizationMode::ForSpeed;
@@ -353,7 +379,7 @@ static bool buildSwiftModuleFromSwiftInterface(
353
379
SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName ;
354
380
SmallVector<FileDependency, 16 > Deps;
355
381
if (collectDepsForSerialization (FS, SubInstance, InPath, ModuleCachePath,
356
- Deps, Diags, OuterTracker)) {
382
+ Deps, Diags, DiagLoc, OuterTracker)) {
357
383
SubError = true ;
358
384
return ;
359
385
}
@@ -389,7 +415,8 @@ static bool serializedASTLooksValidOrCannotBeRead(clang::vfs::FileSystem &FS,
389
415
// / cache or by converting it in a subordinate \c CompilerInstance, caching
390
416
// / the results.
391
417
std::error_code ParseableInterfaceModuleLoader::openModuleFiles (
392
- StringRef DirName, StringRef ModuleFilename, StringRef ModuleDocFilename,
418
+ AccessPathElem ModuleID, StringRef DirName, StringRef ModuleFilename,
419
+ StringRef ModuleDocFilename,
393
420
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
394
421
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
395
422
llvm::SmallVectorImpl<char > &Scratch) {
@@ -430,12 +457,14 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
430
457
// Set up a _potential_ sub-invocation to consume the .swiftinterface and emit
431
458
// the .swiftmodule.
432
459
CompilerInvocation SubInvocation;
433
- configureSubInvocationAndOutputPaths (SubInvocation, InPath, OutPath);
460
+ configureSubInvocationAndOutputPaths (SubInvocation, ModuleID.first , InPath,
461
+ OutPath);
434
462
435
463
// 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))
464
+ if (!swiftModuleIsUpToDate (FS, ModuleID, OutPath, Diags, dependencyTracker)) {
465
+ if (buildSwiftModuleFromSwiftInterface (FS, Diags, ModuleID.second ,
466
+ SubInvocation, InPath, OutPath,
467
+ CacheDir, dependencyTracker))
439
468
return std::make_error_code (std::errc::invalid_argument);
440
469
}
441
470
@@ -444,8 +473,8 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
444
473
LLVM_DEBUG (llvm::dbgs () << " Loading " << OutPath
445
474
<< " via normal module loader\n " );
446
475
auto ErrorCode = SerializedModuleLoaderBase::openModuleFiles (
447
- CacheDir, llvm::sys::path::filename (OutPath), ModuleDocFilename ,
448
- ModuleBuffer, ModuleDocBuffer, Scratch);
476
+ ModuleID, CacheDir, llvm::sys::path::filename (OutPath),
477
+ ModuleDocFilename, ModuleBuffer, ModuleDocBuffer, Scratch);
449
478
LLVM_DEBUG (llvm::dbgs () << " Loaded " << OutPath
450
479
<< " via normal module loader" );
451
480
if (ErrorCode) {
0 commit comments