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@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'}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits