|
21 | 21 | #include "swift/AST/FileUnit.h"
|
22 | 22 | #include "swift/AST/ImportCache.h"
|
23 | 23 | #include "swift/AST/Module.h"
|
| 24 | +#include "swift/AST/SourceFile.h" |
24 | 25 |
|
25 | 26 | using namespace swift;
|
26 | 27 | using namespace namelookup;
|
@@ -391,3 +392,56 @@ swift::namelookup::getAllImports(const DeclContext *dc) {
|
391 | 392 | return dc->getASTContext().getImportCache().getImportSet(dc)
|
392 | 393 | .getAllImports();
|
393 | 394 | }
|
| 395 | + |
| 396 | +ArrayRef<ModuleDecl *> ImportCache::allocateArray( |
| 397 | + ASTContext &ctx, |
| 398 | + llvm::SetVector<ModuleDecl *> &results) { |
| 399 | + if (results.empty()) |
| 400 | + return {}; |
| 401 | + else |
| 402 | + return ctx.AllocateCopy(results.getArrayRef()); |
| 403 | +} |
| 404 | + |
| 405 | +ArrayRef<ModuleDecl *> |
| 406 | +ImportCache::getWeakImports(const ModuleDecl *mod) { |
| 407 | + auto found = WeakCache.find(mod); |
| 408 | + if (found != WeakCache.end()) |
| 409 | + return found->second; |
| 410 | + |
| 411 | + llvm::SetVector<ModuleDecl *> result; |
| 412 | + |
| 413 | + for (auto file : mod->getFiles()) { |
| 414 | + auto *sf = dyn_cast<SourceFile>(file); |
| 415 | + // Other kinds of file units, like serialized modules, can just use this |
| 416 | + // default implementation since the @_weakLinked attribute is not |
| 417 | + // transitive. If module C is imported @_weakLinked by module B, that does |
| 418 | + // not imply that module A imports module C @_weakLinked if it imports |
| 419 | + // module B. |
| 420 | + if (!sf) |
| 421 | + continue; |
| 422 | + |
| 423 | + for (auto &import : sf->getImports()) { |
| 424 | + if (!import.options.contains(ImportFlags::WeakLinked)) |
| 425 | + continue; |
| 426 | + |
| 427 | + ModuleDecl *importedModule = import.module.importedModule; |
| 428 | + result.insert(importedModule); |
| 429 | + |
| 430 | + auto reexportedModules = getImportSet(importedModule).getAllImports(); |
| 431 | + for (auto reexportedModule : reexportedModules) { |
| 432 | + result.insert(reexportedModule.importedModule); |
| 433 | + } |
| 434 | + } |
| 435 | + } |
| 436 | + |
| 437 | + auto resultArray = allocateArray(mod->getASTContext(), result); |
| 438 | + WeakCache[mod] = resultArray; |
| 439 | + return resultArray; |
| 440 | +} |
| 441 | + |
| 442 | +bool ImportCache::isWeakImportedBy(const ModuleDecl *mod, |
| 443 | + const ModuleDecl *from) { |
| 444 | + auto weakImports = getWeakImports(from); |
| 445 | + return std::find(weakImports.begin(), weakImports.end(), mod) |
| 446 | + != weakImports.end(); |
| 447 | +} |
0 commit comments