[C++20] [Modules] Add exported modules as transitive imported modules

Close https://github.com/llvm/llvm-project/issues/144230

The root cause of the problem is, when we decide the transitive imports,
we didn't deal with exported imports.
This commit is contained in:
Chuanqi Xu 2025-06-20 17:01:35 +08:00
parent 874773635d
commit 14e89b061f
2 changed files with 35 additions and 4 deletions

View File

@ -136,6 +136,7 @@ makeTransitiveImportsVisible(ASTContext &Ctx, VisibleModuleSet &VisibleModules,
"modules only.");
llvm::SmallVector<Module *, 4> Worklist;
llvm::SmallSet<Module *, 16> Visited;
Worklist.push_back(Imported);
Module *FoundPrimaryModuleInterface =
@ -144,18 +145,22 @@ makeTransitiveImportsVisible(ASTContext &Ctx, VisibleModuleSet &VisibleModules,
while (!Worklist.empty()) {
Module *Importing = Worklist.pop_back_val();
if (VisibleModules.isVisible(Importing))
if (Visited.count(Importing))
continue;
Visited.insert(Importing);
// FIXME: The ImportLoc here is not meaningful. It may be problematic if we
// use the sourcelocation loaded from the visible modules.
VisibleModules.setVisible(Importing, ImportLoc);
if (isImportingModuleUnitFromSameModule(Ctx, Importing, CurrentModule,
FoundPrimaryModuleInterface))
FoundPrimaryModuleInterface)) {
for (Module *TransImported : Importing->Imports)
if (!VisibleModules.isVisible(TransImported))
Worklist.push_back(TransImported);
Worklist.push_back(TransImported);
for (auto [Exports, _] : Importing->Exports)
Worklist.push_back(Exports);
}
}
}

View File

@ -0,0 +1,26 @@
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
// RUN: %clang_cc1 -std=c++20 %t/P.cppm -emit-module-interface -o %t/M-P.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-module-interface -o %t/M.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/M.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
//--- A.cppm
export module A;
export using T = int;
//--- P.cppm
export module M:P;
import A;
//--- M.cppm
export module M;
export import :P;
//--- M.cpp
// expected-no-diagnostics
module M;
T x;