Author: rsmith Date: Tue Oct 10 17:36:56 2017 New Revision: 315397 URL: http://llvm.org/viewvc/llvm-project?rev=315397&view=rev Log: [Modules TS] Diagnose missing/duplicate module-declaration.
Added: cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/Sema.cpp cfe/trunk/lib/Sema/SemaDecl.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=315397&r1=315396&r2=315397&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 10 17:36:56 2017 @@ -8997,6 +8997,11 @@ def note_prev_module_definition_from_ast 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_redeclaration : Error< + "translation unit contains multiple module declarations">; +def note_prev_module_declaration : Note<"previous module declaration is here">; +def err_module_declaration_missing : Error< + "missing 'export module' declaration in module interface unit">; def err_module_private_specialization : Error< "%select{template|partial|member}0 specialization cannot be " "declared __module_private__">; Modified: cfe/trunk/lib/Sema/Sema.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=315397&r1=315396&r2=315397&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.cpp (original) +++ cfe/trunk/lib/Sema/Sema.cpp Tue Oct 10 17:36:56 2017 @@ -930,6 +930,17 @@ void Sema::ActOnEndOfTranslationUnit() { } if (TUKind == TU_Module) { + // If we are building a module interface unit, we need to have seen the + // module declaration by now. + if (getLangOpts().getCompilingModule() == + LangOptions::CMK_ModuleInterface && + ModuleScopes.back().Module->Kind != Module::ModuleInterfaceUnit) { + // FIXME: Make a better guess as to where to put the module declaration. + Diag(getSourceManager().getLocForStartOfFile( + getSourceManager().getMainFileID()), + diag::err_module_declaration_missing); + } + // If we are building a module, resolve all of the exported declarations // now. if (Module *CurrentModule = PP.getCurrentModule()) { Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=315397&r1=315396&r2=315397&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Oct 10 17:36:56 2017 @@ -16176,9 +16176,19 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe return nullptr; } + assert(ModuleScopes.size() == 1 && "expected to be at global module scope"); + // FIXME: Most of this work should be done by the preprocessor rather than // here, in order to support macro import. + // Only one module-declaration is permitted per source file. + if (ModuleScopes.back().Module->Kind == Module::ModuleInterfaceUnit) { + Diag(ModuleLoc, diag::err_module_redeclaration); + Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module), + diag::note_prev_module_declaration); + return nullptr; + } + // Flatten the dots in a module name. Unlike Clang's hierarchical module map // modules, the dots here are just another character that can appear in a // module name. @@ -16189,8 +16199,6 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe ModuleName += Piece.first->getName(); } - // FIXME: If we've already seen a module-declaration, report an error. - // If a module name was explicitly specified on the command line, it must be // correct. if (!getLangOpts().CurrentModule.empty() && @@ -16205,8 +16213,6 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe auto &Map = PP.getHeaderSearchInfo().getModuleMap(); Module *Mod; - assert(ModuleScopes.size() == 1 && "expected to be at global module scope"); - switch (MDK) { case ModuleDeclKind::Interface: { // We can't have parsed or imported a definition of this module or parsed a @@ -16240,7 +16246,9 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe /*IsIncludeDirective=*/false); if (!Mod) { Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName; - return nullptr; + // Create an empty module interface unit for error recovery. + Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName, + ModuleScopes.front().Module); } break; } 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=315397&r1=315396&r2=315397&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 17:36:56 2017 @@ -17,7 +17,7 @@ module A; #endif #else #ifdef BUILT_AS_INTERFACE - // FIXME: Diagnose missing module declaration (at end of TU) + // expected-error@1 {{missing 'export module' declaration in module interface unit}} #endif #endif Added: cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp?rev=315397&view=auto ============================================================================== --- cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp (added) +++ cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp Tue Oct 10 17:36:56 2017 @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++17 -fmodules-ts -verify %s -DFOO=export -DBAR=export +// RUN: %clang_cc1 -std=c++17 -fmodules-ts -verify %s -DFOO=export -DBAR= +// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s -DFOO=export -emit-module-interface -o %t +// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s -fmodule-file=%t -DFOO= +// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s -fmodule-file=%t -DBAR=export +// RUN: %clang_cc1 -std=c++17 -fmodules-ts -verify %s -fmodule-file=%t -DFOO= -DBAR=export + +#ifdef FOO +FOO module foo; // expected-note {{previous module declaration is here}} +#endif + +#ifdef BAR +BAR module bar; // expected-error {{translation unit contains multiple module declarations}} +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits