r301271 - [modules ts] Diagnose 'export' declarations outside of a module interface.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 24 16:12:30 PDT 2017


Author: rsmith
Date: Mon Apr 24 18:12:30 2017
New Revision: 301271

URL: http://llvm.org/viewvc/llvm-project?rev=301271&view=rev
Log:
[modules ts] Diagnose 'export' declarations outside of a module interface.

Added:
    cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Basic/Module.h
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Parser/cxx-modules-interface.cppm
    cfe/trunk/test/SemaCXX/modules-ts.cppm

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=301271&r1=301270&r2=301271&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 24 18:12:30 2017
@@ -8804,7 +8804,7 @@ let CategoryName = "Modules Issue" in {
 def err_module_decl_in_module_map_module : Error<
   "'module' declaration found while building module from module map">;
 def err_module_interface_implementation_mismatch : Error<
-  "missing 'export' specifier in 'module' declaration while "
+  "missing 'export' specifier in module declaration while "
   "building module interface">;
 def err_current_module_name_mismatch : Error<
   "module name '%0' specified on command line does not match name of module">;
@@ -8848,8 +8848,13 @@ def err_module_self_import : Error<
   "import of module '%0' appears within same top-level module '%1'">;
 def err_module_import_in_implementation : Error<
   "@import of module '%0' in implementation of '%1'; use #import">;
+
+// C++ Modules TS
 def err_export_within_export : Error<
   "export declaration appears within another export declaration">;
+def err_export_not_in_module_interface : Error<
+  "export declaration can only be used within a module interface unit after "
+  "the module declaration">;
 
 def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
   "ambiguous use of internal linkage declaration %0 defined in multiple modules">,

Modified: cfe/trunk/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=301271&r1=301270&r2=301271&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Module.h (original)
+++ cfe/trunk/include/clang/Basic/Module.h Mon Apr 24 18:12:30 2017
@@ -62,6 +62,18 @@ public:
   /// \brief The location of the module definition.
   SourceLocation DefinitionLoc;
 
+  enum ModuleKind {
+    /// \brief This is a module that was defined by a module map and built out
+    /// of header files.
+    ModuleMapModule,
+
+    /// \brief This is a C++ Modules TS module interface unit.
+    ModuleInterfaceUnit
+  };
+
+  /// \brief The kind of this module.
+  ModuleKind Kind = ModuleMapModule;
+
   /// \brief The parent of this module. This will be NULL for the top-level
   /// module.
   Module *Parent;

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=301271&r1=301270&r2=301271&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Mon Apr 24 18:12:30 2017
@@ -581,6 +581,7 @@ Module *ModuleMap::createModuleForInterf
   auto *Result =
       new Module(Name, Loc, nullptr, /*IsFramework*/ false,
                  /*IsExplicit*/ false, NumCreatedModules++);
+  Result->Kind = Module::ModuleInterfaceUnit;
   Modules[Name] = SourceModule = Result;
 
   // Mark the main source file as being within the newly-created module so that

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=301271&r1=301270&r2=301271&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Apr 24 18:12:30 2017
@@ -15922,6 +15922,12 @@ Decl *Sema::ActOnStartExportDecl(Scope *
   ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc);
 
   // C++ Modules TS draft:
+  //   An export-declaration shall appear in the purview of a module other than
+  //   the global module.
+  if (ModuleScopes.empty() || !ModuleScopes.back().Module ||
+      ModuleScopes.back().Module->Kind != Module::ModuleInterfaceUnit)
+    Diag(ExportLoc, diag::err_export_not_in_module_interface);
+
   //   An export-declaration [...] shall not contain more than one
   //   export keyword.
   //

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=301271&r1=301270&r2=301271&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Apr 24 18:12:30 2017
@@ -4779,6 +4779,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
   ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
   bool First = true;
   Module *CurrentModule = nullptr;
+  Module::ModuleKind ModuleKind = Module::ModuleMapModule;
   RecordData Record;
   while (true) {
     llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
@@ -4871,6 +4872,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
         CurrentModule->setASTFile(F.File);
       }
 
+      CurrentModule->Kind = ModuleKind;
       CurrentModule->Signature = F.Signature;
       CurrentModule->IsFromModuleFile = true;
       CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
@@ -4969,6 +4971,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
 
         SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules);
       }
+      ModuleKind = (Module::ModuleKind)Record[2];
       break;
     }
 

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=301271&r1=301270&r2=301271&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Apr 24 18:12:30 2017
@@ -2694,9 +2694,10 @@ void ASTWriter::WriteSubmodules(Module *
   unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
   // Write the submodule metadata block.
-  RecordData::value_type Record[] = {getNumberOfModules(WritingModule),
-                                     FirstSubmoduleID -
-                                         NUM_PREDEF_SUBMODULE_IDS};
+  RecordData::value_type Record[] = {
+      getNumberOfModules(WritingModule),
+      FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS,
+      WritingModule->Kind};
   Stream.EmitRecord(SUBMODULE_METADATA, Record);
   
   // Write all of the submodules.

Added: cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp?rev=301271&view=auto
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp (added)
+++ cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp Mon Apr 24 18:12:30 2017
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fmodules-ts %s -verify -o /dev/null
+// RUN: %clang_cc1 -fmodules-ts %s -DINTERFACE -verify -o /dev/null
+// RUN: %clang_cc1 -fmodules-ts %s -DIMPLEMENTATION -verify -o /dev/null
+//
+// RUN: %clang_cc1 -fmodules-ts %s -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null
+// RUN: %clang_cc1 -fmodules-ts %s -DINTERFACE -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null
+// RUN: %clang_cc1 -fmodules-ts %s -DIMPLEMENTATION -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null
+
+#if INTERFACE
+export module A;
+#elif IMPLEMENTATION
+module A;
+ #ifdef BUILT_AS_INTERFACE
+  // expected-error at -2 {{missing 'export' specifier in module declaration while building module interface}}
+ #endif
+#else
+ #ifdef BUILT_AS_INTERFACE
+  // FIXME: Diagnose missing module declaration (at end of TU)
+ #endif
+#endif
+
+export int a;
+#ifndef INTERFACE
+// expected-error at -2 {{export declaration can only be used within a module interface unit}}
+#else
+// expected-no-diagnostics
+#endif

Modified: cfe/trunk/test/Parser/cxx-modules-interface.cppm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-modules-interface.cppm?rev=301271&r1=301270&r2=301271&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-modules-interface.cppm (original)
+++ cfe/trunk/test/Parser/cxx-modules-interface.cppm Mon Apr 24 18:12:30 2017
@@ -1,11 +1,10 @@
 // RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify
-// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -Dmodule=int -DERRORS
+// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DERRORS
 
 export module foo;
 #ifndef ERRORS
 // expected-no-diagnostics
 #else
-// FIXME: diagnose 'export' declaration in non-module
 // FIXME: diagnose missing module-declaration when building module interface
 
 // FIXME: proclaimed-ownership-declarations?

Modified: cfe/trunk/test/SemaCXX/modules-ts.cppm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/modules-ts.cppm?rev=301271&r1=301270&r2=301271&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/modules-ts.cppm (original)
+++ cfe/trunk/test/SemaCXX/modules-ts.cppm Mon Apr 24 18:12:30 2017
@@ -1,6 +1,6 @@
 // RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=0
-// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -Dmodule=int -DTEST=1
-// RUN: not %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -DTEST=2 2>&1 | FileCheck %s --check-prefix=CHECK-2
+// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=1
+// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -DTEST=2
 // RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -Dfoo=bar -DTEST=3
 
 #if TEST == 0
@@ -8,15 +8,14 @@
 #endif
 
 export module foo;
-#if TEST == 1
-// FIXME: diagnose export outside of module interface unit
-#elif TEST == 2
-// CHECK-2: error: redefinition of module 'foo'
+#if TEST == 2
+// expected-error at -2 {{redefinition of module 'foo'}}
+// expected-note at modules-ts.cppm:* {{loaded from}}
 #endif
 
 static int m; // ok, internal linkage, so no redefinition error
 int n;
-#if TEST == 3
+#if TEST >= 2
 // expected-error at -2 {{redefinition of '}}
 // expected-note at -3 {{previous}}
 #endif




More information about the cfe-commits mailing list