Author: rsmith Date: Tue Oct 10 15:35:27 2017 New Revision: 315381 URL: http://llvm.org/viewvc/llvm-project?rev=315381&view=rev Log: [Modules TS] Diagnose attempts to enter module implementation units without the module interface being available.
Added: cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/Parser.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=315381&r1=315380&r2=315381&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 10 15:35:27 2017 @@ -8994,6 +8994,9 @@ def err_module_redefinition : Error< "redefinition of module '%0'">; def note_prev_module_definition : Note<"previously defined here">; def note_prev_module_definition_from_ast_file : Note<"module loaded from '%0'">; +def err_module_not_defined : Error< + "definition of module '%0' is not available; use -fmodule-file= to specify " + "path to precompiled module interface">; def err_module_private_specialization : Error< "%select{template|partial|member}0 specialization cannot be " "declared __module_private__">; Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=315381&r1=315380&r2=315381&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Tue Oct 10 15:35:27 2017 @@ -1533,7 +1533,8 @@ private: TypeDiagnoser *Diagnoser); struct ModuleScope { - clang::Module *Module; + clang::Module *Module = nullptr; + bool ModuleInterface = false; VisibleModuleSet OuterVisibleModules; }; /// The modules we're currently parsing. @@ -2051,9 +2052,9 @@ public: SourceLocation SemiLoc); enum class ModuleDeclKind { - Module, ///< 'module X;' + Interface, ///< 'export module X;' + Implementation, ///< 'module X;' Partition, ///< 'module partition X;' - Implementation, ///< 'module implementation X;' }; /// The parser has processed a module-declaration that begins the definition Modified: cfe/trunk/lib/Parse/Parser.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=315381&r1=315380&r2=315381&view=diff ============================================================================== --- cfe/trunk/lib/Parse/Parser.cpp (original) +++ cfe/trunk/lib/Parse/Parser.cpp Tue Oct 10 15:35:27 2017 @@ -2048,7 +2048,7 @@ Parser::DeclGroupPtrTy Parser::ParseModu SourceLocation StartLoc = Tok.getLocation(); Sema::ModuleDeclKind MDK = TryConsumeToken(tok::kw_export) - ? Sema::ModuleDeclKind::Module + ? Sema::ModuleDeclKind::Interface : Sema::ModuleDeclKind::Implementation; assert(Tok.is(tok::kw_module) && "not a module declaration"); @@ -2057,7 +2057,7 @@ Parser::DeclGroupPtrTy Parser::ParseModu if (Tok.is(tok::identifier) && NextToken().is(tok::identifier) && Tok.getIdentifierInfo()->isStr("partition")) { // If 'partition' is present, this must be a module interface unit. - if (MDK != Sema::ModuleDeclKind::Module) + if (MDK != Sema::ModuleDeclKind::Interface) Diag(Tok.getLocation(), diag::err_module_implementation_partition) << FixItHint::CreateInsertion(ModuleLoc, "export "); MDK = Sema::ModuleDeclKind::Partition; Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=315381&r1=315380&r2=315381&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Oct 10 15:35:27 2017 @@ -16168,6 +16168,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe // implementation unit. That indicates the 'export' is missing. Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch) << FixItHint::CreateInsertion(ModuleLoc, "export "); + MDK = ModuleDeclKind::Interface; break; case LangOptions::CMK_ModuleMap: @@ -16207,7 +16208,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe assert(ModuleScopes.size() == 1 && "expected to be at global module scope"); switch (MDK) { - case ModuleDeclKind::Module: { + case ModuleDeclKind::Interface: { // We can't have parsed or imported a definition of this module or parsed a // module map defining it already. if (auto *M = Map.findModule(ModuleName)) { @@ -16237,14 +16238,16 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe PP.getIdentifierInfo(ModuleName), Path[0].second); Mod = getModuleLoader().loadModule(ModuleLoc, Path, Module::AllVisible, /*IsIncludeDirective=*/false); - // FIXME: Produce an error in this case. - if (!Mod) + if (!Mod) { + Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName; return nullptr; + } break; } // Switch from the global module to the named module. ModuleScopes.back().Module = Mod; + ModuleScopes.back().ModuleInterface = MDK != ModuleDeclKind::Implementation; VisibleModules.setVisible(Mod, ModuleLoc); // From now on, we have an owning module for all declarations we see. @@ -16430,8 +16433,7 @@ Decl *Sema::ActOnStartExportDecl(Scope * // 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->Kind != Module::ModuleInterfaceUnit) + if (ModuleScopes.empty() || !ModuleScopes.back().ModuleInterface) Diag(ExportLoc, diag::err_export_not_in_module_interface); // An export-declaration [...] shall not contain more than one Modified: cfe/trunk/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp?rev=315381&r1=315380&r2=315381&view=diff ============================================================================== --- cfe/trunk/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp (original) +++ cfe/trunk/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp Tue Oct 10 15:35:27 2017 @@ -9,7 +9,6 @@ // RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface -fmodule-file=%t/x.pcm %t/x.y.cppm -o %t/x.y.pcm // // Module implementation for unknown and known module. (The former is ill-formed.) -// FIXME: TEST=1 should fail because we don't have an interface for module z. // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \ // RUN: -DTEST=1 -DEXPORT= -DPARTITION= -DMODULE_NAME=z // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \ @@ -32,11 +31,11 @@ // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \ // RUN: -DTEST=7 -DEXPORT= -DPARTITION=elderberry -DMODULE_NAME=z // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \ -// RUN: -DTEST=8 -DEXPORT= -DPARTITION= -DMODULE_NAME='z [[]]' +// RUN: -DTEST=8 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[]]' // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \ -// RUN: -DTEST=9 -DEXPORT= -DPARTITION= -DMODULE_NAME='z [[fancy]]' +// RUN: -DTEST=9 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[fancy]]' // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \ -// RUN: -DTEST=10 -DEXPORT= -DPARTITION= -DMODULE_NAME='z [[maybe_unused]]' +// RUN: -DTEST=10 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[maybe_unused]]' EXPORT module PARTITION MODULE_NAME; #if TEST == 4 @@ -45,11 +44,13 @@ EXPORT module PARTITION MODULE_NAME; #elif TEST == 6 // expected-error@-5 {{module partition must be declared 'export'}} #elif TEST == 7 -// expected-error@-7 {{expected ';'}} expected-error@-7 {{requires a type specifier}} +// expected-error@-7 {{expected ';'}} expected-error@-7 {{requires a type specifier}} expected-error@-7 {{definition of module 'elderberry' is not available}} #elif TEST == 9 // expected-warning@-9 {{unknown attribute 'fancy' ignored}} #elif TEST == 10 // expected-error-re@-11 {{'maybe_unused' attribute cannot be applied to a module{{$}}}} +#elif TEST == 1 +// expected-error@-13 {{definition of module 'z' is not available}} #else // expected-no-diagnostics #endif Modified: cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp?rev=315381&r1=315380&r2=315381&view=diff ============================================================================== --- cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp (original) +++ cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp Tue Oct 10 15:35:27 2017 @@ -9,12 +9,15 @@ // RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %t/a.b.cppm -o %t/a.b.pcm // // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -fmodule-file=%t/a.b.pcm -verify %s \ -// RUN: -DMODULE_NAME=z +// RUN: -DMODULE_NAME=z -DINTERFACE // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -fmodule-file=%t/a.b.pcm -verify %s \ // RUN: -DMODULE_NAME=a.b // RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -fmodule-file=%t/a.b.pcm -verify %s \ // RUN: -DMODULE_X -DMODULE_NAME=x +#ifdef INTERFACE +export +#endif module MODULE_NAME; int use_1 = a; Modified: 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=315381&r1=315380&r2=315381&view=diff ============================================================================== --- cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp (original) +++ cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp Tue Oct 10 15:35:27 2017 @@ -1,17 +1,19 @@ // 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 -DINTERFACE -verify -emit-module-interface -o %t +// RUN: %clang_cc1 -fmodules-ts %s -DIMPLEMENTATION -verify -fmodule-file=%t -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 +// expected-no-diagnostics export module A; #elif IMPLEMENTATION module A; #ifdef BUILT_AS_INTERFACE // expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}} + #define INTERFACE #endif #else #ifdef BUILT_AS_INTERFACE @@ -19,9 +21,8 @@ module A; #endif #endif -export int a; #ifndef INTERFACE -// expected-error@-2 {{export declaration can only be used within a module interface unit}} +export int b; // expected-error {{export declaration can only be used within a module interface unit}} #else -// expected-no-diagnostics +export int a; #endif Added: cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp?rev=315381&view=auto ============================================================================== --- cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp (added) +++ cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp Tue Oct 10 15:35:27 2017 @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fmodules-ts -verify %s + +// A named module shall contain exactly one module interface unit. +module M; // expected-error {{definition of module 'M' is not available; use -fmodule-file= to specify path to precompiled module interface}} + +// FIXME: How do we ensure there is not more than one? _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits