diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -659,7 +659,7 @@ /// /// \param File The header that we wish to map to a module. /// \param AllowTextual Whether we want to find textual headers too. - ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File, + ModuleMap::KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual = false, bool AllowExcluded = false) const; @@ -670,7 +670,7 @@ /// /// \ref findModuleForHeader should typically be used instead of this. ArrayRef - findAllModulesForHeader(const FileEntry *File) const; + findAllModulesForHeader(FileEntryRef File) const; /// Like \ref findAllModulesForHeader, but do not attempt to infer module /// ownership from umbrella headers if we've not already done so. @@ -760,7 +760,7 @@ /// /// \return \c true if the file can be used, \c false if we are not permitted to /// find this file due to requirements from \p RequestingModule. - bool findUsableModuleForHeader(const FileEntry *File, + bool findUsableModuleForHeader(OptionalFileEntryRef File, const DirectoryEntry *Root, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, @@ -772,7 +772,7 @@ /// \return \c true if the file can be used, \c false if we are not permitted to /// find this file due to requirements from \p RequestingModule. bool findUsableModuleForFrameworkHeader( - const FileEntry *File, StringRef FrameworkName, Module *RequestingModule, + FileEntryRef File, StringRef FrameworkName, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework); /// Look up the file with the specified name and determine its owning 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 @@ -366,17 +366,17 @@ /// /// \param IntermediateDirs On success, contains the set of directories /// searched before finding \p File. - KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File, - SmallVectorImpl &IntermediateDirs); + KnownHeader findHeaderInUmbrellaDirs( + FileEntryRef File, SmallVectorImpl &IntermediateDirs); /// Given that \p File is not in the Headers map, look it up within /// umbrella directories and find or create a module for it. - KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File); + KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File); /// A convenience method to determine if \p File is (possibly nested) /// in an umbrella directory. - bool isHeaderInUmbrellaDirs(const FileEntry *File) { - SmallVector IntermediateDirs; + bool isHeaderInUmbrellaDirs(FileEntryRef File) { + SmallVector IntermediateDirs; return static_cast(findHeaderInUmbrellaDirs(File, IntermediateDirs)); } @@ -439,8 +439,7 @@ /// \returns The module KnownHeader, which provides the module that owns the /// given header file. The KnownHeader is default constructed to indicate /// that no module owns this header file. - KnownHeader findModuleForHeader(const FileEntry *File, - bool AllowTextual = false, + KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual = false, bool AllowExcluded = false); /// Retrieve all the modules that contain the given header file. Note that @@ -450,7 +449,7 @@ /// /// Typically, \ref findModuleForHeader should be used instead, as it picks /// the preferred module for the header. - ArrayRef findAllModulesForHeader(const FileEntry *File); + ArrayRef findAllModulesForHeader(FileEntryRef File); /// Like \ref findAllModulesForHeader, but do not attempt to infer module /// ownership from umbrella headers if we've not already done so. diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -436,8 +436,8 @@ // If there is a module that corresponds to this header, suggest it. if (!findUsableModuleForHeader( - &File->getFileEntry(), Dir ? Dir : File->getFileEntry().getDir(), - RequestingModule, SuggestedModule, IsSystemHeaderDir)) + *File, Dir ? Dir : File->getFileEntry().getDir(), RequestingModule, + SuggestedModule, IsSystemHeaderDir)) return std::nullopt; return *File; @@ -501,9 +501,9 @@ RelativePath->clear(); RelativePath->append(Filename.begin(), Filename.end()); } - if (!HS.findUsableModuleForHeader( - &File.getFileEntry(), File.getFileEntry().getDir(), - RequestingModule, SuggestedModule, isSystemHeaderDirectory())) { + if (!HS.findUsableModuleForHeader(File, File.getFileEntry().getDir(), + RequestingModule, SuggestedModule, + isSystemHeaderDirectory())) { return std::nullopt; } return File; @@ -713,14 +713,13 @@ bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; if (FoundFramework) { - if (!HS.findUsableModuleForFrameworkHeader( - &File->getFileEntry(), FrameworkPath, RequestingModule, - SuggestedModule, IsSystem)) + if (!HS.findUsableModuleForFrameworkHeader(*File, FrameworkPath, + RequestingModule, + SuggestedModule, IsSystem)) return std::nullopt; } else { - if (!HS.findUsableModuleForHeader(&File->getFileEntry(), getDir(), - RequestingModule, SuggestedModule, - IsSystem)) + if (!HS.findUsableModuleForHeader(*File, getDir(), RequestingModule, + SuggestedModule, IsSystem)) return std::nullopt; } } @@ -1279,7 +1278,7 @@ getFileInfo(&File->getFileEntry()).DirInfo = DirInfo; FrameworkName.pop_back(); // remove the trailing '/' - if (!findUsableModuleForFrameworkHeader(&File->getFileEntry(), FrameworkName, + if (!findUsableModuleForFrameworkHeader(*File, FrameworkName, RequestingModule, SuggestedModule, /*IsSystem*/ false)) return std::nullopt; @@ -1559,7 +1558,7 @@ } ModuleMap::KnownHeader -HeaderSearch::findModuleForHeader(const FileEntry *File, bool AllowTextual, +HeaderSearch::findModuleForHeader(FileEntryRef File, bool AllowTextual, bool AllowExcluded) const { if (ExternalSource) { // Make sure the external source has handled header info about this file, @@ -1570,7 +1569,7 @@ } ArrayRef -HeaderSearch::findAllModulesForHeader(const FileEntry *File) const { +HeaderSearch::findAllModulesForHeader(FileEntryRef File) const { if (ExternalSource) { // Make sure the external source has handled header info about this file, // which includes whether the file is part of a module. @@ -1589,7 +1588,7 @@ return ModMap.findResolvedModulesForHeader(File); } -static bool suggestModule(HeaderSearch &HS, const FileEntry *File, +static bool suggestModule(HeaderSearch &HS, FileEntryRef File, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) { ModuleMap::KnownHeader Module = @@ -1625,18 +1624,19 @@ } bool HeaderSearch::findUsableModuleForHeader( - const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) { + OptionalFileEntryRef File, const DirectoryEntry *Root, + Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, + bool IsSystemHeaderDir) { if (File && needModuleLookup(RequestingModule, SuggestedModule)) { // If there is a module that corresponds to this header, suggest it. hasModuleMap(File->getName(), Root, IsSystemHeaderDir); - return suggestModule(*this, File, RequestingModule, SuggestedModule); + return suggestModule(*this, *File, RequestingModule, SuggestedModule); } return true; } bool HeaderSearch::findUsableModuleForFrameworkHeader( - const FileEntry *File, StringRef FrameworkName, Module *RequestingModule, + FileEntryRef File, StringRef FrameworkName, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) { // If we're supposed to suggest a module, look for one now. if (needModuleLookup(RequestingModule, SuggestedModule)) { 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 @@ -409,29 +409,27 @@ return Known; } -ModuleMap::KnownHeader -ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, - SmallVectorImpl &IntermediateDirs) { +ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs( + FileEntryRef File, SmallVectorImpl &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); @@ -439,10 +437,7 @@ 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 {}; } @@ -582,7 +577,7 @@ 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 { @@ -612,10 +607,10 @@ } ModuleMap::KnownHeader -ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) { +ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) { assert(!Headers.count(File) && "already have a module for this header"); - SmallVector SkippedDirs; + SmallVector SkippedDirs; KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs); if (H) { Module *Result = H.getModule(); @@ -635,11 +630,11 @@ // 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; @@ -657,7 +652,7 @@ // 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; @@ -684,7 +679,7 @@ } ArrayRef -ModuleMap::findAllModulesForHeader(const FileEntry *File) { +ModuleMap::findAllModulesForHeader(FileEntryRef File) { HeadersMap::iterator Known = findKnownHeader(File); if (Known != Headers.end()) return Known->second; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -8799,7 +8799,8 @@ ASTUnit &Unit = *cxtu::getASTUnit(TU); HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo(); - ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE); + // TODO: Make CXFile a FileEntryRef. + ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE->getLastRef()); return Header.getModule(); }