[c++2a] Add semantic support for private module fragments.

llvm-svn: 358713
diff --git a/clang/test/CXX/basic/basic.link/p1.cpp b/clang/test/CXX/basic/basic.link/p1.cpp
index b94e570..c6a119a 100644
--- a/clang/test/CXX/basic/basic.link/p1.cpp
+++ b/clang/test/CXX/basic/basic.link/p1.cpp
@@ -1,24 +1,31 @@
 // RUN: %clang_cc1 -std=c++2a -verify %s
 // RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG %s
 // RUN: %clang_cc1 -std=c++2a -verify -DNO_MODULE_DECL %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_MODULE_DECL -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_MODULE_DECL %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_MODULE_DECL -DNO_PRIVATE_FRAG %s
 // RUN: %clang_cc1 -std=c++2a -verify -DEXPORT_FRAGS %s
 
-#ifdef NO_GLOBAL_FRAG
-// expected-error@#mod-decl {{module declaration must occur at the start of the translation unit}}
-// expected-note@1 {{add 'module;' to the start of the file to introduce a global module fragment}}
-#else
+#ifndef NO_GLOBAL_FRAG
 #ifdef EXPORT_FRAGS
 export // expected-error {{global module fragment cannot be exported}}
 #endif
-module; // #glob-frag
+module;
+#ifdef NO_MODULE_DECL
+// expected-error@-2 {{missing 'module' declaration at end of global module fragment introduced here}}
+#endif
 #endif
 
 extern int a; // #a1
 
-#ifdef NO_MODULE_DECL
-// expected-error@#glob-frag {{missing 'module' declaration at end of global module fragment introduced here}}
-#else
-export module Foo; // #mod-decl
+#ifndef NO_MODULE_DECL
+export module Foo;
+#ifdef NO_GLOBAL_FRAG
+// expected-error@-2 {{module declaration must occur at the start of the translation unit}}
+// expected-note@1 {{add 'module;' to the start of the file to introduce a global module fragment}}
+#endif
 
 // expected-error@#a2 {{declaration of 'a' in module Foo follows declaration in the global module}}
 // expected-note@#a1 {{previous decl}}
@@ -29,9 +36,22 @@
 
 module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}}
 
+#ifndef NO_PRIVATE_FRAG
 #ifdef EXPORT_FRAGS
 export // expected-error {{private module fragment cannot be exported}}
 #endif
-module :private;
+module :private; // #priv-frag
+#ifdef NO_MODULE_DECL
+// expected-error@-2 {{private module fragment declaration with no preceding module declaration}}
+#endif
+#endif
 
 int b; // ok
+
+
+#ifndef NO_PRIVATE_FRAG
+#ifndef NO_MODULE_DECL
+module :private; // expected-error {{private module fragment redefined}}
+// expected-note@#priv-frag {{previous definition is here}}
+#endif
+#endif
diff --git a/clang/test/CXX/basic/basic.link/p2.cpp b/clang/test/CXX/basic/basic.link/p2.cpp
new file mode 100644
index 0000000..54e347c
--- /dev/null
+++ b/clang/test/CXX/basic/basic.link/p2.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++2a -DEXPORT %s -verify
+// RUN: %clang_cc1 -std=c++2a -DEXPORT %s -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a -UEXPORT %s -verify -fmodule-file=%t.pcm
+
+#ifdef EXPORT
+// expected-no-diagnostics
+export
+#else
+// expected-note@+2 {{add 'export' here}}
+#endif
+module M;
+
+#ifndef EXPORT
+// expected-error@+2 {{private module fragment in module implementation unit}}
+#endif
+module :private;
diff --git a/clang/test/CXX/module/module.interface/p1.cpp b/clang/test/CXX/module/module.interface/p1.cpp
new file mode 100644
index 0000000..1eba817
--- /dev/null
+++ b/clang/test/CXX/module/module.interface/p1.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++2a %s -DERRORS -verify
+// RUN: %clang_cc1 -std=c++2a %s -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -DIMPLEMENTATION -verify -Db=b2 -Dc=c2
+
+module;
+
+#ifdef ERRORS
+export int a; // expected-error {{after the module declaration}}
+#endif
+
+#ifndef IMPLEMENTATION
+export
+#else
+// expected-error@#1 {{can only be used within a module interface unit}}
+// expected-error@#2 {{can only be used within a module interface unit}}
+// expected-note@+2 1+{{add 'export'}}
+#endif
+module M;
+
+export int b; // #1
+namespace N {
+  export int c; // #2
+}
+
+#ifdef ERRORS
+namespace {
+  export int d1; // FIXME: invalid
+  namespace X {
+    export int d2; // FIXME: invalid
+  }
+}
+
+export export int e; // expected-error {{within another export declaration}}
+export { export int f; } // expected-error {{within another export declaration}}
+
+module :private; // expected-note {{private module fragment begins here}}
+export int priv; // expected-error {{export declaration cannot be used in a private module fragment}}
+#endif
diff --git a/clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp b/clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
index 68f2570..52f45f5 100644
--- a/clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
+++ b/clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
@@ -10,7 +10,7 @@
 // expected-no-diagnostics
 export module A;
 #elif IMPLEMENTATION
-module A;
+module A; // #module-decl
  #ifdef BUILT_AS_INTERFACE
   // expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}}
   #define INTERFACE
@@ -23,6 +23,9 @@
 
 #ifndef INTERFACE
 export int b; // expected-error {{export declaration can only be used within a module interface unit}}
+#ifdef IMPLEMENTATION
+// expected-note@#module-decl {{add 'export' here}}
+#endif
 #else
 export int a;
 #endif