diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index b9105441b6b62..128e2adc189b2 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -156,7 +156,8 @@ class alignas(8) Module { std::string PresumedModuleMapFile; /// The umbrella header or directory. - llvm::PointerUnion + llvm::PointerUnion Umbrella; /// The module signature. @@ -252,9 +253,9 @@ class alignas(8) Module { struct DirectoryName { std::string NameAsWritten; std::string PathRelativeToRootModuleDirectory; - const DirectoryEntry *Entry; + OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr Entry; - explicit operator bool() { return Entry; } + explicit operator bool() { return Entry.has_value(); } }; /// The headers that are part of this module. @@ -653,9 +654,11 @@ class alignas(8) Module { /// Retrieve the umbrella directory as written. DirectoryName getUmbrellaDirAsWritten() const { - if (const auto *ME = Umbrella.dyn_cast()) + if (const auto *ME = + Umbrella.dyn_cast()) return DirectoryName{UmbrellaAsWritten, - UmbrellaRelativeToRootModuleDirectory, ME}; + UmbrellaRelativeToRootModuleDirectory, + DirectoryEntryRef(*ME)}; return DirectoryName{}; } @@ -670,13 +673,7 @@ class alignas(8) Module { /// Get the effective umbrella directory for this module: either the one /// explicitly written in the module map file, or the parent of the umbrella /// header. - const DirectoryEntry *getEffectiveUmbrellaDir() const; - - /// Determine whether this module has an umbrella directory that is - /// not based on an umbrella header. - bool hasUmbrellaDir() const { - return Umbrella && Umbrella.is(); - } + OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const; /// Add a top-level header associated with this module. void addTopHeader(const FileEntry *File); diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h index bd7e4e6ff8fe7..92697fe7deaa1 100644 --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -699,7 +699,7 @@ class ModuleMap { const Twine &PathRelativeToRootModuleDirectory); /// Sets the umbrella directory of the given module to the given directory. - void setUmbrellaDirAsWritten(Module *Mod, const DirectoryEntry *UmbrellaDir, + void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory); diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index e0bce04412a2f..3df376a32e53e 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -263,12 +263,12 @@ bool Module::fullModuleNameIs(ArrayRef nameParts) const { return nameParts.empty(); } -const DirectoryEntry *Module::getEffectiveUmbrellaDir() const { +OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const { if (const auto *ME = Umbrella.dyn_cast()) return FileEntryRef(*ME).getDir(); - if (const auto *ME = Umbrella.dyn_cast()) - return ME; - return nullptr; + if (const auto *ME = Umbrella.dyn_cast()) + return DirectoryEntryRef(*ME); + return std::nullopt; } void Module::addTopHeader(const FileEntry *File) { diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 9bc1ccd02eb13..0db7ebff29174 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -1186,9 +1186,9 @@ void ModuleMap::setUmbrellaHeaderAsWritten( } void ModuleMap::setUmbrellaDirAsWritten( - Module *Mod, const DirectoryEntry *UmbrellaDir, const Twine &NameAsWritten, + Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory) { - Mod->Umbrella = UmbrellaDir; + Mod->Umbrella = &UmbrellaDir.getMapEntry(); Mod->UmbrellaAsWritten = NameAsWritten.str(); Mod->UmbrellaRelativeToRootModuleDirectory = PathRelativeToRootModuleDirectory.str(); @@ -2515,16 +2515,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(); llvm::sys::path::append(PathName, DirName); - if (auto D = SourceMgr.getFileManager().getDirectory(PathName)) - Dir = *D; + Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName); } if (!Dir) { @@ -2558,7 +2556,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; @@ -2566,7 +2564,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { } // Record this umbrella directory. - Map.setUmbrellaDirAsWritten(ActiveModule, Dir, DirNameAsWritten, DirName); + Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName); } /// Parse a module export declaration. diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index 3c4a1386dfc8e..4103cfe178b29 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -298,7 +298,7 @@ void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) { return; ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); - const DirectoryEntry *Dir = Mod.getEffectiveUmbrellaDir(); + OptionalDirectoryEntryRef Dir = Mod.getEffectiveUmbrellaDir(); llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); std::error_code EC; for (llvm::vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), @@ -318,7 +318,7 @@ void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) { if (!ModMap.isHeaderInUnavailableModule(*Header)) { // Find the relative path that would access this header. SmallString<128> RelativePath; - computeRelativePath(FileMgr, Dir, *Header, RelativePath); + computeRelativePath(FileMgr, *Dir, *Header, RelativePath); Diag(ExpectedHeadersLoc, diag::warn_uncovered_module_header) << Mod.getFullModuleName() << RelativePath; } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 5b53aa3c496bb..f6251fb03ccf2 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5750,7 +5750,8 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F, // See comments in SUBMODULE_UMBRELLA_HEADER std::string Dirname = std::string(Blob); ResolveImportedPath(F, Dirname); - if (auto Umbrella = PP.getFileManager().getDirectory(Dirname)) { + if (auto Umbrella = + PP.getFileManager().getOptionalDirectoryRef(Dirname)) { if (!CurrentModule->getUmbrellaDirAsWritten()) { // FIXME: NameAsWritten ModMap.setUmbrellaDirAsWritten(CurrentModule, *Umbrella, Blob, "");