]> granicus.if.org Git - clang/commitdiff
[modules] Use the "redundant #include" diagnostic rather than the "module
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 6 Dec 2016 00:12:39 +0000 (00:12 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 6 Dec 2016 00:12:39 +0000 (00:12 +0000)
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
include/clang/Sema/Sema.h
lib/Parse/Parser.cpp
lib/Sema/SemaDecl.cpp
test/Modules/Inputs/cxx-header.h

index 7976e84e9cd94e2b5e531a5a2da4a72d58700af2..40eb579be4652a8b2b3678e03a6b48df3c5ed3b3 100644 (file)
@@ -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.
index fe65b08a085602a10d4f9fcf1b9ffba93004a2b9..4334e6522c260d83bb3a15f56fa1f9defed300d8 100644 (file)
@@ -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.
   ///
index 78eba62695ddae86f163b5d7f67a409fd1a2b535..e97b5e495a67f02505f67ed7140478c3345fa382 100644 (file)
@@ -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<Module *>(
+                                   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<Module *>(
-        Tok.getAnnotationValue()), Tok.getLocation());
-      return true;
+      // Recover by entering the module (Sema will diagnose).
+      Actions.ActOnModuleBegin(Tok.getLocation(),
+                               reinterpret_cast<Module *>(
+                                   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<Module *>(
-                                 Tok.getAnnotationValue()));
+                                     Tok.getAnnotationValue()));
       ConsumeToken();
       // If there is another module import, process it.
       continue;
index 8c180790cc931f36cfab75e0a38756639f105a93..984a14ad50d2de612267aeb7c7f16558c2f79987 100644 (file)
@@ -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
index 7ed777512290417bcbd91b14c2c91f6a3f58da0e..ee52c639116a29e8063bce8628d9a33cc978df74 100644 (file)
@@ -1 +1,4 @@
-int f();
+#ifndef CXX_HEADER_H
+#define CXX_HEADER_H
+inline int f() { return 0; }
+#endif