Skip to content

Commit 0672a6a

Browse files
committed
[Clang] Fix the header paths in clang::Module for inferred modules.
The `UmbrellaAsWritten` and `NameAsWritten` fields in `clang::Module` are a lie for framework modules. For those they actually are the path to the header or umbrella relative to the `clang::Module::Directory`. The exception to this case is for inferred modules. Here it actually is the name as written, because we print out the module and read it back in when implicitly building modules. This causes a problem when explicitly building an inferred module, as we skip the printing out step. In order to fix this issue this patch adds a new field for the path we want to use in `getInputBufferForModule`. It also makes `NameAsWritten` actually be the name written in the module map file (or that would be, in the case of an inferred module). rdar://58619519
1 parent 1815e24 commit 0672a6a

File tree

8 files changed

+57
-28
lines changed

8 files changed

+57
-28
lines changed

clang/include/clang/Basic/Module.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ class Module {
109109
/// The name of the umbrella entry, as written in the module map.
110110
std::string UmbrellaAsWritten;
111111

112+
// The path to the umbrella entry relative to the root module's \c Directory.
113+
std::string UmbrellaRelativeToRootModuleDirectory;
114+
112115
/// The module through which entities defined in this module will
113116
/// eventually be exposed, for use in "private" modules.
114117
std::string ExportAsModule;
@@ -156,6 +159,7 @@ class Module {
156159
/// file.
157160
struct Header {
158161
std::string NameAsWritten;
162+
std::string PathRelativeToRootModuleDirectory;
159163
const FileEntry *Entry;
160164

161165
explicit operator bool() { return Entry; }
@@ -165,6 +169,7 @@ class Module {
165169
/// file.
166170
struct DirectoryName {
167171
std::string NameAsWritten;
172+
std::string PathRelativeToRootModuleDirectory;
168173
const DirectoryEntry *Entry;
169174

170175
explicit operator bool() { return Entry; }
@@ -491,7 +496,8 @@ class Module {
491496
/// module.
492497
Header getUmbrellaHeader() const {
493498
if (auto *E = Umbrella.dyn_cast<const FileEntry *>())
494-
return Header{UmbrellaAsWritten, E};
499+
return Header{UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
500+
E};
495501
return Header{};
496502
}
497503

clang/include/clang/Lex/ModuleMap.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,12 +653,14 @@ class ModuleMap {
653653
/// Sets the umbrella header of the given module to the given
654654
/// header.
655655
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
656-
Twine NameAsWritten);
656+
Twine NameAsWritten,
657+
Twine PathRelativeToRootModuleDirectory);
657658

658659
/// Sets the umbrella directory of the given module to the given
659660
/// directory.
660661
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
661-
Twine NameAsWritten);
662+
Twine NameAsWritten,
663+
Twine PathRelativeToRootModuleDirectory);
662664

663665
/// Adds this header to the given module.
664666
/// \param Role The role of the header wrt the module.

clang/lib/Basic/Module.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,10 @@ bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
243243

244244
Module::DirectoryName Module::getUmbrellaDir() const {
245245
if (Header U = getUmbrellaHeader())
246-
return {"", U.Entry->getDir()};
246+
return {"", "", U.Entry->getDir()};
247247

248-
return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
248+
return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
249+
Umbrella.dyn_cast<const DirectoryEntry *>()};
249250
}
250251

251252
ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {

clang/lib/Frontend/FrontendAction.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,8 @@ static std::error_code collectModuleHeaderIncludes(
346346
// file relative to the module build directory (the directory containing
347347
// the module map file) so this will find the same file that we found
348348
// while parsing the module map.
349-
addHeaderInclude(H.NameAsWritten, Includes, LangOpts, Module->IsExternC);
349+
addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
350+
Module->IsExternC);
350351
}
351352
}
352353
// Note that Module->PrivateHeaders will not be a TopHeader.
@@ -355,8 +356,8 @@ static std::error_code collectModuleHeaderIncludes(
355356
Module->addTopHeader(UmbrellaHeader.Entry);
356357
if (Module->Parent)
357358
// Include the umbrella header for submodules.
358-
addHeaderInclude(UmbrellaHeader.NameAsWritten, Includes, LangOpts,
359-
Module->IsExternC);
359+
addHeaderInclude(UmbrellaHeader.PathRelativeToRootModuleDirectory,
360+
Includes, LangOpts, Module->IsExternC);
360361
} else if (Module::DirectoryName UmbrellaDir = Module->getUmbrellaDir()) {
361362
// Add all of the headers we find in this subdirectory.
362363
std::error_code EC;
@@ -389,7 +390,8 @@ static std::error_code collectModuleHeaderIncludes(
389390
auto PathIt = llvm::sys::path::rbegin(Dir->path());
390391
for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
391392
Components.push_back(*PathIt);
392-
SmallString<128> RelativeHeader(UmbrellaDir.NameAsWritten);
393+
SmallString<128> RelativeHeader(
394+
UmbrellaDir.PathRelativeToRootModuleDirectory);
393395
for (auto It = Components.rbegin(), End = Components.rend(); It != End;
394396
++It)
395397
llvm::sys::path::append(RelativeHeader, *It);
@@ -519,8 +521,8 @@ getInputBufferForModule(CompilerInstance &CI, Module *M) {
519521
SmallString<256> HeaderContents;
520522
std::error_code Err = std::error_code();
521523
if (Module::Header UmbrellaHeader = M->getUmbrellaHeader())
522-
addHeaderInclude(UmbrellaHeader.NameAsWritten, HeaderContents,
523-
CI.getLangOpts(), M->IsExternC);
524+
addHeaderInclude(UmbrellaHeader.PathRelativeToRootModuleDirectory,
525+
HeaderContents, CI.getLangOpts(), M->IsExternC);
524526
Err = collectModuleHeaderIncludes(
525527
CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
526528
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), M,

clang/lib/Frontend/FrontendActions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ bool GenerateHeaderModuleAction::BeginSourceFileAction(
295295
<< Name;
296296
continue;
297297
}
298-
Headers.push_back({std::string(Name), &FE->getFileEntry()});
298+
Headers.push_back({std::string(Name), std::string(Name), &FE->getFileEntry()});
299299
}
300300
HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers);
301301

clang/lib/Lex/ModuleMap.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,9 @@ void ModuleMap::resolveHeader(Module *Mod,
260260
<< UmbrellaMod->getFullModuleName();
261261
else
262262
// Record this umbrella header.
263-
setUmbrellaHeader(Mod, File, RelativePathName.str());
263+
setUmbrellaHeader(Mod, File, Header.FileName, RelativePathName.str());
264264
} else {
265-
Module::Header H = {std::string(RelativePathName.str()), File};
265+
Module::Header H = {Header.FileName, std::string(RelativePathName.str()), File};
266266
if (Header.Kind == Module::HK_Excluded)
267267
excludeHeader(Mod, H);
268268
else
@@ -305,7 +305,7 @@ bool ModuleMap::resolveAsBuiltinHeader(
305305
return false;
306306

307307
auto Role = headerKindToRole(Header.Kind);
308-
Module::Header H = {std::string(Path.str()), *File};
308+
Module::Header H = {Header.FileName, std::string(Path.str()), *File};
309309
addHeader(Mod, H, Role);
310310
return true;
311311
}
@@ -1027,11 +1027,14 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
10271027
Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
10281028
Result->Directory = FrameworkDir;
10291029

1030+
// Chop off the first framework bit, as that is implied.
1031+
StringRef RelativePath =
1032+
UmbrellaName.str().substr(
1033+
Result->getTopLevelModule()->Directory->getName().size());
1034+
RelativePath = llvm::sys::path::relative_path(RelativePath);
1035+
10301036
// umbrella header "umbrella-header-name"
1031-
//
1032-
// The "Headers/" component of the name is implied because this is
1033-
// a framework module.
1034-
setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h");
1037+
setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", RelativePath);
10351038

10361039
// export *
10371040
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
@@ -1091,6 +1094,9 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
10911094
if (!Result->isSubFramework()) {
10921095
inferFrameworkLink(Result, FrameworkDir, FileMgr);
10931096
}
1097+
1098+
Result->dump();
1099+
llvm::errs() << Result->Directory->getName() << "\n";
10941100

10951101
return Result;
10961102
}
@@ -1111,10 +1117,13 @@ Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
11111117
}
11121118

11131119
void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
1114-
Twine NameAsWritten) {
1120+
Twine NameAsWritten,
1121+
Twine PathRelativeToRootModuleDirectory) {
11151122
Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
11161123
Mod->Umbrella = UmbrellaHeader;
11171124
Mod->UmbrellaAsWritten = NameAsWritten.str();
1125+
Mod->UmbrellaRelativeToRootModuleDirectory =
1126+
PathRelativeToRootModuleDirectory.str();
11181127
UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
11191128

11201129
// Notify callbacks that we just added a new header.
@@ -1123,9 +1132,12 @@ void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
11231132
}
11241133

11251134
void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
1126-
Twine NameAsWritten) {
1135+
Twine NameAsWritten,
1136+
Twine PathRelativeToRootModuleDirectory) {
11271137
Mod->Umbrella = UmbrellaDir;
11281138
Mod->UmbrellaAsWritten = NameAsWritten.str();
1139+
Mod->UmbrellaRelativeToRootModuleDirectory =
1140+
PathRelativeToRootModuleDirectory.str();
11291141
UmbrellaDirs[UmbrellaDir] = Mod;
11301142
}
11311143

@@ -2394,6 +2406,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
23942406
}
23952407

23962408
std::string DirName = std::string(Tok.getString());
2409+
std::string DirNameAsWritten = DirName;
23972410
SourceLocation DirNameLoc = consumeToken();
23982411

23992412
// Check whether we already have an umbrella.
@@ -2435,7 +2448,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
24352448
for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
24362449
I != E && !EC; I.increment(EC)) {
24372450
if (auto FE = SourceMgr.getFileManager().getFile(I->path())) {
2438-
Module::Header Header = {std::string(I->path()), *FE};
2451+
Module::Header Header = {"", std::string(I->path()), *FE};
24392452
Headers.push_back(std::move(Header));
24402453
}
24412454
}
@@ -2456,7 +2469,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
24562469
}
24572470

24582471
// Record this umbrella directory.
2459-
Map.setUmbrellaDir(ActiveModule, Dir, DirName);
2472+
Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
24602473
}
24612474

24622475
/// Parse a module export declaration.

clang/lib/Serialization/ASTReader.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,7 +1919,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
19191919
// FIXME: This is not always the right filename-as-written, but we're not
19201920
// going to use this information to rebuild the module, so it doesn't make
19211921
// a lot of difference.
1922-
Module::Header H = {std::string(key.Filename), *FileMgr.getFile(Filename)};
1922+
Module::Header H = {std::string(key.Filename), "", *FileMgr.getFile(Filename)};
19231923
ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true);
19241924
HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader);
19251925
}
@@ -5548,7 +5548,8 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
55485548
ResolveImportedPath(F, Filename);
55495549
if (auto Umbrella = PP.getFileManager().getFile(Filename)) {
55505550
if (!CurrentModule->getUmbrellaHeader())
5551-
ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob);
5551+
// FIXME: NameAsWritten
5552+
ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob, "");
55525553
else if (CurrentModule->getUmbrellaHeader().Entry != *Umbrella) {
55535554
if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
55545555
Error("mismatched umbrella headers in submodule");
@@ -5581,7 +5582,8 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
55815582
ResolveImportedPath(F, Dirname);
55825583
if (auto Umbrella = PP.getFileManager().getDirectory(Dirname)) {
55835584
if (!CurrentModule->getUmbrellaDir())
5584-
ModMap.setUmbrellaDir(CurrentModule, *Umbrella, Blob);
5585+
// FIXME: NameAsWritten
5586+
ModMap.setUmbrellaDir(CurrentModule, *Umbrella, Blob, "");
55855587
else if (CurrentModule->getUmbrellaDir().Entry != *Umbrella) {
55865588
if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
55875589
Error("mismatched umbrella directories in submodule");

clang/test/ClangScanDeps/modules-inferred-explicit-build.m

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
// RUN: -mode preprocess-minimized-sources -format experimental-full > %t.db
1010
// RUN: %S/module-deps-to-rsp.py %t.db --module-name=Inferred > %t.inferred.rsp
1111
// RUN: %S/module-deps-to-rsp.py %t.db --tu-index=0 > %t.tu.rsp
12-
// RUN: not %clang_cc1 -E %t.dir/modules_cdb_input.cpp -F%S/Inputs/frameworks -fmodules -fimplicit-module-maps @%t.inferred.rsp 2>&1 | grep "'Inferred.h' file not found"
13-
// RUN: not %clang_cc1 -E %t.dir/modules_cdb_input.cpp -F%S/Inputs/frameworks -fmodules -fimplicit-module-maps @%t.tu.rsp
12+
// RUN: %clang_cc1 -x objective-c -E %t.dir/modules_cdb_input.cpp \
13+
// RUN: -F%S/Inputs/frameworks -fmodules -fimplicit-module-maps \
14+
// RUN: @%t.inferred.rsp
15+
// RUN: %clang_cc1 -x objective-c -E %t.dir/modules_cdb_input.cpp \
16+
// RUN: -F%S/Inputs/frameworks -fmodules -fimplicit-module-maps @%t.tu.rsp
1417

1518
#include <Inferred/Inferred.h>
1619

0 commit comments

Comments
 (0)