iains created this revision. iains updated this revision to Diff 405601. iains added a comment. iains updated this revision to Diff 408766. iains updated this revision to Diff 408866. iains added reviewers: rsmith, urnathan, ChuanqiXu. iains updated this revision to Diff 408892. iains published this revision for review. Herald added a project: clang. Herald added a subscriber: cfe-commits.
rebased onto import state machine iains added a comment. Rebased onto other modules work. iains added a comment. update formatting. iains added a comment. re-push format changes iains added a comment. patch 8 of 8 implementing basic C++20 module partition support. Implementation partitions bring two extra cases where we have visibility of module-private data. 1. When we import a module implementation partition. 2. When a partition implementation imports the primary module intertace. We maintain a record of direct imports into the current module since partition decls from direct imports (but not trasitive ones) are visible. The rules on decl-reachability are much more relaxed (with the standard giving permission for an implementation to load dependent modules and for the decls there to be reachable, but not visible). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D118599 Files: clang/lib/Sema/SemaLookup.cpp clang/test/Modules/cxx20-10-1-ex2.cpp Index: clang/test/Modules/cxx20-10-1-ex2.cpp =================================================================== --- clang/test/Modules/cxx20-10-1-ex2.cpp +++ clang/test/Modules/cxx20-10-1-ex2.cpp @@ -11,9 +11,8 @@ // RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=3 -x c++ %s \ // RUN: -o %t/B_X1.pcm -verify -// Not expected to work yet. -// %clang_cc1 -std=c++20 -emit-module-interface -D TU=4 -x c++ %s \ -// -fmodule-file=%t/B.pcm -o %t/B_X2.pcm +// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=4 -x c++ %s \ +// RUN: -fmodule-file=%t/B.pcm -o %t/B_X2.pcm // RUN: %clang_cc1 -std=c++20 -emit-obj -D TU=5 -x c++ %s \ // RUN: -fmodule-file=%t/B.pcm -o %t/b_tu5.s @@ -21,9 +20,8 @@ // RUN: %clang_cc1 -std=c++20 -S -D TU=6 -x c++ %s \ // RUN: -fmodule-file=%t/B.pcm -o %t/b_tu6.s -verify -// Not expected to work yet. -// %clang_cc1 -std=c++20 -emit-module-interface -D TU=7 -x c++ %s \ -// -fmodule-file=%t/B_X2.pcm -o %t/B_X3.pcm -verify +// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=7 -x c++ %s \ +// RUN: -fmodule-file=%t/B_X2.pcm -o %t/B_X3.pcm -verify #if TU == 1 module B:Y; Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -1686,8 +1686,8 @@ Module *DeclModule = SemaRef.getOwningModule(D); assert(DeclModule && "hidden decl has no owning module"); - // If the owning module is visible, the decl is visible. if (SemaRef.isModuleVisible(DeclModule, D->isModulePrivate())) + // If the owning module is visible, the decl is visible. return true; // Determine whether a decl context is a file context for the purpose of @@ -1761,6 +1761,22 @@ if (ModulePrivate) { if (isInCurrentModule(M, getLangOpts())) return true; + else if (M->Kind == Module::ModuleKind::ModulePartitionImplementation && + isModuleDirectlyImported(M)) + // Unless a partition implementation is directly imported it is not + // counted as visible for lookup, although the contained decls might + // still be reachable. It's a partition, so it must be part of the + // current module to be a valid import. + return true; + else if (getLangOpts().CPlusPlusModules && !ModuleScopes.empty() && + ModuleScopes[0].Module->Kind == + Module::ModuleKind::ModulePartitionImplementation && + ModuleScopes[0].Module->getPrimaryModuleInterfaceName() == + M->Name && + isModuleDirectlyImported(M)) + // We are building a module implementation partition and the TU imports + // the primary module interface unit. + return true; } else { if (VisibleModules.isVisible(M)) return true;
Index: clang/test/Modules/cxx20-10-1-ex2.cpp =================================================================== --- clang/test/Modules/cxx20-10-1-ex2.cpp +++ clang/test/Modules/cxx20-10-1-ex2.cpp @@ -11,9 +11,8 @@ // RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=3 -x c++ %s \ // RUN: -o %t/B_X1.pcm -verify -// Not expected to work yet. -// %clang_cc1 -std=c++20 -emit-module-interface -D TU=4 -x c++ %s \ -// -fmodule-file=%t/B.pcm -o %t/B_X2.pcm +// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=4 -x c++ %s \ +// RUN: -fmodule-file=%t/B.pcm -o %t/B_X2.pcm // RUN: %clang_cc1 -std=c++20 -emit-obj -D TU=5 -x c++ %s \ // RUN: -fmodule-file=%t/B.pcm -o %t/b_tu5.s @@ -21,9 +20,8 @@ // RUN: %clang_cc1 -std=c++20 -S -D TU=6 -x c++ %s \ // RUN: -fmodule-file=%t/B.pcm -o %t/b_tu6.s -verify -// Not expected to work yet. -// %clang_cc1 -std=c++20 -emit-module-interface -D TU=7 -x c++ %s \ -// -fmodule-file=%t/B_X2.pcm -o %t/B_X3.pcm -verify +// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=7 -x c++ %s \ +// RUN: -fmodule-file=%t/B_X2.pcm -o %t/B_X3.pcm -verify #if TU == 1 module B:Y; Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -1686,8 +1686,8 @@ Module *DeclModule = SemaRef.getOwningModule(D); assert(DeclModule && "hidden decl has no owning module"); - // If the owning module is visible, the decl is visible. if (SemaRef.isModuleVisible(DeclModule, D->isModulePrivate())) + // If the owning module is visible, the decl is visible. return true; // Determine whether a decl context is a file context for the purpose of @@ -1761,6 +1761,22 @@ if (ModulePrivate) { if (isInCurrentModule(M, getLangOpts())) return true; + else if (M->Kind == Module::ModuleKind::ModulePartitionImplementation && + isModuleDirectlyImported(M)) + // Unless a partition implementation is directly imported it is not + // counted as visible for lookup, although the contained decls might + // still be reachable. It's a partition, so it must be part of the + // current module to be a valid import. + return true; + else if (getLangOpts().CPlusPlusModules && !ModuleScopes.empty() && + ModuleScopes[0].Module->Kind == + Module::ModuleKind::ModulePartitionImplementation && + ModuleScopes[0].Module->getPrimaryModuleInterfaceName() == + M->Name && + isModuleDirectlyImported(M)) + // We are building a module implementation partition and the TU imports + // the primary module interface unit. + return true; } else { if (VisibleModules.isVisible(M)) return true;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits