Skip to content

Commit 6898aae

Browse files
committed
Make use of ModuleDecl::isImportedImplementationOnly() when searching for visible access path between 2 modules
1 parent 1a18225 commit 6898aae

File tree

1 file changed

+25
-65
lines changed

1 file changed

+25
-65
lines changed

lib/Sema/TypeCheckAccess.cpp

Lines changed: 25 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,7 @@
2525
#include "swift/AST/Import.h"
2626
#include "swift/AST/Pattern.h"
2727
#include "swift/AST/ParameterList.h"
28-
#include "swift/AST/SourceFile.h"
29-
#include "swift/AST/Type.h"
3028
#include "swift/AST/TypeCheckRequests.h"
31-
#include "clang/AST/Type.h"
32-
#include "clang/Basic/Module.h"
33-
#include "llvm/ADT/SmallPtrSet.h"
34-
#include "llvm/ADT/SmallVector.h"
3529

3630
using namespace swift;
3731

@@ -1446,47 +1440,6 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
14461440
}
14471441
}
14481442
};
1449-
1450-
void getVisibleModules(
1451-
llvm::SmallPtrSetImpl<const clang::Module *> &visibleModules,
1452-
swift::SourceFile *SF) {
1453-
llvm::SmallPtrSet<swift::ModuleDecl *, 4> seenModules;
1454-
llvm::SmallVector<swift::ModuleDecl *, 4> stack;
1455-
1456-
auto filter = ModuleDecl::ImportFilter(
1457-
{ModuleDecl::ImportFilterKind::Exported,
1458-
ModuleDecl::ImportFilterKind::Default,
1459-
ModuleDecl::ImportFilterKind::SPIAccessControl,
1460-
ModuleDecl::ImportFilterKind::ShadowedByCrossImportOverlay});
1461-
1462-
SmallVector<ImportedModule, 4> sfImportedModules;
1463-
1464-
SF->getImportedModules(sfImportedModules, filter);
1465-
1466-
for (auto importedModule : sfImportedModules) {
1467-
stack.push_back(importedModule.importedModule);
1468-
seenModules.insert(importedModule.importedModule);
1469-
}
1470-
1471-
while (!stack.empty()) {
1472-
auto module = stack.pop_back_val();
1473-
if (auto clangModule = module->findUnderlyingClangModule()) {
1474-
visibleModules.insert(clangModule);
1475-
continue;
1476-
}
1477-
1478-
SmallVector<ImportedModule, 4> importedModules;
1479-
module->getImportedModules(importedModules, filter);
1480-
1481-
for (auto &importedModule : importedModules) {
1482-
auto moduleDecl = importedModule.importedModule;
1483-
if (!seenModules.contains(moduleDecl)) {
1484-
seenModules.insert(moduleDecl);
1485-
stack.push_back(moduleDecl);
1486-
}
1487-
}
1488-
}
1489-
}
14901443
} // end anonymous namespace
14911444

14921445
/// Returns the kind of origin, implementation-only import or SPI declaration,
@@ -1499,9 +1452,7 @@ swift::getDisallowedOriginKind(const Decl *decl,
14991452
DowngradeToWarning &downgradeToWarning) {
15001453
downgradeToWarning = DowngradeToWarning::No;
15011454
ModuleDecl *M = decl->getModuleContext();
1502-
15031455
auto *SF = where.getDeclContext()->getParentSourceFile();
1504-
15051456
if (SF->isImportedImplementationOnly(M)) {
15061457
// Temporarily downgrade implementation-only exportability in SPI to
15071458
// a warning.
@@ -1510,27 +1461,36 @@ swift::getDisallowedOriginKind(const Decl *decl,
15101461

15111462
// Even if the current module is @_implementationOnly, Swift should
15121463
// not report an error in the cases where the decl is also exported from
1513-
// a non @_implementationOnly module. Thus, we look at all the visible
1514-
// modules and see if we can find the decl in a non @_implementationOnly
1515-
// module.
1516-
llvm::SmallPtrSet<const clang::Module *, 4> visibleModules;
1517-
getVisibleModules(visibleModules, SF);
1518-
1464+
// a non @_implementationOnly module. Thus, we check to see if there is
1465+
// a visible access path to the Clang decl, and only error out in case
1466+
// there is none.
1467+
auto filter = ModuleDecl::ImportFilter(
1468+
{ModuleDecl::ImportFilterKind::Exported,
1469+
ModuleDecl::ImportFilterKind::Default,
1470+
ModuleDecl::ImportFilterKind::SPIAccessControl,
1471+
ModuleDecl::ImportFilterKind::ShadowedByCrossImportOverlay});
1472+
SmallVector<ImportedModule, 4> sfImportedModules;
1473+
SF->getImportedModules(sfImportedModules, filter);
15191474
if (auto clangDecl = decl->getClangDecl()) {
15201475
for (auto redecl : clangDecl->redecls()) {
1521-
if (!visibleModules.contains(redecl->getOwningModule())) {
1522-
continue;
1523-
}
1524-
1525-
if (auto tagRedecl = dyn_cast<clang::TagDecl>(redecl)) {
1526-
// This is a forward declaration.
1527-
// We ignore visibility of these.
1528-
if (tagRedecl->getBraceRange().isInvalid()) {
1476+
if (auto tagReDecl = dyn_cast<clang::TagDecl>(redecl)) {
1477+
// This is a forward declaration. We ignore visibility of those.
1478+
if (tagReDecl->getBraceRange().isInvalid()) {
15291479
continue;
15301480
}
15311481
}
1532-
1533-
return DisallowedOriginKind::None;
1482+
auto moduleWrapper =
1483+
decl->getASTContext().getClangModuleLoader()->getWrapperForModule(
1484+
redecl->getOwningModule());
1485+
auto visibleAccessPath =
1486+
find_if(sfImportedModules, [&moduleWrapper](auto importedModule) {
1487+
return importedModule.importedModule == moduleWrapper ||
1488+
!importedModule.importedModule
1489+
->isImportedImplementationOnly(moduleWrapper);
1490+
});
1491+
if (visibleAccessPath != sfImportedModules.end()) {
1492+
return DisallowedOriginKind::None;
1493+
}
15341494
}
15351495
}
15361496
// Implementation-only imported, cannot be reexported.

0 commit comments

Comments
 (0)