[PATCH] D112903: [C++20] [Module] Fix bug47116 and implement [module.interface]/p6

2022-01-23 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2022-01-21 Thread Nathan Sidwell via Phabricator via cfe-commits
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

2022-01-19 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2022-01-11 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2022-01-03 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2021-12-16 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2021-12-16 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2021-12-16 Thread Aaron Ballman via Phabricator via cfe-commits
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

2021-12-13 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2021-12-08 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2021-11-18 Thread Chuanqi Xu via Phabricator via cfe-commits
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

2021-11-14 Thread Chuanqi Xu via Phabricator via cfe-commits
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
+++