r360195 - -frewrite-imports: Add support for wildcard rules in umbrella modules with

David Blaikie via cfe-commits cfe-commits at lists.llvm.org
Tue May 7 14:38:51 PDT 2019


Author: dblaikie
Date: Tue May  7 14:38:51 2019
New Revision: 360195

URL: http://llvm.org/viewvc/llvm-project?rev=360195&view=rev
Log:
-frewrite-imports: Add support for wildcard rules in umbrella modules with

This trips over a few other limitations, but in the interests of incremental development I'm starting here & I'll look at the issues with -verify and filesystem checks (the fact that the behavior depends on the existence of a 'foo' directory even though it shouldn't need it), etc.

Reviewers: rsmith

Differential Revision: https://reviews.llvm.org/D61656

Added:
    cfe/trunk/test/Modules/preprocess-umbrella.cpp
Modified:
    cfe/trunk/include/clang/Basic/Module.h
    cfe/trunk/lib/Basic/Module.cpp
    cfe/trunk/lib/Lex/Pragma.cpp

Modified: cfe/trunk/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=360195&r1=360194&r2=360195&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Module.h (original)
+++ cfe/trunk/include/clang/Basic/Module.h Tue May  7 14:38:51 2019
@@ -541,6 +541,7 @@ public:
   ///
   /// \returns The submodule if found, or NULL otherwise.
   Module *findSubmodule(StringRef Name) const;
+  Module *findOrInferSubmodule(StringRef Name);
 
   /// Determine whether the specified module would be visible to
   /// a lookup at the end of this module.

Modified: cfe/trunk/lib/Basic/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=360195&r1=360194&r2=360195&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Module.cpp (original)
+++ cfe/trunk/lib/Basic/Module.cpp Tue May  7 14:38:51 2019
@@ -321,6 +321,21 @@ Module *Module::findSubmodule(StringRef
   return SubModules[Pos->getValue()];
 }
 
+Module *Module::findOrInferSubmodule(StringRef Name) {
+  llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
+  if (Pos != SubModuleIndex.end())
+    return SubModules[Pos->getValue()];
+  if (!InferSubmodules)
+    return nullptr;
+  Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
+  Result->InferExplicitSubmodules = InferExplicitSubmodules;
+  Result->InferSubmodules = InferSubmodules;
+  Result->InferExportWildcard = InferExportWildcard;
+  if (Result->InferExportWildcard)
+    Result->Exports.push_back(Module::ExportDecl(nullptr, true));
+  return Result;
+}
+
 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
   // All non-explicit submodules are exported.
   for (std::vector<Module *>::const_iterator I = SubModules.begin(),

Modified: cfe/trunk/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=360195&r1=360194&r2=360195&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Tue May  7 14:38:51 2019
@@ -1584,16 +1584,15 @@ struct PragmaModuleBeginHandler : public
 
     // Find the module we're entering. We require that a module map for it
     // be loaded or implicitly loadable.
-    // FIXME: We could create the submodule here. We'd need to know whether
-    // it's supposed to be explicit, but not much else.
-    Module *M = PP.getHeaderSearchInfo().lookupModule(Current);
+    auto &HSI = PP.getHeaderSearchInfo();
+    Module *M = HSI.lookupModule(Current);
     if (!M) {
       PP.Diag(ModuleName.front().second,
               diag::err_pp_module_begin_no_module_map) << Current;
       return;
     }
     for (unsigned I = 1; I != ModuleName.size(); ++I) {
-      auto *NewM = M->findSubmodule(ModuleName[I].first->getName());
+      auto *NewM = M->findOrInferSubmodule(ModuleName[I].first->getName());
       if (!NewM) {
         PP.Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
           << M->getFullModuleName() << ModuleName[I].first;

Added: cfe/trunk/test/Modules/preprocess-umbrella.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess-umbrella.cpp?rev=360195&view=auto
==============================================================================
--- cfe/trunk/test/Modules/preprocess-umbrella.cpp (added)
+++ cfe/trunk/test/Modules/preprocess-umbrella.cpp Tue May  7 14:38:51 2019
@@ -0,0 +1,36 @@
+// FIXME: The standalone module still seems to cause clang to want to test for
+// the existence of a 'foo' directory:
+// RUN: mkdir %t
+// RUN: cp %s %t
+// RUN: mkdir %t/foo
+// RUN: cd %t
+// RUN: not %clang_cc1 -fmodules -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: error: no matching function for call to 'foo'
+// CHECK: note: candidate function not viable: requires 0 arguments, but 1 was provided
+
+// FIXME: This should use -verify, but it seems it doesn't hook up the
+// SourceManager correctly or something, and the foo.h note gets attributed to
+// the synthetic module translation unit "foo.map Line 2:...".
+// %clang_cc1 -fmodules -verify %s
+
+#pragma clang module build foo
+module foo {
+  umbrella "foo"
+  module * {
+    export *
+  }
+}
+#pragma clang module contents
+#pragma clang module begin foo.foo
+# 1 "foo.h" 1
+#ifndef FOO_FOO_H
+void foo();
+#endif
+#pragma clang module end
+#pragma clang module endbuild
+#pragma clang module import foo.foo
+// expected-note at foo.h:2 {{candidate function not viable: requires 0 arguments, but 1 was provided}}
+int main() {
+  foo(1); // expected-error {{no matching function for call to 'foo'}}
+}




More information about the cfe-commits mailing list