diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -754,7 +754,8 @@ const DirectoryEntry *Root, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, - bool IsSystemHeaderDir); + bool IsSystemHeaderDir, + StringRef FileName = ""); /// Find and suggest a usable module for the given file, which is part of /// the specified framework. 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 @@ -415,7 +415,7 @@ // If there is a module that corresponds to this header, suggest it. if (!findUsableModuleForHeader( &File->getFileEntry(), Dir ? Dir : File->getFileEntry().getDir(), - RequestingModule, SuggestedModule, IsSystemHeaderDir)) + RequestingModule, SuggestedModule, IsSystemHeaderDir, FileName)) return None; return *File; @@ -1563,10 +1563,18 @@ bool HeaderSearch::findUsableModuleForHeader( const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) { + ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir, + StringRef FileName) { if (File && needModuleLookup(RequestingModule, SuggestedModule)) { // If there is a module that corresponds to this header, suggest it. - hasModuleMap(File->getName(), Root, IsSystemHeaderDir); + + // FIXME: File->getName() *should* be the same as FileName, but because + // of the VFS and various hacks in FileManager, that's not necessarily the + // case. We should update this to use FileEntryRef instead and either + // always give back the originally-requested path, or provide a way to get + // to get it. + hasModuleMap(FileName.empty() ? File->getName() : FileName, Root, + IsSystemHeaderDir); return suggestModule(*this, File, RequestingModule, SuggestedModule); } return true; diff --git a/clang/test/Modules/Inputs/all-product-headers.yaml b/clang/test/Modules/Inputs/all-product-headers.yaml new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/all-product-headers.yaml @@ -0,0 +1,33 @@ +{ + 'version': 0, + 'case-sensitive': 'false', + 'roots': [ + { + 'type': 'directory', + 'name': "DUMMY_DIR/build/A.framework/PrivateHeaders" + 'contents': [ + { + 'type': 'file', + 'name': "A.h", + 'external-contents': "DUMMY_DIR/sources/A.h" + } + ] + }, + { + 'type': 'directory', + 'name': "DUMMY_DIR/build/A.framework/Modules" + 'contents': [ + { + 'type': 'file', + 'name': "module.modulemap", + 'external-contents': "DUMMY_DIR/build/module.modulemap" + }, + { + 'type': 'file', + 'name': "module.private.modulemap", + 'external-contents': "DUMMY_DIR/build/module.private.modulemap" + } + ] + } + ] +} diff --git a/clang/test/Modules/modulemap-collision.m b/clang/test/Modules/modulemap-collision.m new file mode 100644 --- /dev/null +++ b/clang/test/Modules/modulemap-collision.m @@ -0,0 +1,15 @@ +// REQUIRES: shell + +// RUN: rm -rf %t +// RUN: mkdir -p %t/sources %t/build +// RUN: echo "// A.h" > %t/sources/A.h +// RUN: echo "framework module A {}" > %t/sources/module.modulemap +// RUN: echo "framework module A.Private { umbrella header \"A.h\" }" > %t/sources/module.private.modulemap +// RUN: cp %t/sources/module.modulemap %t/build/module.modulemap +// RUN: cp %t/sources/module.private.modulemap %t/build/module.private.modulemap + +// RUN: sed -e "s:DUMMY_DIR:%t:g" %S/Inputs/all-product-headers.yaml > %t/build/all-product-headers.yaml +// RUN: %clang_cc1 -fsyntax-only -ivfsoverlay %t/build/all-product-headers.yaml -F%t/build -fmodules -fimplicit-module-maps -fmodules-cache-path=tmp -x objective-c %s -verify + +// expected-no-diagnostics +#import