diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -239,6 +239,9 @@ /// if there were a file with the given name on disk. /// /// The file itself is not accessed. + FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, + time_t ModificationTime); + const FileEntry *getVirtualFile(StringRef Filename, off_t Size, time_t ModificationTime); diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -35,6 +35,7 @@ #define LLVM_CLANG_BASIC_SOURCEMANAGER_H #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/FileEntry.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" @@ -60,8 +61,6 @@ class ASTReader; class ASTWriter; class FileManager; -class FileEntry; -class FileEntryRef; class LineTableInfo; class SourceManager; @@ -982,11 +981,11 @@ } /// Bypass the overridden contents of a file. This creates a new FileEntry - /// and initializes the content cache for it. Returns nullptr if there is no + /// and initializes the content cache for it. Returns None if there is no /// such file in the filesystem. /// /// This should be called before parsing has begun. - const FileEntry *bypassFileContentsOverride(const FileEntry &File); + Optional bypassFileContentsOverride(FileEntryRef File); /// Specify that a file is transient. void setFileIsTransient(const FileEntry *SourceFile); diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -67,13 +67,13 @@ OutOfDate = 2, NotFound = 3 }; - llvm::PointerIntPair Val; + llvm::PointerIntPair Val; public: InputFile() = default; - InputFile(const FileEntry *File, - bool isOverridden = false, bool isOutOfDate = false) { + InputFile(FileEntryRef File, bool isOverridden = false, + bool isOutOfDate = false) { assert(!(isOverridden && isOutOfDate) && "an overridden cannot be out-of-date"); unsigned intVal = 0; @@ -81,7 +81,7 @@ intVal = Overridden; else if (isOutOfDate) intVal = OutOfDate; - Val.setPointerAndInt(File, intVal); + Val.setPointerAndInt(&File.getMapEntry(), intVal); } static InputFile getNotFound() { @@ -90,7 +90,11 @@ return File; } - const FileEntry *getFile() const { return Val.getPointer(); } + OptionalFileEntryRefDegradesToFileEntryPtr getFile() const { + if (auto *P = Val.getPointer()) + return FileEntryRef(*P); + return None; + } bool isOverridden() const { return Val.getInt() == Overridden; } bool isOutOfDate() const { return Val.getInt() == OutOfDate; } bool isNotFound() const { return Val.getInt() == NotFound; } diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -335,9 +335,13 @@ return ReturnedRef; } -const FileEntry * -FileManager::getVirtualFile(StringRef Filename, off_t Size, - time_t ModificationTime) { +const FileEntry *FileManager::getVirtualFile(StringRef Filename, off_t Size, + time_t ModificationTime) { + return &getVirtualFileRef(Filename, Size, ModificationTime).getFileEntry(); +} + +FileEntryRef FileManager::getVirtualFileRef(StringRef Filename, off_t Size, + time_t ModificationTime) { ++NumFileLookups; // See if there is already an entry in the map for an existing file. @@ -345,12 +349,10 @@ {Filename, std::errc::no_such_file_or_directory}).first; if (NamedFileEnt.second) { FileEntryRef::MapValue Value = *NamedFileEnt.second; - FileEntry *FE; - if (LLVM_LIKELY(FE = Value.V.dyn_cast())) - return FE; - return &FileEntryRef(*reinterpret_cast( - Value.V.get())) - .getFileEntry(); + if (LLVM_LIKELY(Value.V.is())) + return FileEntryRef(NamedFileEnt); + return FileEntryRef(*reinterpret_cast( + Value.V.get())); } // We've not seen this before, or the file is cached as non-existent. @@ -389,7 +391,7 @@ // FIXME: Surely this should add a reference by the new name, and return // it instead... if (UFE->isValid()) - return UFE; + return FileEntryRef(NamedFileEnt); UFE->UniqueID = Status.getUniqueID(); UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; @@ -407,7 +409,7 @@ UFE->UID = NextFileUID++; UFE->IsValid = true; UFE->File.reset(); - return UFE; + return FileEntryRef(NamedFileEnt); } llvm::Optional FileManager::getBypassFile(FileEntryRef VF) { diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -698,19 +698,17 @@ getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile; } -const FileEntry * -SourceManager::bypassFileContentsOverride(const FileEntry &File) { - assert(isFileOverridden(&File)); - llvm::Optional BypassFile = - FileMgr.getBypassFile(File.getLastRef()); +Optional +SourceManager::bypassFileContentsOverride(FileEntryRef File) { + assert(isFileOverridden(&File.getFileEntry())); + llvm::Optional BypassFile = FileMgr.getBypassFile(File); // If the file can't be found in the FS, give up. if (!BypassFile) - return nullptr; + return None; - const FileEntry *FE = &BypassFile->getFileEntry(); - (void)getOrCreateContentCache(FE); - return FE; + (void)getOrCreateContentCache(&BypassFile->getFileEntry()); + return BypassFile; } void SourceManager::setFileIsTransient(const FileEntry *File) { 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 @@ -2296,27 +2296,25 @@ StringRef Filename = FI.Filename; uint64_t StoredContentHash = FI.ContentHash; - const FileEntry *File = nullptr; - if (auto FE = FileMgr.getFile(Filename, /*OpenFile=*/false)) - File = *FE; + OptionalFileEntryRefDegradesToFileEntryPtr File = + expectedToOptional(FileMgr.getFileRef(Filename, /*OpenFile=*/false)); // If we didn't find the file, resolve it relative to the // original directory from which this AST file was created. - if (File == nullptr && !F.OriginalDir.empty() && !F.BaseDirectory.empty() && + if (!File && !F.OriginalDir.empty() && !F.BaseDirectory.empty() && F.OriginalDir != F.BaseDirectory) { std::string Resolved = resolveFileRelativeToOriginalDir( std::string(Filename), F.OriginalDir, F.BaseDirectory); if (!Resolved.empty()) - if (auto FE = FileMgr.getFile(Resolved)) - File = *FE; + File = expectedToOptional(FileMgr.getFileRef(Resolved)); } // For an overridden file, create a virtual file with the stored // size/timestamp. - if ((Overridden || Transient) && File == nullptr) - File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime); + if ((Overridden || Transient) && !File) + File = FileMgr.getVirtualFileRef(Filename, StoredSize, StoredTime); - if (File == nullptr) { + if (!File) { if (Complain) { std::string ErrorStr = "could not find file '"; ErrorStr += Filename; @@ -2418,7 +2416,7 @@ // FIXME: If the file is overridden and we've already opened it, // issue an error (or split it into a separate FileEntry). - InputFile IF = InputFile(File, Overridden || Transient, IsOutOfDate); + InputFile IF = InputFile(*File, Overridden || Transient, IsOutOfDate); // Note that we've loaded this input file. F.InputFilesLoaded[ID-1] = IF; @@ -9274,7 +9272,7 @@ InputFileInfo IFI = readInputFileInfo(MF, I + 1); if (IFI.TopLevelModuleMap) // FIXME: This unnecessarily re-reads the InputFileInfo. - if (auto *FE = getInputFile(MF, I + 1).getFile()) + if (auto FE = getInputFile(MF, I + 1).getFile()) Visitor(FE); } }