r334859 - [Modules] Improve .Private fix-its to handle 'explicit' and 'framework'

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 15 13:13:28 PDT 2018


Author: bruno
Date: Fri Jun 15 13:13:28 2018
New Revision: 334859

URL: http://llvm.org/viewvc/llvm-project?rev=334859&view=rev
Log:
[Modules] Improve .Private fix-its to handle 'explicit' and 'framework'

When in the context of suggestion the fix-it from .Private to _Private
for private modules, trim off the 'explicit' and add 'framework' when
appropriate.

rdar://problem/41030554

Modified:
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap
    cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap
    cfe/trunk/test/Modules/implicit-private-with-submodule.m

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=334859&r1=334858&r2=334859&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Fri Jun 15 13:13:28 2018
@@ -1403,6 +1403,13 @@ namespace clang {
     void parseConflict();
     void parseInferredModuleDecl(bool Framework, bool Explicit);
 
+    /// Private modules are canonicalized as Foo_Private. Clang provides extra
+    /// module map search logic to find the appropriate private module when PCH
+    /// is used with implicit module maps. Warn when private modules are written
+    /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
+    void diagnosePrivateModules(SourceLocation ExplicitLoc,
+                                SourceLocation FrameworkLoc);
+
     using Attributes = ModuleMap::Attributes;
 
     bool parseOptionalAttributes(Attributes &Attrs);
@@ -1672,11 +1679,8 @@ namespace {
 /// module map search logic to find the appropriate private module when PCH
 /// is used with implicit module maps. Warn when private modules are written
 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
-static void diagnosePrivateModules(const ModuleMap &Map,
-                                   DiagnosticsEngine &Diags,
-                                   const Module *ActiveModule,
-                                   SourceLocation InlineParent) {
-
+void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
+                                             SourceLocation FrameworkLoc) {
   auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
                              const Module *M, SourceRange ReplLoc) {
     auto D = Diags.Report(ActiveModule->DefinitionLoc,
@@ -1693,6 +1697,7 @@ static void diagnosePrivateModules(const
     SmallString<128> FullName(ActiveModule->getFullModuleName());
     if (!FullName.startswith(M->Name) && !FullName.endswith("Private"))
       continue;
+    SmallString<128> FixedPrivModDecl;
     SmallString<128> Canonical(M->Name);
     Canonical.append("_Private");
 
@@ -1702,8 +1707,20 @@ static void diagnosePrivateModules(const
       Diags.Report(ActiveModule->DefinitionLoc,
                    diag::warn_mmap_mismatched_private_submodule)
           << FullName;
-      GenNoteAndFixIt(FullName, Canonical, M,
-                      SourceRange(InlineParent, ActiveModule->DefinitionLoc));
+
+      SourceLocation FixItInitBegin = CurrModuleDeclLoc;
+      if (FrameworkLoc.isValid())
+        FixItInitBegin = FrameworkLoc;
+      if (ExplicitLoc.isValid())
+        FixItInitBegin = ExplicitLoc;
+
+      if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework)
+        FixedPrivModDecl.append("framework ");
+      FixedPrivModDecl.append("module ");
+      FixedPrivModDecl.append(Canonical);
+
+      GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
+                      SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
       continue;
     }
 
@@ -1747,6 +1764,7 @@ void ModuleMapParser::parseModuleDecl()
 
   // Parse 'explicit' or 'framework' keyword, if present.
   SourceLocation ExplicitLoc;
+  SourceLocation FrameworkLoc;
   bool Explicit = false;
   bool Framework = false;
 
@@ -1758,7 +1776,7 @@ void ModuleMapParser::parseModuleDecl()
 
   // Parse 'framework' keyword, if present.
   if (Tok.is(MMToken::FrameworkKeyword)) {
-    consumeToken();
+    FrameworkLoc = consumeToken();
     Framework = true;
   } 
   
@@ -1800,7 +1818,6 @@ void ModuleMapParser::parseModuleDecl()
   }
   
   Module *PreviousActiveModule = ActiveModule;  
-  SourceLocation LastInlineParentLoc = SourceLocation();
   if (Id.size() > 1) {
     // This module map defines a submodule. Go find the module of which it
     // is a submodule.
@@ -1811,7 +1828,6 @@ void ModuleMapParser::parseModuleDecl()
         if (I == 0)
           TopLevelModule = Next;
         ActiveModule = Next;
-        LastInlineParentLoc = Id[I].second;
         continue;
       }
       
@@ -1934,7 +1950,7 @@ void ModuleMapParser::parseModuleDecl()
       !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
                        StartLoc) &&
       ActiveModule->ModuleMapIsPrivate)
-    diagnosePrivateModules(Map, Diags, ActiveModule, LastInlineParentLoc);
+    diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
 
   bool Done = false;
   do {

Modified: cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap?rev=334859&r1=334858&r2=334859&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap (original)
+++ cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap Fri Jun 15 13:13:28 2018
@@ -2,3 +2,9 @@ framework module A {
   header "a.h"
   export *
 }
+
+framework module B {
+}
+
+framework module C {
+}

Modified: cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap?rev=334859&r1=334858&r2=334859&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap (original)
+++ cfe/trunk/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap Fri Jun 15 13:13:28 2018
@@ -2,3 +2,9 @@ framework module A.Private {
   header "aprivate.h"
   export *
 }
+
+explicit module B.Private {
+}
+
+explicit framework module C.Private {
+}

Modified: cfe/trunk/test/Modules/implicit-private-with-submodule.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/implicit-private-with-submodule.m?rev=334859&r1=334858&r2=334859&view=diff
==============================================================================
--- cfe/trunk/test/Modules/implicit-private-with-submodule.m (original)
+++ cfe/trunk/test/Modules/implicit-private-with-submodule.m Fri Jun 15 13:13:28 2018
@@ -13,7 +13,16 @@
 
 // expected-warning at Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:1{{private submodule 'A.Private' in private module map, expected top-level module}}
 // expected-note at Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:1{{rename 'A.Private' to ensure it can be found by name}}
-// CHECK: fix-it:"{{.*}}module.private.modulemap":{1:18-1:27}:"A_Private"
+
+// expected-warning at Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:6{{private submodule 'B.Private' in private module map, expected top-level module}}
+// expected-note at Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:6{{rename 'B.Private' to ensure it can be found by name}}
+
+// expected-warning at Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:9{{private submodule 'C.Private' in private module map, expected top-level module}}
+// expected-note at Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:9{{rename 'C.Private' to ensure it can be found by name}}
+
+// CHECK: fix-it:"{{.*}}module.private.modulemap":{1:1-1:27}:"framework module A_Private"
+// CHECK: fix-it:"{{.*}}module.private.modulemap":{6:1-6:26}:"framework module B_Private"
+// CHECK: fix-it:"{{.*}}module.private.modulemap":{9:1-9:36}:"framework module C_Private"
 
 #ifndef HEADER
 #define HEADER




More information about the cfe-commits mailing list