diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -491,7 +491,8 @@ IsInHeaderMap = true; - auto FixupSearchPath = [&]() { + auto FixupSearchPathAndFindUsableModule = + [&](auto File) -> OptionalFileEntryRef { if (SearchPath) { StringRef SearchPathRef(getName()); SearchPath->clear(); @@ -501,6 +502,12 @@ RelativePath->clear(); RelativePath->append(Filename.begin(), Filename.end()); } + if (!HS.findUsableModuleForHeader( + &File.getFileEntry(), File.getFileEntry().getDir(), + RequestingModule, SuggestedModule, isSystemHeaderDirectory())) { + return std::nullopt; + } + return File; }; // Check if the headermap maps the filename to a framework include @@ -513,8 +520,7 @@ } if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest, OpenFile)) { - FixupSearchPath(); - return *Res; + return FixupSearchPathAndFindUsableModule(*Res); } // Header maps need to be marked as used whenever the filename matches. diff --git a/clang/test/Modules/implicit-module-header-maps.cpp b/clang/test/Modules/implicit-module-header-maps.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Modules/implicit-module-header-maps.cpp @@ -0,0 +1,53 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: cd %t +// +// RUN: %hmaptool write a.hmap.json hmap +// +// RUN: %clang -Rmodule-build -fmodules -fimplicit-modules -fimplicit-module-maps -fmodule-map-file=module.modulemap -fsyntax-only -I hmap -fmodules-cache-path=%t test.cpp +// +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: cd %t +// +// RUN: sed -e "s|OUTPUTS_DIR|%t|g" -e "s#\\\\#/#g" b.hmap.json > hmap.json +// RUN: %hmaptool write hmap.json hmap +// +// RUN: %clang -Rmodule-build -fmodules -fimplicit-modules -fimplicit-module-maps -fmodule-map-file=module.modulemap -fsyntax-only -I hmap -fmodules-cache-path=%t test.cpp + +//--- After/Mapping.h +#ifdef FOO +#error foo +#endif + +//--- a.hmap.json +{ + "mappings" : + { + "Before/Mapping.h" : "After/Mapping.h", + "After/Mapping.h" : "After/Mapping.h" + } +} + +//--- b.hmap.json +{ + "mappings" : + { + "Before/Mapping.h" : "OUTPUTS_DIR/After/Mapping.h" + } +} + +//--- module.modulemap +module a { + header "After/Mapping.h" +} + + +//--- test.cpp +#define FOO +// This include will fail if: +// 1) modules are't used, as the `FOO` define will propagate into the included +// header and trip a `#error`, or +// 2) header maps aren't usesd, as the header name doesn't exist and relies on +// the header map to remap it to the real header. +#include "Before/Mapping.h"