diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11167,6 +11167,17 @@ "%select{declaration|definition|default argument|" "explicit specialization|partial specialization}0 of %1 must be imported " "from module '%2' before it is required">; +def err_module_private_use : Error< + "%select{declaration|definition|default argument|" + "explicit specialization|partial specialization}0 of %1 is private to module " + "'%2'">; +def err_module_internal_use : Error< + "%select{declaration|definition|default argument|" + "explicit specialization|partial specialization}0 of %1 is internal to " + "'%2'">; +def note_suggest_export : Note< + "export the %select{declaration|definition|default argument|" + "explicit specialization|partial specialization}0 to make it available">; def err_module_unimported_use_header : Error< "%select{missing '#include'|missing '#include %3'}2; " "%select{||default argument of |explicit specialization of |" diff --git a/clang/include/clang/Sema/Lookup.h b/clang/include/clang/Sema/Lookup.h --- a/clang/include/clang/Sema/Lookup.h +++ b/clang/include/clang/Sema/Lookup.h @@ -346,7 +346,7 @@ /// Determine whether the given declaration is visible to the /// program. - static bool isVisible(Sema &SemaRef, NamedDecl *D); + static bool isVisible(Sema &SemaRef, NamedDecl *D, bool ForTypo = false); static bool isReachable(Sema &SemaRef, NamedDecl *D); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3141,12 +3141,16 @@ SourceLocation SemiLoc); enum class ModuleDeclKind { + NoModule, ///< No named module line seen so far. Interface, ///< 'export module X;' Implementation, ///< 'module X;' PartitionInterface, ///< 'export module X:Y;' PartitionImplementation, ///< 'module X:Y;' }; + /// Identify the module kind to disambiguate implementation units. + ModuleDeclKind TheModuleKind = ModuleDeclKind::NoModule; + /// An enumeration to represent the transition of states in parsing module /// fragments and imports. If we are not parsing a C++20 TU, or we find /// an error in state transition, the state is set to NotACXX20Module. diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1780,7 +1780,7 @@ Module *DeclModule = SemaRef.getOwningModule(D); assert(DeclModule && "hidden decl has no owning module"); - // If the owning module is visible, the decl is acceptable. + // If the owning module is visible, the decl is potentially acceptable. if (SemaRef.isModuleVisible(DeclModule, D->isInvisibleOutsideTheOwningModule())) return true; @@ -2065,14 +2065,27 @@ return findAcceptableDecl(getSema(), D, IDNS); } -bool LookupResult::isVisible(Sema &SemaRef, NamedDecl *D) { +bool LookupResult::isVisible(Sema &SemaRef, NamedDecl *D, bool ForTypo) { // If this declaration is already visible, return it directly. if (D->isUnconditionallyVisible()) return true; // During template instantiation, we can refer to hidden declarations, if // they were visible in any module along the path of instantiation. - return isAcceptableSlow(SemaRef, D, Sema::AcceptableKind::Visible); + if (!isAcceptableSlow(SemaRef, D, Sema::AcceptableKind::Visible)) + return false; + + if (ForTypo && SemaRef.getLangOpts().CPlusPlusModules && D->isFromASTFile()) { + // There is no point in offering a typo correction to an item that we will + // reject because it has internal linkage and is in a different module TU; + Module *DeclModule = SemaRef.getOwningModule(D); + if (DeclModule && !DeclModule->isModuleMapModule() && + !SemaRef.isModuleUnitOfCurrentTU(DeclModule) && + (D->getFormalLinkage() == Linkage::InternalLinkage || + DeclModule->isPrivateModule())) + return false; // This is not usefully visible. + } + return true; } bool LookupResult::isReachable(Sema &SemaRef, NamedDecl *D) { @@ -2084,8 +2097,22 @@ bool LookupResult::isAvailableForLookup(Sema &SemaRef, NamedDecl *ND) { // We should check the visibility at the callsite already. - if (isVisible(SemaRef, ND)) + if (isVisible(SemaRef, ND)) { + if (SemaRef.getLangOpts().CPlusPlusModules && ND->isFromASTFile()) { + // The module that owns the decl is visible; However + // [basic.lookup.general]/2, specifically 2.3 + // If the owning module is part of a different TU than the current one, + // and declaration is internal (or from the PMF), then we should not + // include it. + Module *DeclModule = SemaRef.getOwningModule(ND); + if (DeclModule && !DeclModule->isModuleMapModule() && + !SemaRef.isModuleUnitOfCurrentTU(DeclModule) && + (ND->getFormalLinkage() == Linkage::InternalLinkage || + DeclModule->isPrivateModule())) + return false; + } return true; + } // Deduction guide lives in namespace scope generally, but it is just a // hint to the compilers. What we actually lookup for is the generated member @@ -4463,9 +4490,13 @@ static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) { TypoCorrection::decl_iterator DI = TC.begin(), DE = TC.end(); - for (/**/; DI != DE; ++DI) - if (!LookupResult::isVisible(SemaRef, *DI)) + // During the lookups for Typo corrections, we allow 'hidden' decls to be + // found, this can also include (potential typo correction) decls that are + // not in their own right viable. Filter these from the visible set. + for (/**/; DI != DE; ++DI) { + if (!LookupResult::isVisible(SemaRef, *DI, /*ForTypo*/ true)) break; + } // No filtering needed if all decls are visible. if (DI == DE) { TC.setRequiresImport(false); @@ -4476,15 +4507,25 @@ bool AnyVisibleDecls = !NewDecls.empty(); for (/**/; DI != DE; ++DI) { - if (LookupResult::isVisible(SemaRef, *DI)) { + if (LookupResult::isVisible(SemaRef, *DI, /*ForTypo*/ true)) { if (!AnyVisibleDecls) { // Found a visible decl, discard all hidden ones. AnyVisibleDecls = true; NewDecls.clear(); } NewDecls.push_back(*DI); - } else if (!AnyVisibleDecls && !(*DI)->isModulePrivate()) - NewDecls.push_back(*DI); + } else if (!AnyVisibleDecls) { + // We do not want to push a hidden decl if it is not usefully reported + // as a typo (which means the proposed replacement has to be viable). + NamedDecl *ND = *DI; + if (SemaRef.getLangOpts().CPlusPlusModules && ND->isFromASTFile() && + ND->getOwningModule() && + !SemaRef.isModuleUnitOfCurrentTU(ND->getOwningModule()) && + ND->getFormalLinkage() == Linkage::InternalLinkage) + continue; // Internal symbol from a different TU, not visible. + if (!ND->isModulePrivate()) + NewDecls.push_back(ND); + } } if (NewDecls.empty()) @@ -4552,7 +4593,7 @@ // Only consider visible declarations and declarations from modules with // names that exactly match. - if (!LookupResult::isVisible(SemaRef, ND) && Name != Typo) + if (!LookupResult::isVisible(SemaRef, ND, /*ForTypo*/ true) && Name != Typo) return; FoundName(Name->getName()); @@ -5735,6 +5776,7 @@ Modules = UniqueModules; + bool DidFixit = false; if (Modules.size() > 1) { std::string ModuleList; unsigned N = 0; @@ -5749,13 +5791,26 @@ Diag(UseLoc, diag::err_module_unimported_use_multiple) << (int)MIK << Decl << ModuleList; + } else if (Decl->hasLinkage() && + Decl->getFormalLinkage() == Linkage::ModuleLinkage) { + Diag(UseLoc, diag::err_module_private_use) + << (int)MIK << Decl << Modules[0]->getFullModuleName(); + Diag(Decl->getBeginLoc(), diag::note_suggest_export) + << (int)MIK + << FixItHint::CreateInsertion(Decl->getBeginLoc(), "export"); + DidFixit = true; + } else if (Decl->hasLinkage() && + Decl->getFormalLinkage() == Linkage::InternalLinkage) { + Diag(UseLoc, diag::err_module_internal_use) + << (int)MIK << Decl << Modules[0]->getFullModuleName(); } else { // FIXME: Add a FixItHint that imports the corresponding module. Diag(UseLoc, diag::err_module_unimported_use) << (int)MIK << Decl << Modules[0]->getFullModuleName(); } - NotePrevious(); + if (!DidFixit) + NotePrevious(); // Try to recover by implicitly importing this module. if (Recover) diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -301,6 +301,8 @@ Module *Mod; switch (MDK) { + case ModuleDeclKind::NoModule: + llvm_unreachable("we should be building some kind of module"); case ModuleDeclKind::Interface: case ModuleDeclKind::PartitionInterface: { // We can't have parsed or imported a definition of this module or parsed a @@ -385,6 +387,7 @@ // We are in the module purview, but before any other (non import) // statements, so imports are allowed. ImportState = ModuleImportState::ImportAllowed; + TheModuleKind = MDK; // Save this information to help decl TU queries. // For an implementation, We already made an implicit import (its interface). // Make and return the import decl to be added to the current TU. @@ -1014,10 +1017,42 @@ Module *CurrentModuleUnit = getCurrentModule(); - // If we are not in a module currently, M must not be the module unit of + // If we are not in a module currently, M cannot be a module unit of the // current TU. if (!CurrentModuleUnit) return false; + // We only create the special GlobalModuleFragments for the current TU; GMF + // fragments of imported modules are part of those imports. These are the + // only sub-modules (potentially) present for a non-partition module + // implementation TU. + if (M == TheGlobalModuleFragment || M == TheImplicitGlobalModuleFragment || + M == TheExportedImplicitGlobalModuleFragment) + return true; + + // If we are in the GMF and the match above failed, the query is for some + // other TU. + if (CurrentModuleUnit == TheGlobalModuleFragment) + return false; + + // If we are in a non-partition module implementation TU, then we are done; + // the only possible cases are considered above. + if (TheModuleKind == ModuleDeclKind::Implementation) + return false; + + // Now we've checked for the implementation case, we could have a query for + // a decl earlier in the current module purview. + if (M == CurrentModuleUnit) + return true; + + // If we are (temporarily) in one of the special Global Module fragments that + // handle language linkage cases, then the only relevant case is that the + // parent equals the queried module. + if (CurrentModuleUnit == TheImplicitGlobalModuleFragment || + CurrentModuleUnit == TheExportedImplicitGlobalModuleFragment) { + return CurrentModuleUnit->Parent == M; + } + + // FIXME: probably, it is sufficient to check for the PMF here. return M->isSubModuleOf(CurrentModuleUnit->getTopLevelModule()); } diff --git a/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp b/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp --- a/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp +++ b/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp @@ -62,27 +62,15 @@ not_exported = 1; #ifndef IMPLEMENTATION - // expected-error@-2 {{declaration of 'not_exported' must be imported from module 'A' before it is required}} - // expected-note@p2.cpp:19 {{declaration here is not visible}} + // expected-error@-2 {{declaration of 'not_exported' is private to module 'A'}} + // expected-note@p2.cpp:19 {{export the declaration to make it available}} #endif - internal = 1; -#ifndef IMPLEMENTATION - // expected-error@-2 {{declaration of 'internal' must be imported from module 'A' before it is required}} - // expected-note@p2.cpp:20 {{declaration here is not visible}} -#endif + internal = 1; // expected-error {{use of undeclared identifier 'internal'}} - not_exported_private = 1; -#ifndef IMPLEMENTATION - // FIXME: should not be visible here - // expected-error@-3 {{undeclared identifier}} -#endif + not_exported_private = 1; // expected-error {{use of undeclared identifier 'not_exported_private'}} - internal_private = 1; -#ifndef IMPLEMENTATION - // FIXME: should not be visible here - // expected-error@-3 {{undeclared identifier}} -#endif + internal_private = 1; // expected-error {{undeclared identifier 'internal_private'}} } #endif diff --git a/clang/test/CXX/module/basic/basic.def.odr/p4.cppm b/clang/test/CXX/module/basic/basic.def.odr/p4.cppm --- a/clang/test/CXX/module/basic/basic.def.odr/p4.cppm +++ b/clang/test/CXX/module/basic/basic.def.odr/p4.cppm @@ -5,9 +5,9 @@ // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %t/Module.cppm --implicit-check-not unused // // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple -emit-module-interface -o %t/Module.pcm -// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple -fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp --implicit-check-not=unused --implicit-check-not=global_module +// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple -fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp --implicit-check-not=unused --implicit-check-not=global_module // -// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple -fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp --implicit-check-not=unused --implicit-check-not=global_module +// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple -fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp --implicit-check-not=unused --implicit-check-not=global_module //--- Module.cppm // CHECK-DAG: @extern_var_global_module = external {{(dso_local )?}}global @@ -128,8 +128,6 @@ // // CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local )?}}global // CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr {{(dso_local )?}}global -// CHECK-DAG: @_ZL25static_var_module_linkage = internal {{(dso_local )?}}global i32 0, -// CHECK-DAG: @_ZL24const_var_module_linkage = internal {{(dso_local )?}}constant i32 3, module Module; @@ -143,9 +141,6 @@ (void)&inline_var_exported; (void)&const_var_exported; - // CHECK: define {{.*}}@_ZL26used_static_module_linkagev - used_static_module_linkage(); - // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev used_inline_module_linkage(); @@ -154,8 +149,7 @@ (void)&extern_var_module_linkage; (void)&inline_var_module_linkage; - (void)&static_var_module_linkage; // FIXME: Should not be visible here. - (void)&const_var_module_linkage; + // Internal linkage declarations are not visible here. } //--- user.cpp @@ -176,5 +170,6 @@ (void)&inline_var_exported; (void)&const_var_exported; + // Internal linkage declarations are not visible here. // Module-linkage declarations are not visible here. } diff --git a/clang/test/CXX/module/basic/basic.link/p2.cppm b/clang/test/CXX/module/basic/basic.link/p2.cppm --- a/clang/test/CXX/module/basic/basic.link/p2.cppm +++ b/clang/test/CXX/module/basic/basic.link/p2.cppm @@ -39,20 +39,19 @@ } //--- M.cpp -// expected-no-diagnostics module M; -// FIXME: Use of internal linkage entities should be rejected. void use_from_module_impl() { external_linkage_fn(); module_linkage_fn(); - internal_linkage_fn(); + internal_linkage_fn(); // expected-error {{use of undeclared identifier 'internal_linkage_fn'; did you mean 'external_linkage_fn'}} + // expected-note@M.cppm:8 {{'external_linkage_fn' declared here}} (void)external_linkage_class{}; (void)module_linkage_class{}; - (void)internal_linkage_class{}; + (void)internal_linkage_class; // expected-error {{use of undeclared identifier 'internal_linkage_class'}} (void)external_linkage_var; (void)module_linkage_var; - (void)internal_linkage_var; + (void)internal_linkage_var; // expected-error {{use of undeclared identifier 'internal_linkage_var'}} } //--- user.cpp @@ -60,13 +59,13 @@ void use_from_module_impl() { external_linkage_fn(); - module_linkage_fn(); // expected-error {{declaration of 'module_linkage_fn' must be imported}} - internal_linkage_fn(); // expected-error {{declaration of 'internal_linkage_fn' must be imported}} + module_linkage_fn(); // expected-error {{declaration of 'module_linkage_fn' is private to module 'M'}} + // expected-note@M.cppm:9 {{export the declaration to make it available}} + internal_linkage_fn(); // expected-error {{use of undeclared identifier 'internal_linkage_fn'; did you mean 'external_linkage_fn'}} (void)external_linkage_class{}; (void)module_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}} (void)internal_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}} - // expected-note@M.cppm:9 {{declaration here is not visible}} - // expected-note@M.cppm:10 {{declaration here is not visible}} + // expected-note@M.cppm:8 {{'external_linkage_fn' declared here}} (void)external_linkage_var; (void)module_linkage_var; // expected-error {{undeclared identifier}} (void)internal_linkage_var; // expected-error {{undeclared identifier}} diff --git a/clang/test/CXX/module/module.import/p2.cpp b/clang/test/CXX/module/module.import/p2.cpp --- a/clang/test/CXX/module/module.import/p2.cpp +++ b/clang/test/CXX/module/module.import/p2.cpp @@ -23,10 +23,10 @@ //--- Use.cpp import M; void test() { - A a; // expected-error {{declaration of 'A' must be imported from module 'M:impl'}} - // expected-error@-1 {{definition of 'A' must be imported from module 'M:impl'}} expected-error@-1 {{}} - // expected-note@impl.cppm:2 {{declaration here is not visible}} - // expected-note@impl.cppm:2 {{definition here is not reachable}} expected-note@impl.cppm:2 {{}} + A a; // expected-error {{declaration of 'A' is private to module 'M:impl'}} + // expected-note@impl.cppm:2 {{export the declaration to make it available}} + // expected-error@-2 1+{{definition of 'A' is private to module 'M:impl'}} + // expected-note@impl.cppm:2 1+{{export the definition to make it available}} } //--- UseInPartA.cppm @@ -41,10 +41,10 @@ export module B; import M; void test() { - A a; // expected-error {{declaration of 'A' must be imported from module 'M:impl'}} - // expected-error@-1 {{definition of 'A' must be imported from module 'M:impl'}} expected-error@-1 {{}} - // expected-note@impl.cppm:2 {{declaration here is not visible}} - // expected-note@impl.cppm:2 {{definition here is not reachable}} expected-note@impl.cppm:2 {{}} + A a; // expected-error {{declaration of 'A' is private to module 'M:impl'}} + // expected-note@impl.cppm:2 {{export the declaration to make it available}} + // expected-error@-2 1+{{definition of 'A' is private to module 'M:impl'}} + // expected-note@impl.cppm:2 1+{{export the definition to make it available}} } //--- Private.cppm diff --git a/clang/test/CXX/module/module.interface/p2.cpp b/clang/test/CXX/module/module.interface/p2.cpp --- a/clang/test/CXX/module/module.interface/p2.cpp +++ b/clang/test/CXX/module/module.interface/p2.cpp @@ -69,29 +69,29 @@ void use() { // namespace A is implicitly exported by the export of A::g. - A::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}} - // expected-note@* {{declaration here is not visible}} + A::f(); // expected-error {{declaration of 'f' is private to module 'p2'}} + // expected-note@* {{export the declaration to make it available}} A::g(); - A::h(); // expected-error {{declaration of 'h' must be imported from module 'p2' before it is required}} - // expected-note@* {{declaration here is not visible}} + A::h(); // expected-error {{declaration of 'h' is private to module 'p2'}} + // expected-note@* {{export the declaration to make it available}} using namespace A::inner; // expected-error {{declaration of 'inner' must be imported from module 'p2' before it is required}} // expected-note@* {{declaration here is not visible}} // namespace B and B::inner are explicitly exported using namespace B; using namespace B::inner; - B::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}} - // expected-note@* {{declaration here is not visible}} - f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}} - // expected-note@* {{declaration here is not visible}} + B::f(); // expected-error {{declaration of 'f' is private to module 'p2'}} + // expected-note@* {{export the declaration to make it available}} + f(); // expected-error {{declaration of 'f' is private to module 'p2'}} + // expected-note@* {{export the declaration to make it available}} // namespace C is not exported using namespace C; // expected-error {{declaration of 'C' must be imported from module 'p2' before it is required}} // expected-note@* {{declaration here is not visible}} // namespace D is exported, but D::f is not - D::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}} - // expected-note@* {{declaration here is not visible}} + D::f(); // expected-error {{declaration of 'f' is private to module 'p2'}} + // expected-note@* {{export the declaration to make it available}} } int use_header() { return foo + bar::baz(); } diff --git a/clang/test/CXX/module/module.interface/p7.cpp b/clang/test/CXX/module/module.interface/p7.cpp --- a/clang/test/CXX/module/module.interface/p7.cpp +++ b/clang/test/CXX/module/module.interface/p7.cpp @@ -57,12 +57,12 @@ void test2() { auto a = E1::e1; // OK, namespace-scope name E1 is visible and e1 is reachable auto b = e1; // OK, namespace-scope name e1 is visible - auto c = E2::e2; // expected-error {{declaration of 'E2' must be imported from module}} - // expected-note@* {{declaration here is not visible}} + auto c = E2::e2; // expected-error {{declaration of 'E2' is private to module 'p7'}} + // expected-note@* {{export the declaration to make it available}} auto d = e2; // should be error, namespace-scope name e2 is not visible auto e = E2U::e2; // OK, namespace-scope name E2U is visible and E2::e2 is reachable - auto f = E3::e3; // expected-error {{declaration of 'E3' must be imported from module 'p7' before it is required}} - // expected-note@* {{declaration here is not visible}} + auto f = E3::e3; // expected-error {{declaration of 'E3' is private to module 'p7'}} + // expected-note@* {{export the declaration to make it available}} auto g = e3; // should be error, namespace-scope name e3 is not visible auto h = decltype(func())::e3; // OK, namespace-scope name f is visible and E3::e3 is reachable } diff --git a/clang/test/CXX/module/module.reach/ex1.cpp b/clang/test/CXX/module/module.reach/ex1.cpp --- a/clang/test/CXX/module/module.reach/ex1.cpp +++ b/clang/test/CXX/module/module.reach/ex1.cpp @@ -37,10 +37,10 @@ //--- X.cppm export module X; import M; -B b3; // expected-error {{definition of 'B' must be imported from module 'M:B' before it is required}} expected-error {{}} - // expected-note@* {{definition here is not reachable}} expected-note@* {{}} -// FIXME: We should emit an error for unreachable definition of B. +B b3; // expected-error {{definition of 'B' is private to module 'M:B'}} expected-error {{}} + // expected-note@* {{export the definition to make it available}} expected-note@* {{}} + void g() { f(); } -void g1() { f(B()); } // expected-error 1+{{definition of 'B' must be imported from module 'M:B' before it is required}} - // expected-note@* 1+{{definition here is not reachable}} +void g1() { f(B()); } // expected-error 1+{{definition of 'B' is private to module 'M:B'}} + // expected-note@* 1+{{export the definition to make it available}} // expected-note@M.cppm:5 {{passing argument to parameter 'b' here}} diff --git a/clang/test/CXX/module/module.reach/p2.cpp b/clang/test/CXX/module/module.reach/p2.cpp --- a/clang/test/CXX/module/module.reach/p2.cpp +++ b/clang/test/CXX/module/module.reach/p2.cpp @@ -17,6 +17,6 @@ //--- UseStrict.cpp import M; void test() { - auto a = f(); // expected-error {{definition of 'A' must be imported from module 'M:impl' before it is required}} expected-error{{}} - // expected-note@* {{definition here is not reachable}} expected-note@* {{}} + auto a = f(); // expected-error 1+{{definition of 'A' is private to module 'M:impl'}} + // expected-note@* 1+{{export the definition to make it available}} } diff --git a/clang/test/CXX/module/module.reach/p5.cpp b/clang/test/CXX/module/module.reach/p5.cpp --- a/clang/test/CXX/module/module.reach/p5.cpp +++ b/clang/test/CXX/module/module.reach/p5.cpp @@ -14,5 +14,5 @@ export module B; import A; Y y; // OK, definition of X is reachable -X x; // expected-error {{declaration of 'X' must be imported from module 'A' before it is required}} - // expected-note@* {{declaration here is not visible}} +X x; // expected-error {{declaration of 'X' is private to module 'A'}} + // expected-note@* {{export the declaration to make it available}} diff --git a/clang/test/Modules/Reachability-template-default-arg.cpp b/clang/test/Modules/Reachability-template-default-arg.cpp --- a/clang/test/Modules/Reachability-template-default-arg.cpp +++ b/clang/test/Modules/Reachability-template-default-arg.cpp @@ -18,6 +18,6 @@ import template_default_arg; void bar() { A<> a0; - A a1; // expected-error {{declaration of 't' must be imported from module 'template_default_arg' before it is required}} - // expected-note@* {{declaration here is not visible}} + A a1; // expected-error {{declaration of 't' is private to module 'template_default_arg'}} + // expected-note@* {{export the declaration to make it available}} } diff --git a/clang/test/Modules/cxx20-10-1-ex2.cpp b/clang/test/Modules/cxx20-10-1-ex2.cpp --- a/clang/test/Modules/cxx20-10-1-ex2.cpp +++ b/clang/test/Modules/cxx20-10-1-ex2.cpp @@ -53,8 +53,8 @@ //--- std10-1-ex2-tu6.cpp import B; // error, n is module-local and this is not a module. -int &c = n; // expected-error {{declaration of 'n' must be imported}} - // expected-note@* {{declaration here is not visible}} +int &c = n; // expected-error {{declaration of 'n' is private to module 'B'}} + // expected-note@* {{export the declaration to make it available}} //--- std10-1-ex2-tu7.cpp // expected-no-diagnostics diff --git a/clang/test/Modules/deduction-guide3.cppm b/clang/test/Modules/deduction-guide3.cppm --- a/clang/test/Modules/deduction-guide3.cppm +++ b/clang/test/Modules/deduction-guide3.cppm @@ -19,8 +19,8 @@ //--- Use.cpp import Templ; void func() { - Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}} + Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}} // expected-error@-1 {{unknown type name 'Templ'}} - // expected-note@Templ.cppm:3 {{declaration here is not visible}} + // expected-note@Templ.cppm:3 {{export the declaration to make it available}} } diff --git a/clang/test/Modules/diagnose-missing-import.m b/clang/test/Modules/diagnose-missing-import.m --- a/clang/test/Modules/diagnose-missing-import.m +++ b/clang/test/Modules/diagnose-missing-import.m @@ -6,9 +6,9 @@ void foo(void) { XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \ - expected-error {{declaration of 'XYZLogEvent' must be imported}} \ - expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \ - expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} + expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \ + expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \ + expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} } // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}