aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-02 21:17:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:34:50 +0000
commit06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch)
tree62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
parentcf037972ea8863e2bab7461d77345367d2c1e054 (diff)
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp281
1 files changed, 155 insertions, 126 deletions
diff --git a/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp b/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
index ee2cca4e0814..5a1b0a918caa 100644
--- a/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
+++ b/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
@@ -181,7 +181,7 @@ OptionalFileEntryRef ModuleMap::findHeader(
Module *M, const Module::UnresolvedHeaderDirective &Header,
SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {
// Search for the header file within the module's home directory.
- auto *Directory = M->Directory;
+ auto Directory = M->Directory;
SmallString<128> FullPathName(Directory->getName());
auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef {
@@ -266,7 +266,8 @@ void ModuleMap::resolveHeader(Module *Mod,
<< UmbrellaMod->getFullModuleName();
else
// Record this umbrella header.
- setUmbrellaHeader(Mod, *File, Header.FileName, RelativePathName.str());
+ setUmbrellaHeaderAsWritten(Mod, *File, Header.FileName,
+ RelativePathName.str());
} else {
Module::Header H = {Header.FileName, std::string(RelativePathName.str()),
*File};
@@ -408,29 +409,27 @@ ModuleMap::findKnownHeader(const FileEntry *File) {
return Known;
}
-ModuleMap::KnownHeader
-ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
- SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
+ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs(
+ FileEntryRef File, SmallVectorImpl<DirectoryEntryRef> &IntermediateDirs) {
if (UmbrellaDirs.empty())
return {};
- const DirectoryEntry *Dir = File->getDir();
- assert(Dir && "file in no directory");
+ OptionalDirectoryEntryRef Dir = File.getDir();
// Note: as an egregious but useful hack we use the real path here, because
// frameworks moving from top-level frameworks to embedded frameworks tend
// to be symlinked from the top-level location to the embedded location,
// and we need to resolve lookups as if we had found the embedded location.
- StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
+ StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);
// Keep walking up the directory hierarchy, looking for a directory with
// an umbrella header.
do {
- auto KnownDir = UmbrellaDirs.find(Dir);
+ auto KnownDir = UmbrellaDirs.find(*Dir);
if (KnownDir != UmbrellaDirs.end())
return KnownHeader(KnownDir->second, NormalHeader);
- IntermediateDirs.push_back(Dir);
+ IntermediateDirs.push_back(*Dir);
// Retrieve our parent path.
DirName = llvm::sys::path::parent_path(DirName);
@@ -438,10 +437,7 @@ ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
break;
// Resolve the parent path to a directory entry.
- if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName))
- Dir = *DirEntry;
- else
- Dir = nullptr;
+ Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
} while (Dir);
return {};
}
@@ -528,8 +524,9 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
// We have found a module, but we don't use it.
if (NotUsed) {
- Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
- << RequestingModule->getTopLevelModule()->Name << Filename;
+ Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
+ << RequestingModule->getTopLevelModule()->Name << Filename
+ << NotUsed->Name;
return;
}
@@ -580,7 +577,7 @@ static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
return false;
}
-ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
+ModuleMap::KnownHeader ModuleMap::findModuleForHeader(FileEntryRef File,
bool AllowTextual,
bool AllowExcluded) {
auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
@@ -610,10 +607,10 @@ ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
}
ModuleMap::KnownHeader
-ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
+ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
assert(!Headers.count(File) && "already have a module for this header");
- SmallVector<const DirectoryEntry *, 2> SkippedDirs;
+ SmallVector<DirectoryEntryRef, 2> SkippedDirs;
KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
if (H) {
Module *Result = H.getModule();
@@ -621,7 +618,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
// Search up the module stack until we find a module with an umbrella
// directory.
Module *UmbrellaModule = Result;
- while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
+ while (!UmbrellaModule->getEffectiveUmbrellaDir() && UmbrellaModule->Parent)
UmbrellaModule = UmbrellaModule->Parent;
if (UmbrellaModule->InferSubmodules) {
@@ -633,11 +630,11 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
// the actual header is located.
bool Explicit = UmbrellaModule->InferExplicitSubmodules;
- for (const DirectoryEntry *SkippedDir : llvm::reverse(SkippedDirs)) {
+ for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
// Find or create the module that corresponds to this directory name.
SmallString<32> NameBuf;
StringRef Name = sanitizeFilenameAsIdentifier(
- llvm::sys::path::stem(SkippedDir->getName()), NameBuf);
+ llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Explicit).first;
InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
@@ -655,7 +652,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
// Infer a submodule with the same name as this header file.
SmallString<32> NameBuf;
StringRef Name = sanitizeFilenameAsIdentifier(
- llvm::sys::path::stem(File->getName()), NameBuf);
+ llvm::sys::path::stem(File.getName()), NameBuf);
Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Explicit).first;
InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
@@ -682,7 +679,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
}
ArrayRef<ModuleMap::KnownHeader>
-ModuleMap::findAllModulesForHeader(const FileEntry *File) {
+ModuleMap::findAllModulesForHeader(FileEntryRef File) {
HeadersMap::iterator Known = findKnownHeader(File);
if (Known != Headers.end())
return Known->second;
@@ -703,13 +700,12 @@ ModuleMap::findResolvedModulesForHeader(const FileEntry *File) const {
return It->second;
}
-bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
+bool ModuleMap::isHeaderInUnavailableModule(FileEntryRef Header) const {
return isHeaderUnavailableInModule(Header, nullptr);
}
-bool
-ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
- const Module *RequestingModule) const {
+bool ModuleMap::isHeaderUnavailableInModule(
+ FileEntryRef Header, const Module *RequestingModule) const {
resolveHeaderDirectives(Header);
HeadersMap::const_iterator Known = Headers.find(Header);
if (Known != Headers.end()) {
@@ -737,8 +733,8 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
return true;
}
- const DirectoryEntry *Dir = Header->getDir();
- SmallVector<const DirectoryEntry *, 2> SkippedDirs;
+ OptionalDirectoryEntryRef Dir = Header.getDir();
+ SmallVector<DirectoryEntryRef, 2> SkippedDirs;
StringRef DirName = Dir->getName();
auto IsUnavailable = [&](const Module *M) {
@@ -749,8 +745,7 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
// Keep walking up the directory hierarchy, looking for a directory with
// an umbrella header.
do {
- llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
- = UmbrellaDirs.find(Dir);
+ auto KnownDir = UmbrellaDirs.find(*Dir);
if (KnownDir != UmbrellaDirs.end()) {
Module *Found = KnownDir->second;
if (IsUnavailable(Found))
@@ -759,15 +754,16 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
// Search up the module stack until we find a module with an umbrella
// directory.
Module *UmbrellaModule = Found;
- while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
+ while (!UmbrellaModule->getEffectiveUmbrellaDir() &&
+ UmbrellaModule->Parent)
UmbrellaModule = UmbrellaModule->Parent;
if (UmbrellaModule->InferSubmodules) {
- for (const DirectoryEntry *SkippedDir : llvm::reverse(SkippedDirs)) {
+ for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
// Find or create the module that corresponds to this directory name.
SmallString<32> NameBuf;
StringRef Name = sanitizeFilenameAsIdentifier(
- llvm::sys::path::stem(SkippedDir->getName()), NameBuf);
+ llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
Found = lookupModuleQualified(Name, Found);
if (!Found)
return false;
@@ -778,7 +774,7 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
// Infer a submodule with the same name as this header file.
SmallString<32> NameBuf;
StringRef Name = sanitizeFilenameAsIdentifier(
- llvm::sys::path::stem(Header->getName()),
+ llvm::sys::path::stem(Header.getName()),
NameBuf);
Found = lookupModuleQualified(Name, Found);
if (!Found)
@@ -788,7 +784,7 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
return IsUnavailable(Found);
}
- SkippedDirs.push_back(Dir);
+ SkippedDirs.push_back(*Dir);
// Retrieve our parent path.
DirName = llvm::sys::path::parent_path(DirName);
@@ -796,10 +792,7 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
break;
// Resolve the parent path to a directory entry.
- if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName))
- Dir = *DirEntry;
- else
- Dir = nullptr;
+ Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
} while (Dir);
return false;
@@ -854,7 +847,7 @@ Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
Module *Parent) {
auto *Result = new Module("<global>", Loc, Parent, /*IsFramework*/ false,
/*IsExplicit*/ true, NumCreatedModules++);
- Result->Kind = Module::GlobalModuleFragment;
+ Result->Kind = Module::ExplicitGlobalModuleFragment;
// If the created module isn't owned by a parent, send it to PendingSubmodules
// to wait for its parent.
if (!Result->Parent)
@@ -862,6 +855,21 @@ Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
return Result;
}
+Module *ModuleMap::createImplicitGlobalModuleFragmentForModuleUnit(
+ SourceLocation Loc, bool IsExported, Module *Parent) {
+ assert(Parent && "We should only create an implicit global module fragment "
+ "in a module purview");
+ // Note: Here the `IsExplicit` parameter refers to the semantics in clang
+ // modules. All the non-explicit submodules in clang modules will be exported
+ // too. Here we simplify the implementation by using the concept.
+ auto *Result = new Module(IsExported ? "<exported implicit global>"
+ : "<implicit global>",
+ Loc, Parent, /*IsFramework*/ false,
+ /*IsExplicit*/ !IsExported, NumCreatedModules++);
+ Result->Kind = Module::ImplicitGlobalModuleFragment;
+ return Result;
+}
+
Module *
ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
SourceLocation Loc) {
@@ -872,23 +880,30 @@ ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
return Result;
}
-Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
- StringRef Name) {
- assert(LangOpts.CurrentModule == Name && "module name mismatch");
- assert(!Modules[Name] && "redefining existing module");
-
+Module *ModuleMap::createModuleUnitWithKind(SourceLocation Loc, StringRef Name,
+ Module::ModuleKind Kind) {
auto *Result =
new Module(Name, Loc, nullptr, /*IsFramework*/ false,
/*IsExplicit*/ false, NumCreatedModules++);
- Result->Kind = Module::ModuleInterfaceUnit;
- Modules[Name] = SourceModule = Result;
+ Result->Kind = Kind;
- // Reparent the current global module fragment as a submodule of this module.
+ // Reparent any current global module fragment as a submodule of this module.
for (auto &Submodule : PendingSubmodules) {
Submodule->setParent(Result);
Submodule.release(); // now owned by parent
}
PendingSubmodules.clear();
+ return Result;
+}
+
+Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
+ StringRef Name) {
+ assert(LangOpts.CurrentModule == Name && "module name mismatch");
+ assert(!Modules[Name] && "redefining existing module");
+
+ auto *Result =
+ createModuleUnitWithKind(Loc, Name, Module::ModuleInterfaceUnit);
+ Modules[Name] = SourceModule = Result;
// Mark the main source file as being within the newly-created module so that
// declarations and macros are properly visibility-restricted to it.
@@ -899,6 +914,30 @@ Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
return Result;
}
+Module *ModuleMap::createModuleForImplementationUnit(SourceLocation Loc,
+ StringRef Name) {
+ assert(LangOpts.CurrentModule == Name && "module name mismatch");
+ // The interface for this implementation must exist and be loaded.
+ assert(Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit &&
+ "creating implementation module without an interface");
+
+ // Create an entry in the modules map to own the implementation unit module.
+ // User module names must not start with a period (so that this cannot clash
+ // with any legal user-defined module name).
+ StringRef IName = ".ImplementationUnit";
+ assert(!Modules[IName] && "multiple implementation units?");
+
+ auto *Result =
+ createModuleUnitWithKind(Loc, Name, Module::ModuleImplementationUnit);
+ Modules[IName] = SourceModule = Result;
+
+ // Check that the main file is present.
+ assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&
+ "no input file for module implementation");
+
+ return Result;
+}
+
Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
Module::Header H) {
assert(LangOpts.CurrentModule == Name && "module name mismatch");
@@ -914,37 +953,23 @@ Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
/// For a framework module, infer the framework against which we
/// should link.
-static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
- FileManager &FileMgr) {
+static void inferFrameworkLink(Module *Mod) {
assert(Mod->IsFramework && "Can only infer linking for framework modules");
assert(!Mod->isSubFramework() &&
"Can only infer linking for top-level frameworks");
- SmallString<128> LibName;
- LibName += FrameworkDir->getName();
- llvm::sys::path::append(LibName, Mod->Name);
-
- // The library name of a framework has more than one possible extension since
- // the introduction of the text-based dynamic library format. We need to check
- // for both before we give up.
- for (const char *extension : {"", ".tbd"}) {
- llvm::sys::path::replace_extension(LibName, extension);
- if (FileMgr.getFile(LibName)) {
- Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
- /*IsFramework=*/true));
- return;
- }
- }
+ Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
+ /*IsFramework=*/true));
}
-Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
+Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
bool IsSystem, Module *Parent) {
Attributes Attrs;
Attrs.IsSystem = IsSystem;
return inferFrameworkModule(FrameworkDir, Attrs, Parent);
}
-Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
+Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
Attributes Attrs, Module *Parent) {
// Note: as an egregious but useful hack we use the real path here, because
// we might be looking at an embedded framework that symlinks out to a
@@ -975,7 +1000,7 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
// Figure out the parent path.
StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
- if (auto ParentDir = FileMgr.getDirectory(Parent)) {
+ if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) {
// Check whether we have already looked into the parent directory
// for a module map.
llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
@@ -984,9 +1009,9 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
// We haven't looked here before. Load a module map, if there is
// one.
bool IsFrameworkDir = Parent.endswith(".framework");
- if (const FileEntry *ModMapFile =
- HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
- parseModuleMapFile(ModMapFile, Attrs.IsSystem, *ParentDir);
+ if (OptionalFileEntryRef ModMapFile =
+ HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
+ parseModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir);
inferred = InferredDirectories.find(*ParentDir);
}
@@ -1022,7 +1047,7 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
}
// Look for an umbrella header.
- SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
+ SmallString<128> UmbrellaName = FrameworkDir.getName();
llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName);
@@ -1056,7 +1081,8 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
RelativePath = llvm::sys::path::relative_path(RelativePath);
// umbrella header "umbrella-header-name"
- setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", RelativePath);
+ setUmbrellaHeaderAsWritten(Result, *UmbrellaHeader, ModuleName + ".h",
+ RelativePath);
// export *
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
@@ -1067,8 +1093,7 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
// Look for subframeworks.
std::error_code EC;
- SmallString<128> SubframeworksDirName
- = StringRef(FrameworkDir->getName());
+ SmallString<128> SubframeworksDirName = FrameworkDir.getName();
llvm::sys::path::append(SubframeworksDirName, "Frameworks");
llvm::sys::path::native(SubframeworksDirName);
llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
@@ -1079,8 +1104,7 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
if (!StringRef(Dir->path()).endswith(".framework"))
continue;
- if (auto SubframeworkDir =
- FileMgr.getDirectory(Dir->path())) {
+ if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) {
// Note: as an egregious but useful hack, we use the real path here and
// check whether it is actually a subdirectory of the parent directory.
// This will not be the case if the 'subframework' is actually a symlink
@@ -1113,9 +1137,8 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
// If the module is a top-level framework, automatically link against the
// framework.
- if (!Result->isSubFramework()) {
- inferFrameworkLink(Result, FrameworkDir, FileMgr);
- }
+ if (!Result->isSubFramework())
+ inferFrameworkLink(Result);
return Result;
}
@@ -1135,11 +1158,11 @@ Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
return Result;
}
-void ModuleMap::setUmbrellaHeader(
+void ModuleMap::setUmbrellaHeaderAsWritten(
Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
const Twine &PathRelativeToRootModuleDirectory) {
Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
- Mod->Umbrella = &UmbrellaHeader.getMapEntry();
+ Mod->Umbrella = UmbrellaHeader;
Mod->UmbrellaAsWritten = NameAsWritten.str();
Mod->UmbrellaRelativeToRootModuleDirectory =
PathRelativeToRootModuleDirectory.str();
@@ -1147,12 +1170,12 @@ void ModuleMap::setUmbrellaHeader(
// Notify callbacks that we just added a new header.
for (const auto &Cb : Callbacks)
- Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
+ Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
}
-void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
- const Twine &NameAsWritten,
- const Twine &PathRelativeToRootModuleDirectory) {
+void ModuleMap::setUmbrellaDirAsWritten(
+ Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten,
+ const Twine &PathRelativeToRootModuleDirectory) {
Mod->Umbrella = UmbrellaDir;
Mod->UmbrellaAsWritten = NameAsWritten.str();
Mod->UmbrellaRelativeToRootModuleDirectory =
@@ -1256,7 +1279,7 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
// Notify callbacks that we just added a new header.
for (const auto &Cb : Callbacks)
- Cb->moduleMapAddHeader(Header.Entry->getName());
+ Cb->moduleMapAddHeader(Header.Entry.getName());
}
OptionalFileEntryRef
@@ -1296,24 +1319,14 @@ ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) {
}
FileManager &FM = SourceMgr.getFileManager();
- auto DirEntry = FM.getDirectory(Dir.empty() ? "." : Dir);
+ auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);
if (!DirEntry)
- return DirEntry.getError();
+ return llvm::errorToErrorCode(DirEntry.takeError());
// Canonicalize the directory.
StringRef CanonicalDir = FM.getCanonicalName(*DirEntry);
- if (CanonicalDir != Dir) {
- auto CanonicalDirEntry = FM.getDirectory(CanonicalDir);
- // Only use the canonicalized path if it resolves to the same entry as the
- // original. This is not true if there's a VFS overlay on top of a FS where
- // the directory is a symlink. The overlay would not remap the target path
- // of the symlink to the same directory entry in that case.
- if (CanonicalDirEntry && *CanonicalDirEntry == *DirEntry) {
- bool Done = llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
- (void)Done;
- assert(Done && "Path should always start with Dir");
- }
- }
+ if (CanonicalDir != Dir)
+ llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
// In theory, the filename component should also be canonicalized if it
// on a case-insensitive filesystem. However, the extra canonicalization is
@@ -1485,7 +1498,7 @@ namespace clang {
/// The directory that file names in this module map file should
/// be resolved relative to.
- const DirectoryEntry *Directory;
+ DirectoryEntryRef Directory;
/// Whether this module map is in a system header directory.
bool IsSystem;
@@ -1551,7 +1564,7 @@ namespace clang {
explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
const TargetInfo *Target, DiagnosticsEngine &Diags,
ModuleMap &Map, const FileEntry *ModuleMapFile,
- const DirectoryEntry *Directory, bool IsSystem)
+ DirectoryEntryRef Directory, bool IsSystem)
: L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
ModuleMapFile(ModuleMapFile), Directory(Directory),
IsSystem(IsSystem) {
@@ -2003,10 +2016,28 @@ void ModuleMapParser::parseModuleDecl() {
Module *ShadowingModule = nullptr;
if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
// We might see a (re)definition of a module that we already have a
- // definition for in two cases:
+ // definition for in four cases:
// - If we loaded one definition from an AST file and we've just found a
// corresponding definition in a module map file, or
- bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
+ bool LoadedFromASTFile = Existing->IsFromModuleFile;
+ // - If we previously inferred this module from different module map file.
+ bool Inferred = Existing->IsInferred;
+ // - If we're building a framework that vends a module map, we might've
+ // previously seen the one in intermediate products and now the system
+ // one.
+ // FIXME: If we're parsing module map file that looks like this:
+ // framework module FW { ... }
+ // module FW.Sub { ... }
+ // We can't check the framework qualifier, since it's not attached to
+ // the definition of Sub. Checking that qualifier on \c Existing is
+ // not correct either, since we might've previously seen:
+ // module FW { ... }
+ // module FW.Sub { ... }
+ // We should enforce consistency of redefinitions so that we can rely
+ // that \c Existing is part of a framework iff the redefinition of FW
+ // we have just skipped had it too. Once we do that, stop checking
+ // the local framework qualifier and only rely on \c Existing.
+ bool PartOfFramework = Framework || Existing->isPartOfFramework();
// - If we're building a (preprocessed) module and we've just loaded the
// module map file from which it was created.
bool ParsedAsMainInput =
@@ -2014,7 +2045,8 @@ void ModuleMapParser::parseModuleDecl() {
Map.LangOpts.CurrentModule == ModuleName &&
SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
- if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
+ if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
+ ActiveModule = PreviousActiveModule;
// Skip the module definition.
skipUntil(MMToken::RBrace);
if (Tok.is(MMToken::RBrace))
@@ -2169,9 +2201,8 @@ void ModuleMapParser::parseModuleDecl() {
// If the active module is a top-level framework, and there are no link
// libraries, automatically link against the framework.
if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
- ActiveModule->LinkLibraries.empty()) {
- inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
- }
+ ActiveModule->LinkLibraries.empty())
+ inferFrameworkLink(ActiveModule);
// If the module meets all requirements but is still unavailable, mark the
// whole tree as unavailable to prevent it from building.
@@ -2222,16 +2253,16 @@ void ModuleMapParser::parseExternModuleDecl() {
StringRef FileNameRef = FileName;
SmallString<128> ModuleMapFileName;
if (llvm::sys::path::is_relative(FileNameRef)) {
- ModuleMapFileName += Directory->getName();
+ ModuleMapFileName += Directory.getName();
llvm::sys::path::append(ModuleMapFileName, FileName);
FileNameRef = ModuleMapFileName;
}
- if (auto File = SourceMgr.getFileManager().getFile(FileNameRef))
+ if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
Map.parseModuleMapFile(
*File, IsSystem,
Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
? Directory
- : (*File)->getDir(),
+ : File->getDir(),
FileID(), nullptr, ExternLoc);
}
@@ -2444,7 +2475,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
bool NeedsFramework = false;
Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
- if (NeedsFramework && ActiveModule)
+ if (NeedsFramework)
Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
<< ActiveModule->getFullModuleName()
<< FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
@@ -2481,16 +2512,14 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
}
// Look for this file.
- const DirectoryEntry *Dir = nullptr;
+ OptionalDirectoryEntryRef Dir;
if (llvm::sys::path::is_absolute(DirName)) {
- if (auto D = SourceMgr.getFileManager().getDirectory(DirName))
- Dir = *D;
+ Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
} else {
SmallString<128> PathName;
- PathName = Directory->getName();
+ PathName = Directory.getName();
llvm::sys::path::append(PathName, DirName);
- if (auto D = SourceMgr.getFileManager().getDirectory(PathName))
- Dir = *D;
+ Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);
}
if (!Dir) {
@@ -2511,7 +2540,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().getOptionalFileRef(I->path())) {
- Module::Header Header = {"", std::string(I->path()), FE};
+ Module::Header Header = {"", std::string(I->path()), *FE};
Headers.push_back(std::move(Header));
}
}
@@ -2524,7 +2553,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
return;
}
- if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
+ if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
<< OwningModule->getFullModuleName();
HadError = true;
@@ -2532,7 +2561,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
}
// Record this umbrella directory.
- Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
+ Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);
}
/// Parse a module export declaration.
@@ -2796,7 +2825,7 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
if (ActiveModule) {
// Inferred modules must have umbrella directories.
if (!Failed && ActiveModule->IsAvailable &&
- !ActiveModule->getUmbrellaDir()) {
+ !ActiveModule->getEffectiveUmbrellaDir()) {
Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
Failed = true;
}
@@ -3050,7 +3079,7 @@ bool ModuleMapParser::parseModuleMapFile() {
}
bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
- const DirectoryEntry *Dir, FileID ID,
+ DirectoryEntryRef Dir, FileID ID,
unsigned *Offset,
SourceLocation ExternModuleLoc) {
assert(Target && "Missing target information");