diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-08-19 01:43:06 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-08-19 01:43:06 +0000 |
commit | 964cc53d9a7411bc2d7ecc2bf7958ac5c65da32e (patch) | |
tree | 98aa8d14c7270f2a64cb48186e70936d58cf75fd /clang/lib/Sema/SemaDecl.cpp | |
parent | 9ec2cb600bd96b08c6d48d914c982b3c51e6b418 (diff) | |
download | bcm5719-llvm-964cc53d9a7411bc2d7ecc2bf7958ac5c65da32e.tar.gz bcm5719-llvm-964cc53d9a7411bc2d7ecc2bf7958ac5c65da32e.zip |
C++ Modules TS: support parsing the 'module' declaration (including extensions
from p0273r0 approved by EWG). We'll eventually need to handle this from the
lexer as well, in order to disallow preprocessor directives preceding the
module declaration and to support macro import.
llvm-svn: 279196
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5dab15a8d66..ca4de55fb51 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15178,6 +15178,56 @@ void Sema::diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc) { return checkModuleImportContext(*this, M, ImportLoc, CurContext); } +Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation ModuleLoc, + ModuleDeclKind MDK, + ModuleIdPath Path) { + // We should see 'module implementation' if and only if we are not compiling + // a module interface. + if (getLangOpts().CompilingModule == + (MDK == ModuleDeclKind::Implementation)) { + Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch) + << (unsigned)MDK; + return nullptr; + } + + // FIXME: Create a ModuleDecl and return it. + // FIXME: Teach the lexer to handle this declaration too. + + switch (MDK) { + case ModuleDeclKind::Module: + // FIXME: Check we're not in a submodule. + // FIXME: Set CurrentModule and create a corresponding Module object. + return nullptr; + + case ModuleDeclKind::Partition: + // FIXME: Check we are in a submodule of the named module. + return nullptr; + + case ModuleDeclKind::Implementation: + DeclResult Import = ActOnModuleImport(ModuleLoc, ModuleLoc, Path); + if (Import.isInvalid()) + return nullptr; + ImportDecl *ID = cast<ImportDecl>(Import.get()); + + // The current module is whatever we just loaded. + // + // FIXME: We should probably do this from the lexer rather than waiting + // until now, in case we look ahead across something where the current + // module matters (eg a #include). + auto Name = ID->getImportedModule()->getTopLevelModuleName(); + if (!getLangOpts().CurrentModule.empty() && + getLangOpts().CurrentModule != Name) { + Diag(Path.front().second, diag::err_current_module_name_mismatch) + << SourceRange(Path.front().second, Path.back().second) + << getLangOpts().CurrentModule; + } + const_cast<LangOptions&>(getLangOpts()).CurrentModule = Name; + return ConvertDeclToDeclGroup(ID); + } + + llvm_unreachable("unexpected module decl kind"); +} + DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, SourceLocation ImportLoc, ModuleIdPath Path) { @@ -15194,7 +15244,10 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, // FIXME: we should support importing a submodule within a different submodule // of the same top-level module. Until we do, make it an error rather than // silently ignoring the import. - if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule) + // Import-from-implementation is valid in the Modules TS. FIXME: Should we + // warn on a redundant import of the current module? + if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule && + (getLangOpts().CompilingModule || !getLangOpts().ModulesTS)) Diag(ImportLoc, getLangOpts().CompilingModule ? diag::err_module_self_import : diag::err_module_import_in_implementation) |