diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -651,19 +651,27 @@ getTopLevelModule()->ASTFile = File; } - /// Retrieve the directory for which this module serves as the - /// umbrella. - DirectoryName getUmbrellaDir() const; + /// Retrieve the explicitly written umbrella directory for this module. + DirectoryName getWrittenUmbrellaDir() const { + if (const auto *ME = Umbrella.dyn_cast()) + return DirectoryName{UmbrellaAsWritten, + UmbrellaRelativeToRootModuleDirectory, ME}; + return DirectoryName{}; + } - /// Retrieve the header that serves as the umbrella header for this - /// module. - Header getUmbrellaHeader() const { - if (auto *ME = Umbrella.dyn_cast()) + /// Retrieve the explicitly written umbrella header for this module. + Header getWrittenUmbrellaHeader() const { + if (const auto *ME = Umbrella.dyn_cast()) return Header{UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory, FileEntryRef(*ME)}; return Header{}; } + /// 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 { diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -692,17 +692,15 @@ /// false otherwise. bool resolveConflicts(Module *Mod, bool Complain); - /// Sets the umbrella header of the given module to the given - /// header. - void setUmbrellaHeader(Module *Mod, FileEntryRef UmbrellaHeader, - const Twine &NameAsWritten, - const Twine &PathRelativeToRootModuleDirectory); - - /// Sets the umbrella directory of the given module to the given - /// directory. - void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, - const Twine &NameAsWritten, - const Twine &PathRelativeToRootModuleDirectory); + /// Sets the umbrella header of the given module to the given header. + void setWrittenUmbrellaHeader(Module *Mod, FileEntryRef UmbrellaHeader, + const Twine &NameAsWritten, + const Twine &PathRelativeToRootModuleDirectory); + + /// Sets the umbrella directory of the given module to the given directory. + void setWrittenUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, + const Twine &NameAsWritten, + const Twine &PathRelativeToRootModuleDirectory); /// Adds this header to the given module. /// \param Role The role of the header wrt the module. diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -263,12 +263,12 @@ return nameParts.empty(); } -Module::DirectoryName Module::getUmbrellaDir() const { - if (Header U = getUmbrellaHeader()) - return {"", "", U.Entry->getDir()}; - - return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory, - Umbrella.dyn_cast()}; +const DirectoryEntry *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; } void Module::addTopHeader(const FileEntry *File) { @@ -483,12 +483,12 @@ OS << "\n"; } - if (Header H = getUmbrellaHeader()) { + if (Header H = getWrittenUmbrellaHeader()) { OS.indent(Indent + 2); OS << "umbrella header \""; OS.write_escaped(H.NameAsWritten); OS << "\"\n"; - } else if (DirectoryName D = getUmbrellaDir()) { + } else if (DirectoryName D = getWrittenUmbrellaDir()) { OS.indent(Indent + 2); OS << "umbrella \""; OS.write_escaped(D.NameAsWritten); diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -364,13 +364,13 @@ } // Note that Module->PrivateHeaders will not be a TopHeader. - if (Module::Header UmbrellaHeader = Module->getUmbrellaHeader()) { + if (auto UmbrellaHeader = Module->getWrittenUmbrellaHeader()) { Module->addTopHeader(UmbrellaHeader.Entry); if (Module->Parent) // Include the umbrella header for submodules. addHeaderInclude(UmbrellaHeader.PathRelativeToRootModuleDirectory, Includes, LangOpts, Module->IsExternC); - } else if (Module::DirectoryName UmbrellaDir = Module->getUmbrellaDir()) { + } else if (auto UmbrellaDir = Module->getWrittenUmbrellaDir()) { // Add all of the headers we find in this subdirectory. std::error_code EC; SmallString<128> DirNative; @@ -550,7 +550,7 @@ // Collect the set of #includes we need to build the module. SmallString<256> HeaderContents; std::error_code Err = std::error_code(); - if (Module::Header UmbrellaHeader = M->getUmbrellaHeader()) + if (Module::Header UmbrellaHeader = M->getWrittenUmbrellaHeader()) addHeaderInclude(UmbrellaHeader.PathRelativeToRootModuleDirectory, HeaderContents, CI.getLangOpts(), M->IsExternC); Err = collectModuleHeaderIncludes( diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -266,7 +266,8 @@ << UmbrellaMod->getFullModuleName(); else // Record this umbrella header. - setUmbrellaHeader(Mod, *File, Header.FileName, RelativePathName.str()); + setWrittenUmbrellaHeader(Mod, *File, Header.FileName, + RelativePathName.str()); } else { Module::Header H = {Header.FileName, std::string(RelativePathName.str()), *File}; @@ -622,7 +623,7 @@ // 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) { @@ -760,7 +761,8 @@ // 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) { @@ -1089,7 +1091,8 @@ RelativePath = llvm::sys::path::relative_path(RelativePath); // umbrella header "umbrella-header-name" - setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", RelativePath); + setWrittenUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", + RelativePath); // export * Result->Exports.push_back(Module::ExportDecl(nullptr, true)); @@ -1167,7 +1170,7 @@ return Result; } -void ModuleMap::setUmbrellaHeader( +void ModuleMap::setWrittenUmbrellaHeader( Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory) { Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); @@ -1182,9 +1185,9 @@ Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader); } -void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, - const Twine &NameAsWritten, - const Twine &PathRelativeToRootModuleDirectory) { +void ModuleMap::setWrittenUmbrellaDir( + Module *Mod, const DirectoryEntry *UmbrellaDir, const Twine &NameAsWritten, + const Twine &PathRelativeToRootModuleDirectory) { Mod->Umbrella = UmbrellaDir; Mod->UmbrellaAsWritten = NameAsWritten.str(); Mod->UmbrellaRelativeToRootModuleDirectory = @@ -2563,7 +2566,7 @@ } // Record this umbrella directory. - Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName); + Map.setWrittenUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName); } /// Parse a module export declaration. @@ -2827,7 +2830,7 @@ 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; } diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -282,14 +282,14 @@ static void collectAllSubModulesWithUmbrellaHeader( const Module &Mod, SmallVectorImpl &SubMods) { - if (Mod.getUmbrellaHeader()) + if (Mod.getWrittenUmbrellaHeader()) SubMods.push_back(&Mod); for (auto *M : Mod.submodules()) collectAllSubModulesWithUmbrellaHeader(*M, SubMods); } void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) { - const Module::Header &UmbrellaHeader = Mod.getUmbrellaHeader(); + Module::Header UmbrellaHeader = Mod.getWrittenUmbrellaHeader(); assert(UmbrellaHeader.Entry && "Module must use umbrella header"); const FileID &File = SourceMgr.translateFile(UmbrellaHeader.Entry); SourceLocation ExpectedHeadersLoc = SourceMgr.getLocForEndOfFile(File); @@ -298,7 +298,7 @@ return; ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); - const DirectoryEntry *Dir = Mod.getUmbrellaDir().Entry; + const DirectoryEntry *Dir = Mod.getEffectiveUmbrellaDir(); llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); std::error_code EC; for (llvm::vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5713,9 +5713,9 @@ std::string Filename = std::string(Blob); ResolveImportedPath(F, Filename); if (auto Umbrella = PP.getFileManager().getOptionalFileRef(Filename)) { - if (!CurrentModule->getUmbrellaHeader()) { + if (!CurrentModule->getWrittenUmbrellaHeader()) { // FIXME: NameAsWritten - ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob, ""); + ModMap.setWrittenUmbrellaHeader(CurrentModule, *Umbrella, Blob, ""); } // Note that it's too late at this point to return out of date if the // name from the PCM doesn't match up with the one in the module map, @@ -5751,9 +5751,9 @@ std::string Dirname = std::string(Blob); ResolveImportedPath(F, Dirname); if (auto Umbrella = PP.getFileManager().getDirectory(Dirname)) { - if (!CurrentModule->getUmbrellaDir()) { + if (!CurrentModule->getWrittenUmbrellaDir()) { // FIXME: NameAsWritten - ModMap.setUmbrellaDir(CurrentModule, *Umbrella, Blob, ""); + ModMap.setWrittenUmbrellaDir(CurrentModule, *Umbrella, Blob, ""); } } break; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2846,11 +2846,11 @@ } // Emit the umbrella header, if there is one. - if (auto UmbrellaHeader = Mod->getUmbrellaHeader()) { + if (auto UmbrellaHeader = Mod->getWrittenUmbrellaHeader()) { RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_HEADER}; Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, UmbrellaHeader.NameAsWritten); - } else if (auto UmbrellaDir = Mod->getUmbrellaDir()) { + } else if (auto UmbrellaDir = Mod->getWrittenUmbrellaDir()) { RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_DIR}; Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record, UmbrellaDir.NameAsWritten);