diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index a7d6a068fe2d0..6b1fcac75ac2b 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -623,7 +623,7 @@ static std::error_code collectModuleHeaderIncludes( llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative); llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); - SmallVector, 8> Headers; + SmallVector, 8> HeaderPaths; for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End; Dir != End && !EC; Dir.increment(EC)) { // Check whether this entry has an extension typically associated with @@ -633,17 +633,6 @@ static std::error_code collectModuleHeaderIncludes( .Default(false)) continue; - auto Header = FileMgr.getOptionalFileRef(Dir->path()); - // FIXME: This shouldn't happen unless there is a file system race. Is - // that worth diagnosing? - if (!Header) - continue; - - // If this header is marked 'unavailable' in this module, don't include - // it. - if (ModMap.isHeaderUnavailableInModule(*Header, Module)) - continue; - // Compute the relative path from the directory to this file. SmallVector Components; auto PathIt = llvm::sys::path::rbegin(Dir->path()); @@ -655,20 +644,33 @@ static std::error_code collectModuleHeaderIncludes( ++It) llvm::sys::path::append(RelativeHeader, *It); - std::string RelName = RelativeHeader.c_str(); - Headers.push_back(std::make_pair(RelName, *Header)); + HeaderPaths.push_back( + std::make_pair(Dir->path().str(), RelativeHeader.c_str())); } if (EC) return EC; // Sort header paths and make the header inclusion order deterministic - // across different OSs and filesystems. - llvm::sort(Headers, llvm::less_first()); - for (auto &H : Headers) { + // across different OSs and filesystems. As the header search table + // serialization order depends on the file reference UID, we need to create + // file references in deterministic order too. + llvm::sort(HeaderPaths, llvm::less_first()); + for (auto &[Path, RelPath] : HeaderPaths) { + auto Header = FileMgr.getOptionalFileRef(Path); + // FIXME: This shouldn't happen unless there is a file system race. Is + // that worth diagnosing? + if (!Header) + continue; + + // If this header is marked 'unavailable' in this module, don't include + // it. + if (ModMap.isHeaderUnavailableInModule(*Header, Module)) + continue; + // Include this header as part of the umbrella directory. - Module->addTopHeader(H.second); - addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC); + Module->addTopHeader(*Header); + addHeaderInclude(RelPath, Includes, LangOpts, Module->IsExternC); } } diff --git a/clang/test/Modules/Inputs/umbrella_header_order/module.modulemap b/clang/test/Modules/Inputs/umbrella_header_order/module.modulemap new file mode 100644 index 0000000000000..5c64e33068822 --- /dev/null +++ b/clang/test/Modules/Inputs/umbrella_header_order/module.modulemap @@ -0,0 +1,3 @@ +module x { + umbrella "umbrella" +} \ No newline at end of file diff --git a/clang/test/Modules/Inputs/umbrella_header_order/umbrella/A.h b/clang/test/Modules/Inputs/umbrella_header_order/umbrella/A.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Modules/Inputs/umbrella_header_order/umbrella/B.h b/clang/test/Modules/Inputs/umbrella_header_order/umbrella/B.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Modules/Inputs/umbrella_header_order/umbrella/C.h b/clang/test/Modules/Inputs/umbrella_header_order/umbrella/C.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Modules/Inputs/umbrella_header_order/umbrella/D.h b/clang/test/Modules/Inputs/umbrella_header_order/umbrella/D.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Modules/Inputs/umbrella_header_order/umbrella/E.h b/clang/test/Modules/Inputs/umbrella_header_order/umbrella/E.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Modules/Inputs/umbrella_header_order/umbrella/F.h b/clang/test/Modules/Inputs/umbrella_header_order/umbrella/F.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Modules/umbrella_dir_order.m b/clang/test/Modules/umbrella_dir_order.m new file mode 100644 index 0000000000000..5faa1f940080d --- /dev/null +++ b/clang/test/Modules/umbrella_dir_order.m @@ -0,0 +1,11 @@ +// RUN: cd %S +// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x objective-c -fmodule-name=x -emit-module Inputs/umbrella_header_order/module.modulemap -o %t/mod.pcm +// RUN: llvm-bcanalyzer --dump --disable-histogram %t/mod.pcm | FileCheck %s + +// CHECK: blob data = 'module.modulemap' +// CHECK: blob data = 'umbrella{{[/\\]}}A.h' +// CHECK: blob data = 'umbrella{{[/\\]}}B.h' +// CHECK: blob data = 'umbrella{{[/\\]}}C.h' +// CHECK: blob data = 'umbrella{{[/\\]}}D.h' +// CHECK: blob data = 'umbrella{{[/\\]}}E.h' +// CHECK: blob data = 'umbrella{{[/\\]}}F.h'