17
17
#include " ModuleFormat.h"
18
18
#include " swift/Serialization/SerializationOptions.h"
19
19
#include " swift/Subsystems.h"
20
+ #include " swift/AST/DiagnosticsSema.h"
20
21
#include " swift/AST/ASTContext.h"
21
22
#include " swift/AST/ASTMangler.h"
22
23
#include " swift/AST/GenericSignature.h"
@@ -122,56 +123,19 @@ bool ModuleFile::allowCompilerErrors() const {
122
123
return getContext ().LangOpts .AllowModuleWithCompilerErrors ;
123
124
}
124
125
125
- Status ModuleFile::associateWithFileContext (FileUnit *file, SourceLoc diagLoc,
126
- bool recoverFromIncompatibility) {
127
- PrettyStackTraceModuleFile stackEntry (*this );
128
-
129
- assert (!hasError () && " error already detected; should not call this" );
130
- assert (!FileContext && " already associated with an AST module" );
131
- FileContext = file;
132
- Status status = Status::Valid;
133
-
134
- ModuleDecl *M = file->getParentModule ();
135
- // The real (on-disk) name of the module should be checked here as that's the
136
- // actually loaded module. In case module aliasing is used when building the main
137
- // module, e.g. -module-name MyModule -module-alias Foo=Bar, the loaded module
138
- // that maps to 'Foo' is actually Bar.swiftmodule|.swiftinterface (applies to swift
139
- // modules only), which is retrieved via M->getRealName(). If no module aliasing is
140
- // used, M->getRealName() will return the same value as M->getName(), which is 'Foo'.
141
- if (M->getRealName ().str () != Core->Name ) {
142
- return error (Status::NameMismatch);
143
- }
144
-
126
+ Status
127
+ ModuleFile::loadDependenciesForFileContext (const FileUnit *file,
128
+ SourceLoc diagLoc,
129
+ bool forTestable) {
145
130
ASTContext &ctx = getContext ();
146
-
147
- llvm::Triple moduleTarget (llvm::Triple::normalize (Core->TargetTriple ));
148
- if (!areCompatibleArchitectures (moduleTarget, ctx.LangOpts .Target ) ||
149
- !areCompatibleOSs (moduleTarget, ctx.LangOpts .Target )) {
150
- status = Status::TargetIncompatible;
151
- if (!recoverFromIncompatibility)
152
- return error (status);
153
- } else if (ctx.LangOpts .EnableTargetOSChecking && !M->isResilient () &&
154
- isTargetTooNew (moduleTarget, ctx.LangOpts .Target )) {
155
- status = Status::TargetTooNew;
156
- if (!recoverFromIncompatibility)
157
- return error (status);
158
- }
159
-
160
- StringRef SDKPath = ctx.SearchPathOpts .getSDKPath ();
161
- if (SDKPath.empty () ||
162
- !Core->ModuleInputBuffer ->getBufferIdentifier ().startswith (SDKPath)) {
163
- for (const auto &searchPath : Core->SearchPaths ) {
164
- ctx.addSearchPath (
165
- ctx.SearchPathOpts .SearchPathRemapper .remapPath (searchPath.Path ),
166
- searchPath.IsFramework ,
167
- searchPath.IsSystem );
168
- }
169
- }
170
-
171
131
auto clangImporter = static_cast <ClangImporter *>(ctx.getClangModuleLoader ());
132
+ ModuleDecl *M = file->getParentModule ();
172
133
173
134
bool missingDependency = false ;
174
135
for (auto &dependency : Dependencies) {
136
+ if (forTestable && dependency.isLoaded ())
137
+ continue ;
138
+
175
139
assert (!dependency.isLoaded () && " already loaded?" );
176
140
177
141
if (dependency.isHeader ()) {
@@ -195,7 +159,15 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
195
159
}
196
160
197
161
ModuleLoadingBehavior transitiveBehavior =
198
- getTransitiveLoadingBehavior (dependency);
162
+ getTransitiveLoadingBehavior (dependency, forTestable);
163
+
164
+ if (ctx.LangOpts .EnableModuleLoadingRemarks ) {
165
+ ctx.Diags .diagnose (diagLoc,
166
+ diag::transitive_dependency_behavior,
167
+ dependency.Core .getPrettyPrintedPath (),
168
+ M->getName (),
169
+ unsigned (transitiveBehavior));
170
+ }
199
171
200
172
// Skip this dependency?
201
173
if (transitiveBehavior == ModuleLoadingBehavior::Ignored)
@@ -250,6 +222,59 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
250
222
return error (Status::MissingDependency);
251
223
}
252
224
225
+ return Status::Valid;
226
+ }
227
+
228
+ Status ModuleFile::associateWithFileContext (FileUnit *file, SourceLoc diagLoc,
229
+ bool recoverFromIncompatibility) {
230
+ PrettyStackTraceModuleFile stackEntry (*this );
231
+
232
+ assert (!hasError () && " error already detected; should not call this" );
233
+ assert (!FileContext && " already associated with an AST module" );
234
+ FileContext = file;
235
+ Status status = Status::Valid;
236
+
237
+ ModuleDecl *M = file->getParentModule ();
238
+ // The real (on-disk) name of the module should be checked here as that's the
239
+ // actually loaded module. In case module aliasing is used when building the main
240
+ // module, e.g. -module-name MyModule -module-alias Foo=Bar, the loaded module
241
+ // that maps to 'Foo' is actually Bar.swiftmodule|.swiftinterface (applies to swift
242
+ // modules only), which is retrieved via M->getRealName(). If no module aliasing is
243
+ // used, M->getRealName() will return the same value as M->getName(), which is 'Foo'.
244
+ if (M->getRealName ().str () != Core->Name ) {
245
+ return error (Status::NameMismatch);
246
+ }
247
+
248
+ ASTContext &ctx = getContext ();
249
+
250
+ llvm::Triple moduleTarget (llvm::Triple::normalize (Core->TargetTriple ));
251
+ if (!areCompatibleArchitectures (moduleTarget, ctx.LangOpts .Target ) ||
252
+ !areCompatibleOSs (moduleTarget, ctx.LangOpts .Target )) {
253
+ status = Status::TargetIncompatible;
254
+ if (!recoverFromIncompatibility)
255
+ return error (status);
256
+ } else if (ctx.LangOpts .EnableTargetOSChecking && !M->isResilient () &&
257
+ isTargetTooNew (moduleTarget, ctx.LangOpts .Target )) {
258
+ status = Status::TargetTooNew;
259
+ if (!recoverFromIncompatibility)
260
+ return error (status);
261
+ }
262
+
263
+ StringRef SDKPath = ctx.SearchPathOpts .getSDKPath ();
264
+ if (SDKPath.empty () ||
265
+ !Core->ModuleInputBuffer ->getBufferIdentifier ().startswith (SDKPath)) {
266
+ for (const auto &searchPath : Core->SearchPaths ) {
267
+ ctx.addSearchPath (
268
+ ctx.SearchPathOpts .SearchPathRemapper .remapPath (searchPath.Path ),
269
+ searchPath.IsFramework ,
270
+ searchPath.IsSystem );
271
+ }
272
+ }
273
+
274
+ Status res = loadDependenciesForFileContext (file, diagLoc,
275
+ /* forTestable=*/ false );
276
+ if (res != Status::Valid) return res;
277
+
253
278
if (Core->Bits .HasEntryPoint ) {
254
279
FileContext->getParentModule ()->registerEntryPointFile (FileContext,
255
280
SourceLoc (),
@@ -260,7 +285,8 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
260
285
}
261
286
262
287
ModuleLoadingBehavior
263
- ModuleFile::getTransitiveLoadingBehavior (const Dependency &dependency) const {
288
+ ModuleFile::getTransitiveLoadingBehavior (const Dependency &dependency,
289
+ bool forTestable) const {
264
290
ASTContext &ctx = getContext ();
265
291
ModuleDecl *mod = FileContext->getParentModule ();
266
292
@@ -271,7 +297,8 @@ ModuleFile::getTransitiveLoadingBehavior(const Dependency &dependency) const {
271
297
return Core->getTransitiveLoadingBehavior (dependency.Core ,
272
298
ctx.LangOpts .DebuggerSupport ,
273
299
isPartialModule,
274
- ctx.LangOpts .PackageName );
300
+ ctx.LangOpts .PackageName ,
301
+ forTestable);
275
302
}
276
303
277
304
bool ModuleFile::mayHaveDiagnosticsPointingAtBuffer () const {
0 commit comments