[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG3a3af2bbc97e: [C++20] [Module] fix bug 47716 and implement [module.interface]/p6 (authored by ChuanqiXu). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 Files: clang/include/clang/AST/DeclBase.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/AST/DeclBase.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/module/module.interface/p2-2.cpp clang/test/CXX/module/module.interface/p6.cpp Index: clang/test/CXX/module/module.interface/p6.cpp === --- /dev/null +++ clang/test/CXX/module/module.interface/p6.cpp @@ -0,0 +1,93 @@ +// The test is check we couldn't export a redeclaration which isn't exported previously and +// check it is OK to redeclare no matter exported nor not if is the previous declaration is exported. +// RUN: %clang_cc1 -std=c++20 %s -verify + +export module X; + +struct S { // expected-note {{previous declaration is here}} + int n; +}; +typedef S S; +export typedef S S; // OK, does not redeclare an entity +export struct S;// expected-error {{cannot export redeclaration 'S' here since the previous declaration is not exported}} + +namespace A { +struct X; // expected-note {{previous declaration is here}} +export struct Y; +} // namespace A + +namespace A { +export struct X; // expected-error {{cannot export redeclaration 'X' here since the previous declaration is not exported}} +export struct Y; // OK +struct Z;// expected-note {{previous declaration is here}} +export struct Z; // expected-error {{cannot export redeclaration 'Z' here since the previous declaration is not exported}} +} // namespace A + +namespace A { +struct B;// expected-note {{previous declaration is here}} +struct C {}; // expected-note {{previous declaration is here}} +} // namespace A + +namespace A { +export struct B {}; // expected-error {{cannot export redeclaration 'B' here since the previous declaration is not exported}} +export struct C;// expected-error {{cannot export redeclaration 'C' here since the previous declaration is not exported}} +} // namespace A + +template +struct TemplS; // expected-note {{previous declaration is here}} + +export template +struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration is not exported}} + +template +struct TemplS2; // expected-note {{previous declaration is here}} + +export template +struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration is not exported}} + +void baz();// expected-note {{previous declaration is here}} +export void baz(); // expected-error {{cannot export redeclaration 'baz' here since the previous declaration is not exported}} + +namespace A { +export void foo(); +void bar();// expected-note {{previous declaration is here}} +export void bar(); // expected-error {{cannot export redeclaration 'bar' here since the previous declaration is not exported}} +void f1(); // expected-note {{previous declaration is here}} +} // namespace A + +// OK +// +// [module.interface]/p6 +// A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration +void A::foo(); + +// The compiler couldn't export A::f1() here since A::f1() is declared above without exported. +// See [module.interface]/p6 for details. +export void A::f1(); // expected-error {{cannot export redeclaration 'f1' here since the previous declaration is not exported}} + +template +void TemplFunc(); // expected-note {{previous declaration is here}} + +export template +void TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration is not exported}} +} + +namespace A { +template +void TemplFunc2(); // expected-note {{previous declaration is here}} +export template +void TemplFunc2() {} // expected-error {{cannot export redeclaration 'TemplFunc2' here since the previous declaration is not exported}} +template +void TemplFunc3(); // expected-note {{previous declaration is here}} +} // namespace A + +export template +void A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration is not exported}} + +int var;// expected-note {{previous declaration is here}} +export int var; // expected-error {{cannot export redeclaration 'var' here since the previous declaration is not exported}} + +template +T TemplVar; // expected-note {{previous declaration is here}} +export template +T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration is not
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
urnathan accepted this revision. urnathan added a comment. This revision is now accepted and ready to land. LGTM, thanks for working on this CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu added a comment. @aaron.ballman @urnathan gentle ping~ CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu added a comment. @aaron.ballman @urnathan gentle ping~ CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu added a comment. @aaron.ballman @urnathan gentle ping~ CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu marked 5 inline comments as done. ChuanqiXu added inline comments. Comment at: clang/lib/Sema/SemaDecl.cpp:1622 +// [module.interface]p6: +// A redeclaration of an entity X is implicitly exported if X was introduced by aaron.ballman wrote: > I didn't address this since it belongs to C++20 instead of C++2b. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu updated this revision to Diff 395045. ChuanqiXu added a comment. Address comments CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 Files: clang/include/clang/AST/DeclBase.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/AST/DeclBase.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/module/module.interface/p2-2.cpp clang/test/CXX/module/module.interface/p6.cpp Index: clang/test/CXX/module/module.interface/p6.cpp === --- /dev/null +++ clang/test/CXX/module/module.interface/p6.cpp @@ -0,0 +1,93 @@ +// The test is check we couldn't export a redeclaration which isn't exported previously and +// check it is OK to redeclare no matter exported nor not if is the previous declaration is exported. +// RUN: %clang_cc1 -std=c++20 %s -verify + +export module X; + +struct S { // expected-note {{previous declaration is here}} + int n; +}; +typedef S S; +export typedef S S; // OK, does not redeclare an entity +export struct S;// expected-error {{cannot export redeclaration 'S' here since the previous declaration is not exported}} + +namespace A { +struct X; // expected-note {{previous declaration is here}} +export struct Y; +} // namespace A + +namespace A { +export struct X; // expected-error {{cannot export redeclaration 'X' here since the previous declaration is not exported}} +export struct Y; // OK +struct Z;// expected-note {{previous declaration is here}} +export struct Z; // expected-error {{cannot export redeclaration 'Z' here since the previous declaration is not exported}} +} // namespace A + +namespace A { +struct B;// expected-note {{previous declaration is here}} +struct C {}; // expected-note {{previous declaration is here}} +} // namespace A + +namespace A { +export struct B {}; // expected-error {{cannot export redeclaration 'B' here since the previous declaration is not exported}} +export struct C;// expected-error {{cannot export redeclaration 'C' here since the previous declaration is not exported}} +} // namespace A + +template +struct TemplS; // expected-note {{previous declaration is here}} + +export template +struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration is not exported}} + +template +struct TemplS2; // expected-note {{previous declaration is here}} + +export template +struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration is not exported}} + +void baz();// expected-note {{previous declaration is here}} +export void baz(); // expected-error {{cannot export redeclaration 'baz' here since the previous declaration is not exported}} + +namespace A { +export void foo(); +void bar();// expected-note {{previous declaration is here}} +export void bar(); // expected-error {{cannot export redeclaration 'bar' here since the previous declaration is not exported}} +void f1(); // expected-note {{previous declaration is here}} +} // namespace A + +// OK +// +// [module.interface]/p6 +// A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration +void A::foo(); + +// The compiler couldn't export A::f1() here since A::f1() is declared above without exported. +// See [module.interface]/p6 for details. +export void A::f1(); // expected-error {{cannot export redeclaration 'f1' here since the previous declaration is not exported}} + +template +void TemplFunc(); // expected-note {{previous declaration is here}} + +export template +void TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration is not exported}} +} + +namespace A { +template +void TemplFunc2(); // expected-note {{previous declaration is here}} +export template +void TemplFunc2() {} // expected-error {{cannot export redeclaration 'TemplFunc2' here since the previous declaration is not exported}} +template +void TemplFunc3(); // expected-note {{previous declaration is here}} +} // namespace A + +export template +void A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration is not exported}} + +int var;// expected-note {{previous declaration is here}} +export int var; // expected-error {{cannot export redeclaration 'var' here since the previous declaration is not exported}} + +template +T TemplVar; // expected-note {{previous declaration is here}} +export template +T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration is not exported}} Index: clang/test/CXX/module/module.interface/p2-2.cpp === --- /dev/null +++ clang/test/CXX/module/module.interface/p2-2.cpp @@
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
aaron.ballman added inline comments. Comment at: clang/include/clang/AST/DeclBase.h:616 + bool isInExportDeclContext() const; + I think it would be good to add some comments to document the function (as done with surrounding code). Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:7793-7794 "because namespace %1 does not enclose namespace %2">; +def err_export_non_namespace_scope_name : Error<"cannot export %0 as it is " + "not at namespace scope.">; +def err_redeclaration_non_exported : Error <"cannot export redeclaration %0 here " Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:7795-7796 + "not at namespace scope.">; +def err_redeclaration_non_exported : Error <"cannot export redeclaration %0 here " + "since the previous declaration is not exported.">; def err_invalid_declarator_global_scope : Error< Both of these tweak the formatting somewhat, but the important thing is dropping the trailing punctuation from the diagnostic text. Comment at: clang/lib/AST/DeclBase.cpp:999 +bool Decl::isInExportDeclContext() const { + auto *DC = getLexicalDeclContext(); + Comment at: clang/lib/Sema/SemaDecl.cpp:1622 +// [module.interface]p6: +// A redeclaration of an entity X is implicitly exported if X was introduced by Comment at: clang/lib/Sema/SemaDecl.cpp:1643-1645 +// A simple wrapper function to ease the call for +// CheckRedeclarationModuleOwnership and CheckRedeclarationExported and any +// other thing needed. Comment at: clang/lib/Sema/SemaDecl.cpp:5789 + if (!isa(DC)) +Diag(Loc, diag::err_export_non_namespace_scope_name) << Name; + else CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu added a comment. @rsmith @aaron.ballman @urnathan gentle ping~ CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu updated this revision to Diff 393030. ChuanqiXu added a comment. Rebased CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 Files: clang/include/clang/AST/DeclBase.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/AST/DeclBase.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/module/module.interface/p2-2.cpp clang/test/CXX/module/module.interface/p6.cpp Index: clang/test/CXX/module/module.interface/p6.cpp === --- /dev/null +++ clang/test/CXX/module/module.interface/p6.cpp @@ -0,0 +1,93 @@ +// The test is check we couldn't export a redeclaration which isn't exported previously and +// check it is OK to redeclare no matter exported nor not if is the previous declaration is exported. +// RUN: %clang_cc1 -std=c++20 %s -verify + +export module X; + +struct S { // expected-note {{previous declaration is here}} + int n; +}; +typedef S S; +export typedef S S; // OK, does not redeclare an entity +export struct S;// expected-error {{cannot export redeclaration 'S' here since the previous declaration is not exported.}} + +namespace A { +struct X; // expected-note {{previous declaration is here}} +export struct Y; +} // namespace A + +namespace A { +export struct X; // expected-error {{cannot export redeclaration 'X' here since the previous declaration is not exported.}} +export struct Y; // OK +struct Z;// expected-note {{previous declaration is here}} +export struct Z; // expected-error {{cannot export redeclaration 'Z' here since the previous declaration is not exported.}} +} // namespace A + +namespace A { +struct B;// expected-note {{previous declaration is here}} +struct C {}; // expected-note {{previous declaration is here}} +} // namespace A + +namespace A { +export struct B {}; // expected-error {{cannot export redeclaration 'B' here since the previous declaration is not exported.}} +export struct C;// expected-error {{cannot export redeclaration 'C' here since the previous declaration is not exported.}} +} // namespace A + +template +struct TemplS; // expected-note {{previous declaration is here}} + +export template +struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration is not exported.}} + +template +struct TemplS2; // expected-note {{previous declaration is here}} + +export template +struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration is not exported.}} + +void baz();// expected-note {{previous declaration is here}} +export void baz(); // expected-error {{cannot export redeclaration 'baz' here since the previous declaration is not exported.}} + +namespace A { +export void foo(); +void bar();// expected-note {{previous declaration is here}} +export void bar(); // expected-error {{cannot export redeclaration 'bar' here since the previous declaration is not exported.}} +void f1(); // expected-note {{previous declaration is here}} +} // namespace A + +// OK +// +// [module.interface]/p6 +// A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration +void A::foo(); + +// The compiler couldn't export A::f1() here since A::f1() is declared above without exported. +// See [module.interface]/p6 for details. +export void A::f1(); // expected-error {{cannot export redeclaration 'f1' here since the previous declaration is not exported.}} + +template +void TemplFunc(); // expected-note {{previous declaration is here}} + +export template +void TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration is not exported.}} +} + +namespace A { +template +void TemplFunc2(); // expected-note {{previous declaration is here}} +export template +void TemplFunc2() {} // expected-error {{cannot export redeclaration 'TemplFunc2' here since the previous declaration is not exported.}} +template +void TemplFunc3(); // expected-note {{previous declaration is here}} +} // namespace A + +export template +void A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration is not exported.}} + +int var;// expected-note {{previous declaration is here}} +export int var; // expected-error {{cannot export redeclaration 'var' here since the previous declaration is not exported.}} + +template +T TemplVar; // expected-note {{previous declaration is here}} +export template +T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration is not exported.}} Index: clang/test/CXX/module/module.interface/p2-2.cpp === --- /dev/null +++
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu added a comment. @aaron.ballman @urnathan gentle ping~ CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6
ChuanqiXu updated this revision to Diff 387144. ChuanqiXu added a comment. Fix a mismatch in test CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112903/new/ https://reviews.llvm.org/D112903 Files: clang/include/clang/AST/DeclBase.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/AST/DeclBase.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/module/module.interface/p2-2.cpp clang/test/CXX/module/module.interface/p6.cpp Index: clang/test/CXX/module/module.interface/p6.cpp === --- /dev/null +++ clang/test/CXX/module/module.interface/p6.cpp @@ -0,0 +1,93 @@ +// The test is check we couldn't export a redeclaration which isn't exported previously and +// check it is OK to redeclare no matter exported nor not if is the previous declaration is exported. +// RUN: %clang_cc1 -std=c++20 %s -verify + +export module X; + +struct S { // expected-note {{previous declaration is here}} + int n; +}; +typedef S S; +export typedef S S; // OK, does not redeclare an entity +export struct S;// expected-error {{cannot export redeclaration 'S' here since the previous declaration is not exported.}} + +namespace A { +struct X; // expected-note {{previous declaration is here}} +export struct Y; +} // namespace A + +namespace A { +export struct X; // expected-error {{cannot export redeclaration 'X' here since the previous declaration is not exported.}} +export struct Y; // OK +struct Z;// expected-note {{previous declaration is here}} +export struct Z; // expected-error {{cannot export redeclaration 'Z' here since the previous declaration is not exported.}} +} // namespace A + +namespace A { +struct B;// expected-note {{previous declaration is here}} +struct C {}; // expected-note {{previous declaration is here}} +} // namespace A + +namespace A { +export struct B {}; // expected-error {{cannot export redeclaration 'B' here since the previous declaration is not exported.}} +export struct C;// expected-error {{cannot export redeclaration 'C' here since the previous declaration is not exported.}} +} // namespace A + +template +struct TemplS; // expected-note {{previous declaration is here}} + +export template +struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration is not exported.}} + +template +struct TemplS2; // expected-note {{previous declaration is here}} + +export template +struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration is not exported.}} + +void baz();// expected-note {{previous declaration is here}} +export void baz(); // expected-error {{cannot export redeclaration 'baz' here since the previous declaration is not exported.}} + +namespace A { +export void foo(); +void bar();// expected-note {{previous declaration is here}} +export void bar(); // expected-error {{cannot export redeclaration 'bar' here since the previous declaration is not exported.}} +void f1(); // expected-note {{previous declaration is here}} +} // namespace A + +// OK +// +// [module.interface]/p6 +// A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration +void A::foo(); + +// The compiler couldn't export A::f1() here since A::f1() is declared above without exported. +// See [module.interface]/p6 for details. +export void A::f1(); // expected-error {{cannot export redeclaration 'f1' here since the previous declaration is not exported.}} + +template +void TemplFunc(); // expected-note {{previous declaration is here}} + +export template +void TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration is not exported.}} +} + +namespace A { +template +void TemplFunc2(); // expected-note {{previous declaration is here}} +export template +void TemplFunc2() {} // expected-error {{cannot export redeclaration 'TemplFunc2' here since the previous declaration is not exported.}} +template +void TemplFunc3(); // expected-note {{previous declaration is here}} +} // namespace A + +export template +void A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration is not exported.}} + +int var;// expected-note {{previous declaration is here}} +export int var; // expected-error {{cannot export redeclaration 'var' here since the previous declaration is not exported.}} + +template +T TemplVar; // expected-note {{previous declaration is here}} +export template +T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration is not exported.}} Index: clang/test/CXX/module/module.interface/p2-2.cpp === --- /dev/null +++