aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorMichael Spencer <bigcheesegs@gmail.com>2021-05-17 09:40:29 +0200
committerJan Svoboda <jan_svoboda@apple.com>2021-05-17 10:40:51 +0200
commitd3676d4b666ead794fc58bbc7e07aa406dcf487a (patch)
treee6bd8757bf390c926ef87571afeee9be90764fcd /clang/lib/Lex/ModuleMap.cpp
parent65936b952964d257c387ce2a7a9362a2ce297a63 (diff)
downloadllvm-d3676d4b666ead794fc58bbc7e07aa406dcf487a.zip
llvm-d3676d4b666ead794fc58bbc7e07aa406dcf487a.tar.gz
llvm-d3676d4b666ead794fc58bbc7e07aa406dcf487a.tar.bz2
[clang][modules] Build inferred modules
This patch enables explicitly building inferred modules. Effectively a cherry-pick of https://github.com/apple/llvm-project/pull/699 authored by @Bigcheese with libclang and dependency scanner changes omitted. Contains the following changes: 1. [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). 2. [Clang] Allow explicitly building an inferred module. * Building the actual module still fails, but make sure it fails for the right reason. Split from D100934. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D102491
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--clang/lib/Lex/ModuleMap.cpp34
1 files changed, 22 insertions, 12 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 28dd7ed..2c0038d 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -260,9 +260,10 @@ void ModuleMap::resolveHeader(Module *Mod,
<< UmbrellaMod->getFullModuleName();
else
// Record this umbrella header.
- setUmbrellaHeader(Mod, *File, RelativePathName.str());
+ setUmbrellaHeader(Mod, *File, Header.FileName, RelativePathName.str());
} else {
- Module::Header H = {std::string(RelativePathName.str()), *File};
+ Module::Header H = {Header.FileName, std::string(RelativePathName.str()),
+ *File};
if (Header.Kind == Module::HK_Excluded)
excludeHeader(Mod, H);
else
@@ -305,7 +306,7 @@ bool ModuleMap::resolveAsBuiltinHeader(
return false;
auto Role = headerKindToRole(Header.Kind);
- Module::Header H = {std::string(Path.str()), *File};
+ Module::Header H = {Header.FileName, std::string(Path.str()), *File};
addHeader(Mod, H, Role);
return true;
}
@@ -1038,11 +1039,13 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
Result->Directory = FrameworkDir;
+ // Chop off the first framework bit, as that is implied.
+ StringRef RelativePath = UmbrellaName.str().substr(
+ Result->getTopLevelModule()->Directory->getName().size());
+ RelativePath = llvm::sys::path::relative_path(RelativePath);
+
// umbrella header "umbrella-header-name"
- //
- // The "Headers/" component of the name is implied because this is
- // a framework module.
- setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h");
+ setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", RelativePath);
// export *
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
@@ -1121,11 +1124,14 @@ Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
return Result;
}
-void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
- Twine NameAsWritten) {
+void ModuleMap::setUmbrellaHeader(
+ Module *Mod, const FileEntry *UmbrellaHeader, const Twine &NameAsWritten,
+ const Twine &PathRelativeToRootModuleDirectory) {
Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Mod->Umbrella = UmbrellaHeader;
Mod->UmbrellaAsWritten = NameAsWritten.str();
+ Mod->UmbrellaRelativeToRootModuleDirectory =
+ PathRelativeToRootModuleDirectory.str();
UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
// Notify callbacks that we just added a new header.
@@ -1134,9 +1140,12 @@ void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
}
void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
- Twine NameAsWritten) {
+ const Twine &NameAsWritten,
+ const Twine &PathRelativeToRootModuleDirectory) {
Mod->Umbrella = UmbrellaDir;
Mod->UmbrellaAsWritten = NameAsWritten.str();
+ Mod->UmbrellaRelativeToRootModuleDirectory =
+ PathRelativeToRootModuleDirectory.str();
UmbrellaDirs[UmbrellaDir] = Mod;
}
@@ -2405,6 +2414,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
}
std::string DirName = std::string(Tok.getString());
+ std::string DirNameAsWritten = DirName;
SourceLocation DirNameLoc = consumeToken();
// Check whether we already have an umbrella.
@@ -2446,7 +2456,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
I != E && !EC; I.increment(EC)) {
if (auto FE = SourceMgr.getFileManager().getFile(I->path())) {
- Module::Header Header = {std::string(I->path()), *FE};
+ Module::Header Header = {"", std::string(I->path()), *FE};
Headers.push_back(std::move(Header));
}
}
@@ -2467,7 +2477,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
}
// Record this umbrella directory.
- Map.setUmbrellaDir(ActiveModule, Dir, DirName);
+ Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
}
/// Parse a module export declaration.