jansvoboda11 updated this revision to Diff 339187.
jansvoboda11 added a comment.
Rebase on top of D100942 <https://reviews.llvm.org/D100942>
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D100934/new/
https://reviews.llvm.org/D100934
Files:
clang/include/clang/Basic/Module.h
clang/include/clang/Lex/ModuleMap.h
clang/lib/Basic/Module.cpp
clang/lib/Frontend/FrontendAction.cpp
clang/lib/Frontend/FrontendActions.cpp
clang/lib/Lex/ModuleMap.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
clang/test/ClangScanDeps/Inputs/frameworks/Inferred.framework/Frameworks/Sub.framework/Headers/Sub.h
clang/test/ClangScanDeps/Inputs/frameworks/Inferred.framework/Headers/Inferred.h
clang/test/ClangScanDeps/Inputs/frameworks/System.framework/Headers/System.h
clang/test/ClangScanDeps/Inputs/frameworks/System.framework/Modules/module.modulemap
clang/test/ClangScanDeps/Inputs/frameworks/module.modulemap
clang/test/ClangScanDeps/Inputs/modules_inferred_cdb.json
clang/test/ClangScanDeps/module-deps-to-rsp.py
clang/test/ClangScanDeps/modules-full.cpp
clang/test/ClangScanDeps/modules-inferred-explicit-build.m
clang/test/ClangScanDeps/modules-inferred.m
Index: clang/test/ClangScanDeps/modules-inferred.m
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/modules-inferred.m
@@ -0,0 +1,61 @@
+// RUN: rm -rf %t.dir
+// RUN: rm -rf %t.cdb
+// RUN: mkdir -p %t.dir
+// RUN: cp %s %t.dir/modules_cdb_input.cpp
+// RUN: sed -e "s|DIR|%/t.dir|g" -e "s|FRAMEWORKS|%S/Inputs/frameworks|g" \
+// RUN: %S/Inputs/modules_inferred_cdb.json > %t.cdb
+//
+// RUN: echo -%t.dir > %t.result
+// RUN: echo -%S >> %t.result
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 -format experimental-full \
+// RUN: -mode preprocess-minimized-sources >> %t.result
+// RUN: cat %t.result | sed 's/\\/\//g' | FileCheck --check-prefixes=CHECK %s
+
+#include <Inferred/Inferred.h>
+
+inferred a = 0;
+
+// CHECK: -[[PREFIX:.*]]
+// CHECK-NEXT: -[[SOURCEDIR:.*]]
+// CHECK-NEXT: {
+// CHECK-NEXT: "modules": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "clang-module-deps": [],
+// CHECK-NEXT: "clang-modulemap-file": "[[SOURCEDIR]]/Inputs/frameworks/module.modulemap",
+// CHECK-NEXT: "command-line": [
+// CHECK-NEXT: "-cc1",
+// CHECK: "-emit-module",
+// CHECK: "-fmodule-name=Inferred",
+// CHECK: "-fno-implicit-modules",
+// CHECK: ],
+// CHECK-NEXT: "context-hash": "[[CONTEXT_HASH_H1:[A-Z0-9]+]]",
+// CHECK-NEXT: "file-deps": [
+// CHECK-NEXT: "[[SOURCEDIR]]/Inputs/frameworks/Inferred.framework/Frameworks/Sub.framework/Headers/Sub.h",
+// CHECK-NEXT: "[[SOURCEDIR]]/Inputs/frameworks/Inferred.framework/Headers/Inferred.h",
+// CHECK-NEXT: "[[SOURCEDIR]]/Inputs/frameworks/module.modulemap"
+// CHECK-NEXT: ],
+// CHECK-NEXT: "name": "Inferred"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK-NEXT: "translation-units": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "clang-context-hash": "[[CONTEXT_HASH_H1]]",
+// CHECK-NEXT: "clang-module-deps": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "context-hash": "[[CONTEXT_HASH_H1]]",
+// CHECK-NEXT: "module-name": "Inferred"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK-NEXT: "command-line": [
+// CHECK-NEXT: "-fno-implicit-modules",
+// CHECK-NEXT: "-fno-implicit-module-maps",
+// CHECK-NEXT: "-fmodule-file=[[PREFIX]]/module-cache/[[CONTEXT_HASH_H1]]/Inferred-{{[A-Z0-9]+}}.pcm",
+// CHECK-NEXT: "-fmodule-map-file=[[SOURCEDIR]]/Inputs/frameworks/module.modulemap"
+// CHECK-NEXT: ],
+// CHECK-NEXT: "file-deps": [
+// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
+// CHECK-NEXT: ],
+// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
Index: clang/test/ClangScanDeps/modules-inferred-explicit-build.m
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/modules-inferred-explicit-build.m
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t.dir
+// RUN: rm -rf %t.cdb
+// RUN: mkdir -p %t.dir
+// RUN: cp %s %t.dir/modules_cdb_input.cpp
+// RUN: sed -e "s|DIR|%/t.dir|g" -e "s|FRAMEWORKS|%/S/Inputs/frameworks|g" -e "s|-E|-x objective-c -E|g" \
+// RUN: %S/Inputs/modules_inferred_cdb.json > %t.cdb
+//
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 -format experimental-full \
+// RUN: -mode preprocess-minimized-sources > %t.db
+// RUN: %S/module-deps-to-rsp.py %t.db --module-name=Inferred > %t.inferred.rsp
+// RUN: %S/module-deps-to-rsp.py %t.db --module-name=System > %t.system.rsp
+// RUN: %S/module-deps-to-rsp.py %t.db --tu-index=0 > %t.tu.rsp
+// RUN: %clang @%t.inferred.rsp -pedantic -Werror
+// RUN: %clang @%t.system.rsp -pedantic -Werror
+// RUN: %clang -x objective-c -fsyntax-only %t.dir/modules_cdb_input.cpp \
+// RUN: -F%S/Inputs/frameworks -fmodules -fimplicit-module-maps \
+// RUN: -pedantic -Werror @%t.tu.rsp
+
+#include <Inferred/Inferred.h>
+#include <System/System.h>
+
+inferred a = bigger_than_int;
Index: clang/test/ClangScanDeps/modules-full.cpp
===================================================================
--- clang/test/ClangScanDeps/modules-full.cpp
+++ clang/test/ClangScanDeps/modules-full.cpp
@@ -40,7 +40,6 @@
// CHECK-NEXT: "-cc1",
// CHECK: "-fmodule-map-file=[[PREFIX]]/Inputs/module.modulemap",
// CHECK: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[CONTEXT_HASH_H1]]/header2-{{[A-Z0-9]+}}.pcm",
-// CHECK-NOT: "-fimplicit-module-maps",
// CHECK: "-fno-implicit-modules",
// CHECK: ],
// CHECK-NEXT: "context-hash": "[[CONTEXT_HASH_H1]]",
@@ -55,7 +54,6 @@
// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/Inputs/module.modulemap",
// CHECK-NEXT: "command-line": [
// CHECK-NEXT: "-cc1",
-// CHECK-NOT: "-fimplicit-module-maps",
// CHECK: "-fno-implicit-modules",
// CHECK: ],
// CHECK-NEXT: "context-hash": "[[CONTEXT_HASH_H2:[A-Z0-9]+]]",
@@ -70,7 +68,6 @@
// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/Inputs/module.modulemap",
// CHECK-NEXT: "command-line": [
// CHECK-NEXT: "-cc1",
-// CHECK-NOT: "-fimplicit-module-maps",
// CHECK: "-fno-implicit-modules",
// CHECK: ],
// CHECK-NEXT: "context-hash": "[[CONTEXT_HASH_H1]]",
Index: clang/test/ClangScanDeps/module-deps-to-rsp.py
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/module-deps-to-rsp.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+import argparse
+import json
+import sys
+
+class ModuleNotFoundError(Exception):
+ def __init__(self, module_name):
+ self.module_name = module_name
+
+class FullDeps:
+ def __init__(self):
+ self.modules = dict()
+ self.translation_units = str()
+
+def getModulePathArgs(modules, full_deps):
+ cmd = []
+ for md in modules:
+ m = full_deps.modules[md['module-name'] + '-' + md['context-hash']]
+ cmd += [u'-fmodule-map-file=' + m['clang-modulemap-file']]
+ cmd += [u'-fmodule-file=' + md['module-name'] + '-' + md['context-hash'] + '.pcm']
+ return cmd
+
+def getCommandLineForModule(module_name, full_deps):
+ for m in full_deps.modules.values():
+ if m['name'] == module_name:
+ module = m
+ break
+ else:
+ raise ModuleNotFoundError(module_name)
+
+ cmd = m['command-line']
+ cmd += getModulePathArgs(m['clang-module-deps'], full_deps)
+ cmd += [u'-o', m['name'] + '-' + m['context-hash'] + '.pcm']
+ cmd += [m['clang-modulemap-file']]
+
+ return cmd
+
+def getCommandLineForTU(tu, full_deps):
+ cmd = tu['command-line']
+ cmd = [a for a in cmd if not (a.startswith('-fmodule-map-file=') or a.startswith('-fmodule-file='))]
+ cmd += getModulePathArgs(tu['clang-module-deps'], full_deps)
+ return cmd
+
+def parseFullDeps(json):
+ ret = FullDeps()
+ for m in json['modules']:
+ ret.modules[m['name'] + '-' + m['context-hash']] = m
+ ret.translation_units = json['translation-units']
+ return ret
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("full_deps_file", help="Path to the full dependencies json file",
+ type=str)
+ action = parser.add_mutually_exclusive_group(required=True)
+ action.add_argument("--module-name", help="The name of the module to get arguments for",
+ type=str)
+ action.add_argument("--tu-index", help="The index of the translation unit to get arguments for",
+ type=int)
+ args = parser.parse_args()
+
+ full_deps = parseFullDeps(json.load(open(args.full_deps_file, 'r')))
+
+ try:
+ if args.module_name:
+ print(" ".join(getCommandLineForModule(args.module_name, full_deps)))
+
+ elif args.tu_index != None:
+ print(" ".join(getCommandLineForTU(full_deps.translation_units[args.tu_index], full_deps)))
+ except:
+ print("Unexpected error:", sys.exc_info()[0])
+ raise
+
+if __name__ == '__main__':
+ main()
Index: clang/test/ClangScanDeps/Inputs/modules_inferred_cdb.json
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/modules_inferred_cdb.json
@@ -0,0 +1,7 @@
+[
+{
+ "directory": "DIR",
+ "command": "clang -E DIR/modules_cdb_input.cpp -FFRAMEWORKS -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -pedantic -Werror",
+ "file": "DIR/modules_cdb_input.cpp"
+}
+]
Index: clang/test/ClangScanDeps/Inputs/frameworks/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/frameworks/module.modulemap
@@ -0,0 +1 @@
+framework module * {}
Index: clang/test/ClangScanDeps/Inputs/frameworks/System.framework/Modules/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/frameworks/System.framework/Modules/module.modulemap
@@ -0,0 +1,3 @@
+framework module System [system] {
+ umbrella header "System.h"
+}
Index: clang/test/ClangScanDeps/Inputs/frameworks/System.framework/Headers/System.h
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/frameworks/System.framework/Headers/System.h
@@ -0,0 +1 @@
+enum { bigger_than_int = 0x80000000 };
Index: clang/test/ClangScanDeps/Inputs/frameworks/Inferred.framework/Headers/Inferred.h
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/frameworks/Inferred.framework/Headers/Inferred.h
@@ -0,0 +1 @@
+typedef int inferred;
Index: clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -32,7 +32,6 @@
CI.getFrontendOpts().IsSystemModule = Deps.IsSystem;
CI.getLangOpts()->ImplicitModules = false;
- CI.getHeaderSearchOpts().ImplicitModuleMaps = false;
return CI;
}
@@ -171,7 +170,7 @@
const FileEntry *ModuleMap = Instance.getPreprocessor()
.getHeaderSearchInfo()
.getModuleMap()
- .getContainingModuleMapFile(M);
+ .getModuleMapFileForUniquing(M);
MD.Invocation = Instance.getInvocationPtr();
MD.ClangModuleMapFile = std::string(ModuleMap ? ModuleMap->getName() : "");
@@ -183,6 +182,15 @@
MDC.Instance.getASTReader()->getModuleManager().lookup(M->getASTFile());
MDC.Instance.getASTReader()->visitInputFiles(
*MF, true, true, [&](const serialization::InputFile &IF, bool isSystem) {
+ // __inferred_module.map is the result of the way in which an implicit
+ // module build handles inferred modules. It adds an overlay VFS with
+ // this file in the proper directory and relies on the rest of Clang to
+ // handle it like normal. With explicitly built modules we don't need
+ // to play VFS tricks, so replace it with the correct module map.
+ if (IF.getFile()->getName().endswith("__inferred_module.map")) {
+ MD.FileDeps.insert(ModuleMap->getName());
+ return;
+ }
MD.FileDeps.insert(IF.getFile()->getName());
});
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1924,7 +1924,8 @@
// FIXME: This is not always the right filename-as-written, but we're not
// going to use this information to rebuild the module, so it doesn't make
// a lot of difference.
- Module::Header H = {std::string(key.Filename), *FileMgr.getFile(Filename)};
+ Module::Header H = {std::string(key.Filename), "",
+ *FileMgr.getFile(Filename)};
ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true);
HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader);
}
@@ -5618,7 +5619,8 @@
ResolveImportedPath(F, Filename);
if (auto Umbrella = PP.getFileManager().getFile(Filename)) {
if (!CurrentModule->getUmbrellaHeader())
- ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob);
+ // FIXME: NameAsWritten
+ ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob, "");
else if (CurrentModule->getUmbrellaHeader().Entry != *Umbrella) {
if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
Error("mismatched umbrella headers in submodule");
@@ -5651,7 +5653,8 @@
ResolveImportedPath(F, Dirname);
if (auto Umbrella = PP.getFileManager().getDirectory(Dirname)) {
if (!CurrentModule->getUmbrellaDir())
- ModMap.setUmbrellaDir(CurrentModule, *Umbrella, Blob);
+ // FIXME: NameAsWritten
+ ModMap.setUmbrellaDir(CurrentModule, *Umbrella, Blob, "");
else if (CurrentModule->getUmbrellaDir().Entry != *Umbrella) {
if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
Error("mismatched umbrella directories in submodule");
Index: clang/lib/Lex/ModuleMap.cpp
===================================================================
--- clang/lib/Lex/ModuleMap.cpp
+++ clang/lib/Lex/ModuleMap.cpp
@@ -260,9 +260,10 @@
<< 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 @@
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 @@
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));
@@ -1122,10 +1125,13 @@
}
void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
- Twine NameAsWritten) {
+ Twine NameAsWritten,
+ 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::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
- Twine NameAsWritten) {
+ Twine NameAsWritten,
+ Twine PathRelativeToRootModuleDirectory) {
Mod->Umbrella = UmbrellaDir;
Mod->UmbrellaAsWritten = NameAsWritten.str();
+ Mod->UmbrellaRelativeToRootModuleDirectory =
+ PathRelativeToRootModuleDirectory.str();
UmbrellaDirs[UmbrellaDir] = Mod;
}
@@ -2405,6 +2414,7 @@
}
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 @@
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 @@
}
// Record this umbrella directory.
- Map.setUmbrellaDir(ActiveModule, Dir, DirName);
+ Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
}
/// Parse a module export declaration.
Index: clang/lib/Frontend/FrontendActions.cpp
===================================================================
--- clang/lib/Frontend/FrontendActions.cpp
+++ clang/lib/Frontend/FrontendActions.cpp
@@ -297,7 +297,8 @@
<< Name;
continue;
}
- Headers.push_back({std::string(Name), &FE->getFileEntry()});
+ Headers.push_back(
+ {std::string(Name), std::string(Name), &FE->getFileEntry()});
}
HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers);
Index: clang/lib/Frontend/FrontendAction.cpp
===================================================================
--- clang/lib/Frontend/FrontendAction.cpp
+++ clang/lib/Frontend/FrontendAction.cpp
@@ -342,7 +342,8 @@
// file relative to the module build directory (the directory containing
// the module map file) so this will find the same file that we found
// while parsing the module map.
- addHeaderInclude(H.NameAsWritten, Includes, LangOpts, Module->IsExternC);
+ addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
+ Module->IsExternC);
}
}
// Note that Module->PrivateHeaders will not be a TopHeader.
@@ -351,8 +352,8 @@
Module->addTopHeader(UmbrellaHeader.Entry);
if (Module->Parent)
// Include the umbrella header for submodules.
- addHeaderInclude(UmbrellaHeader.NameAsWritten, Includes, LangOpts,
- Module->IsExternC);
+ addHeaderInclude(UmbrellaHeader.PathRelativeToRootModuleDirectory,
+ Includes, LangOpts, Module->IsExternC);
} else if (Module::DirectoryName UmbrellaDir = Module->getUmbrellaDir()) {
// Add all of the headers we find in this subdirectory.
std::error_code EC;
@@ -386,7 +387,8 @@
auto PathIt = llvm::sys::path::rbegin(Dir->path());
for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
Components.push_back(*PathIt);
- SmallString<128> RelativeHeader(UmbrellaDir.NameAsWritten);
+ SmallString<128> RelativeHeader(
+ UmbrellaDir.PathRelativeToRootModuleDirectory);
for (auto It = Components.rbegin(), End = Components.rend(); It != End;
++It)
llvm::sys::path::append(RelativeHeader, *It);
@@ -470,7 +472,7 @@
// Dig out the module definition.
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
Module *M = HS.lookupModule(CI.getLangOpts().CurrentModule,
- /*AllowSearch=*/false);
+ /*AllowSearch=*/true);
if (!M) {
CI.getDiagnostics().Report(diag::err_missing_module)
<< CI.getLangOpts().CurrentModule << ModuleMapFilename;
@@ -528,8 +530,8 @@
SmallString<256> HeaderContents;
std::error_code Err = std::error_code();
if (Module::Header UmbrellaHeader = M->getUmbrellaHeader())
- addHeaderInclude(UmbrellaHeader.NameAsWritten, HeaderContents,
- CI.getLangOpts(), M->IsExternC);
+ addHeaderInclude(UmbrellaHeader.PathRelativeToRootModuleDirectory,
+ HeaderContents, CI.getLangOpts(), M->IsExternC);
Err = collectModuleHeaderIncludes(
CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), M,
Index: clang/lib/Basic/Module.cpp
===================================================================
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -245,9 +245,10 @@
Module::DirectoryName Module::getUmbrellaDir() const {
if (Header U = getUmbrellaHeader())
- return {"", U.Entry->getDir()};
+ return {"", "", U.Entry->getDir()};
- return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
+ return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
+ Umbrella.dyn_cast<const DirectoryEntry *>()};
}
void Module::addTopHeader(const FileEntry *File) {
Index: clang/include/clang/Lex/ModuleMap.h
===================================================================
--- clang/include/clang/Lex/ModuleMap.h
+++ clang/include/clang/Lex/ModuleMap.h
@@ -649,12 +649,14 @@
/// Sets the umbrella header of the given module to the given
/// header.
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
- Twine NameAsWritten);
+ Twine NameAsWritten,
+ Twine PathRelativeToRootModuleDirectory);
/// Sets the umbrella directory of the given module to the given
/// directory.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
- Twine NameAsWritten);
+ Twine NameAsWritten,
+ Twine PathRelativeToRootModuleDirectory);
/// Adds this header to the given module.
/// \param Role The role of the header wrt the module.
Index: clang/include/clang/Basic/Module.h
===================================================================
--- clang/include/clang/Basic/Module.h
+++ clang/include/clang/Basic/Module.h
@@ -141,6 +141,9 @@
/// The name of the umbrella entry, as written in the module map.
std::string UmbrellaAsWritten;
+ // The path to the umbrella entry relative to the root module's \c Directory.
+ std::string UmbrellaRelativeToRootModuleDirectory;
+
/// The module through which entities defined in this module will
/// eventually be exposed, for use in "private" modules.
std::string ExportAsModule;
@@ -188,6 +191,7 @@
/// file.
struct Header {
std::string NameAsWritten;
+ std::string PathRelativeToRootModuleDirectory;
const FileEntry *Entry;
explicit operator bool() { return Entry; }
@@ -197,6 +201,7 @@
/// file.
struct DirectoryName {
std::string NameAsWritten;
+ std::string PathRelativeToRootModuleDirectory;
const DirectoryEntry *Entry;
explicit operator bool() { return Entry; }
@@ -545,7 +550,8 @@
/// module.
Header getUmbrellaHeader() const {
if (auto *FE = Umbrella.dyn_cast<const FileEntry *>())
- return Header{UmbrellaAsWritten, FE};
+ return Header{UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
+ FE};
return Header{};
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits