From a7fb4573dfc1578edb3ba94acfa485167f8d5b9c Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 6 Dec 2016 00:12:39 +0000 Subject: [PATCH] [modules] Use the "redundant #include" diagnostic rather than the "module import can't appear here" diagnostic if an already-visible module is textually entered (because we have the module map but not the AST file) within a function/namespace scope. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@288737 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Parser.h | 3 ++- include/clang/Sema/Sema.h | 4 ---- lib/Parse/Parser.cpp | 27 +++++++++++++++++++++------ lib/Sema/SemaDecl.cpp | 8 +------- test/Modules/Inputs/cxx-header.h | 5 ++++- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 7976e84e9c..40eb579be4 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -74,7 +74,8 @@ class Parser : public CodeCompletionHandler { // a statement). SourceLocation PrevTokLocation; - unsigned short ParenCount, BracketCount, BraceCount; + unsigned short ParenCount = 0, BracketCount = 0, BraceCount = 0; + unsigned short MisplacedModuleBeginCount = 0; /// Actions - These are the callbacks we invoke as we parse various constructs /// in the file. diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index fe65b08a08..4334e6522c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1908,10 +1908,6 @@ public: /// \brief The parser has left a submodule. void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod); - /// \brief Check if module import may be found in the current context, - /// emit error if not. - void diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc); - /// \brief Create an implicit import of the given module at the given /// source location, for error recovery, if possible. /// diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 78eba62695..e97b5e495a 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -77,7 +77,6 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) Tok.setKind(tok::eof); Actions.CurScope = nullptr; NumCachedScopes = 0; - ParenCount = BracketCount = BraceCount = 0; CurParsedObjCImpl = nullptr; // Add #pragma handlers. These are removed and destroyed in the @@ -2169,19 +2168,35 @@ bool Parser::parseMisplacedModuleImport() { while (true) { switch (Tok.getKind()) { case tok::annot_module_end: + // If we recovered from a misplaced module begin, we expect to hit a + // misplaced module end too. Stay in the current context when this + // happens. + if (MisplacedModuleBeginCount) { + --MisplacedModuleBeginCount; + Actions.ActOnModuleEnd(Tok.getLocation(), + reinterpret_cast( + Tok.getAnnotationValue())); + ConsumeToken(); + continue; + } // Inform caller that recovery failed, the error must be handled at upper - // level. + // level. This will generate the desired "missing '}' at end of module" + // diagnostics on the way out. return true; case tok::annot_module_begin: - Actions.diagnoseMisplacedModuleImport(reinterpret_cast( - Tok.getAnnotationValue()), Tok.getLocation()); - return true; + // Recover by entering the module (Sema will diagnose). + Actions.ActOnModuleBegin(Tok.getLocation(), + reinterpret_cast( + Tok.getAnnotationValue())); + ConsumeToken(); + ++MisplacedModuleBeginCount; + continue; case tok::annot_module_include: // Module import found where it should not be, for instance, inside a // namespace. Recover by importing the module. Actions.ActOnModuleInclude(Tok.getLocation(), reinterpret_cast( - Tok.getAnnotationValue())); + Tok.getAnnotationValue())); ConsumeToken(); // If there is another module import, process it. continue; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8c180790cc..984a14ad50 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -15439,10 +15439,6 @@ static void checkModuleImportContext(Sema &S, Module *M, } } -void Sema::diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc) { - return checkModuleImportContext(*this, M, ImportLoc, CurContext); -} - Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path) { @@ -15610,7 +15606,7 @@ void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { } void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { - checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext); + checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true); ModuleScopes.push_back({}); ModuleScopes.back().Module = Mod; @@ -15621,8 +15617,6 @@ void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { } void Sema::ActOnModuleEnd(SourceLocation EofLoc, Module *Mod) { - checkModuleImportContext(*this, Mod, EofLoc, CurContext); - if (getLangOpts().ModulesLocalVisibility) { VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules); // Leaving a module hides namespace names, so our visible namespace cache diff --git a/test/Modules/Inputs/cxx-header.h b/test/Modules/Inputs/cxx-header.h index 7ed7775122..ee52c63911 100644 --- a/test/Modules/Inputs/cxx-header.h +++ b/test/Modules/Inputs/cxx-header.h @@ -1 +1,4 @@ -int f(); +#ifndef CXX_HEADER_H +#define CXX_HEADER_H +inline int f() { return 0; } +#endif -- 2.40.0