Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions clang/lib/Frontend/FrontendAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ static std::error_code collectModuleHeaderIncludes(
llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);

llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
SmallVector<std::pair<std::string, FileEntryRef>, 8> Headers;
SmallVector<std::pair<std::string, std::string>, 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
Expand All @@ -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<StringRef, 16> Components;
auto PathIt = llvm::sys::path::rbegin(Dir->path());
Expand All @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module x {
umbrella "umbrella"
}
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
11 changes: 11 additions & 0 deletions clang/test/Modules/umbrella_dir_order.m
Original file line number Diff line number Diff line change
@@ -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: <INPUT_FILE abbrevid=4 op0=1 op1=36 op2=0 op3=0 op4=0 op5=1 op6=1 op7=16/> blob data = 'module.modulemap'
// CHECK: <INPUT_FILE abbrevid=4 op0=2 op1=0 op2=0 op3=0 op4=0 op5=0 op6=0 op7=12/> blob data = 'umbrella{{[/\\]}}A.h'
// CHECK: <INPUT_FILE abbrevid=4 op0=3 op1=0 op2=0 op3=0 op4=0 op5=0 op6=0 op7=12/> blob data = 'umbrella{{[/\\]}}B.h'
// CHECK: <INPUT_FILE abbrevid=4 op0=4 op1=0 op2=0 op3=0 op4=0 op5=0 op6=0 op7=12/> blob data = 'umbrella{{[/\\]}}C.h'
// CHECK: <INPUT_FILE abbrevid=4 op0=5 op1=0 op2=0 op3=0 op4=0 op5=0 op6=0 op7=12/> blob data = 'umbrella{{[/\\]}}D.h'
// CHECK: <INPUT_FILE abbrevid=4 op0=6 op1=0 op2=0 op3=0 op4=0 op5=0 op6=0 op7=12/> blob data = 'umbrella{{[/\\]}}E.h'
// CHECK: <INPUT_FILE abbrevid=4 op0=7 op1=0 op2=0 op3=0 op4=0 op5=0 op6=0 op7=12/> blob data = 'umbrella{{[/\\]}}F.h'
Loading