Index: clang-tools-extra/clangd/ParsedAST.cpp =================================================================== --- clang-tools-extra/clangd/ParsedAST.cpp +++ clang-tools-extra/clangd/ParsedAST.cpp @@ -170,10 +170,9 @@ void replay() { for (const auto &Inc : Includes) { - const FileEntry *File = nullptr; + llvm::Optional File; if (Inc.Resolved != "") - if (auto FE = SM.getFileManager().getFile(Inc.Resolved)) - File = *FE; + File = SM.getFileManager().getFileRef(Inc.Resolved); // Re-lex the #include directive to find its interesting parts. auto HashLoc = SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset); @@ -211,17 +210,17 @@ SynthesizedFilenameTok.setKind(tok::header_name); SynthesizedFilenameTok.setLiteralData(Inc.Written.data()); + const FileEntry *FE = File ? &File.getEntry() : nullptr; llvm::StringRef WrittenFilename = llvm::StringRef(Inc.Written).drop_front().drop_back(); Delegate->InclusionDirective(HashTok->location(), SynthesizedIncludeTok, WrittenFilename, Inc.Written.front() == '<', - FileTok->range(SM).toCharRange(SM), File, + FileTok->range(SM).toCharRange(SM), FE, "SearchPath", "RelPath", /*Imported=*/nullptr, Inc.FileKind); if (File) // FIXME: Use correctly named FileEntryRef. - Delegate->FileSkipped(FileEntryRef(File->getName(), *File), - SynthesizedFilenameTok, Inc.FileKind); + Delegate->FileSkipped(File, SynthesizedFilenameTok, Inc.FileKind); else { llvm::SmallString<1> UnusedRecovery; Delegate->FileNotFound(WrittenFilename, UnusedRecovery); Index: clang/include/clang/Basic/FileManager.h =================================================================== --- clang/include/clang/Basic/FileManager.h +++ clang/include/clang/Basic/FileManager.h @@ -71,6 +71,62 @@ const llvm::StringMapEntry> *Entry; }; +class FileEntry; + +/// A reference to the file entry that is associated with a particular +/// filename, or a reference to another FileEntryRef that should be used +/// instead. +/// +/// The reference to another filename is specifically useful for Redirecting +/// VFSs that use external names. In that case, the \c FileEntryRef returned +/// by the \c FileManager will have the external name, and not the name that +/// was used to lookup the file. +struct SeenFileTableValue { + using MapEntryTy = llvm::StringMapEntry>; + llvm::PointerUnion V; + + SeenFileTableValue() = delete; + SeenFileTableValue(FileEntry &FE) : V(&FE) {} + SeenFileTableValue(MapEntryTy &ME) : V(&ME) {} +}; + +/// A reference to a \c FileEntry that includes the name of the file as it was +/// accessed by the FileManager's client. +class FileEntryRef { +public: + const StringRef getName() const { return Entry->first(); } + + const FileEntry &getFileEntry() const { + return *Entry->second->V.get(); + } + + inline bool isValid() const; + inline off_t getSize() const; + inline unsigned getUID() const; + inline const llvm::sys::fs::UniqueID &getUniqueID() const; + inline time_t getModificationTime() const; + + friend bool operator==(const FileEntryRef &LHS, const FileEntryRef &RHS) { + return LHS.Entry == RHS.Entry; + } + friend bool operator!=(const FileEntryRef &LHS, const FileEntryRef &RHS) { + return !(LHS == RHS); + } + +private: + friend class FileManager; + + FileEntryRef() = delete; + explicit FileEntryRef(const SeenFileTableValue::MapEntryTy &Entry) + : Entry(&Entry) { + assert(Entry.second && "Expected payload"); + assert(Entry.second->V && "Expected non-null"); + assert(Entry.second->V.is() && "Expected FileEntry"); + } + + const SeenFileTableValue::MapEntryTy *Entry; +}; + /// Cached information about one file (either on disk /// or in the virtual file system). /// @@ -79,7 +135,6 @@ class FileEntry { friend class FileManager; - StringRef Name; // Name of the file. std::string RealPathName; // Real path to the file; could be empty. off_t Size; // File size in bytes. time_t ModTime; // Modification time of file. @@ -92,6 +147,14 @@ /// The open file, if it is owned by the \p FileEntry. mutable std::unique_ptr File; + // First access name for this FileEntry. + // + // This is Optional only to allow delayed construction (FileEntryRef has no + // default constructor). It should always have a value in practice. + // + // TODO: remote this once everyone that needs a name uses FileEntryRef. + Optional LastRef; + public: FileEntry() : UniqueID(0, 0), IsNamedPipe(false), IsValid(false) @@ -100,7 +163,9 @@ FileEntry(const FileEntry &) = delete; FileEntry &operator=(const FileEntry &) = delete; - StringRef getName() const { return Name; } + StringRef getName() const { return LastRef->getName(); } + FileEntryRef getLastRef() const { return *LastRef; } + StringRef tryGetRealPathName() const { return RealPathName; } bool isValid() const { return IsValid; } off_t getSize() const { return Size; } @@ -126,41 +191,19 @@ bool isOpenForTests() const { return File != nullptr; } }; -/// A reference to a \c FileEntry that includes the name of the file as it was -/// accessed by the FileManager's client. -class FileEntryRef { -public: - FileEntryRef() = delete; - FileEntryRef(StringRef Name, const FileEntry &Entry) - : Name(Name), Entry(&Entry) {} - - const StringRef getName() const { return Name; } - - bool isValid() const { return Entry->isValid(); } +bool FileEntryRef::isValid() const { return getFileEntry().isValid(); } - const FileEntry &getFileEntry() const { return *Entry; } +off_t FileEntryRef::getSize() const { return getFileEntry().getSize(); } - off_t getSize() const { return Entry->getSize(); } +unsigned FileEntryRef::getUID() const { return getFileEntry().getUID(); } - unsigned getUID() const { return Entry->getUID(); } +const llvm::sys::fs::UniqueID &FileEntryRef::getUniqueID() const { + return getFileEntry().getUniqueID(); +} - const llvm::sys::fs::UniqueID &getUniqueID() const { - return Entry->getUniqueID(); - } - - time_t getModificationTime() const { return Entry->getModificationTime(); } - - friend bool operator==(const FileEntryRef &LHS, const FileEntryRef &RHS) { - return LHS.Entry == RHS.Entry && LHS.Name == RHS.Name; - } - friend bool operator!=(const FileEntryRef &LHS, const FileEntryRef &RHS) { - return !(LHS == RHS); - } - -private: - StringRef Name; - const FileEntry *Entry; -}; +time_t FileEntryRef::getModificationTime() const { + return getFileEntry().getModificationTime(); +} /// Implements support for file system lookup, file system caching, /// and directory search management. @@ -219,10 +262,16 @@ /// the file. /// /// \see SeenDirEntries - llvm::StringMap, - llvm::BumpPtrAllocator> + llvm::StringMap, llvm::BumpPtrAllocator> SeenFileEntries; + /// A mirror of SeenFileEntries to give fake answers for getBypassFile(). + /// + /// Don't bother hooking up a BumpPtrAllocator. This should be rarely used, + /// and only on error paths. + std::unique_ptr>> + SeenBypassFileEntries; + /// The canonical names of files and directories . llvm::DenseMap CanonicalNames; @@ -365,6 +414,14 @@ /// The file itself is not accessed. const FileEntry *getVirtualFile(StringRef Filename, off_t Size, time_t ModificationTime); + FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, + time_t ModificationTime); + + /// Blindly add another reference to the given FileEntry. + /// + /// Returns None if the filename is already mapped. + Optional addAliasForFile(StringRef Filename, + const FileEntry &FE); /// Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual /// file entry, to access the real file. The returned FileEntry will have Index: clang/include/clang/Basic/SourceManager.h =================================================================== --- clang/include/clang/Basic/SourceManager.h +++ clang/include/clang/Basic/SourceManager.h @@ -992,14 +992,21 @@ return getFakeBufferForRecovery()->getMemBufferRef(); } - /// Returns the FileEntry record for the provided FileID. - const FileEntry *getFileEntryForID(FileID FID) const { + /// Returns the FileInfo record for the provided FileID. + const SrcMgr::FileInfo *getFileInfoForID(FileID FID) const { bool MyInvalid = false; const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); if (MyInvalid || !Entry.isFile()) return nullptr; + return &Entry.getFile(); + } + + const FileEntry *getFileEntryForID(FileID FID) const { + auto FI = getFileInfoForID(FID); + if (!FI) + return nullptr; - const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache(); + const SrcMgr::ContentCache *Content = FI->getContentCache(); if (!Content) return nullptr; return Content->OrigEntry; Index: clang/lib/Basic/FileManager.cpp =================================================================== --- clang/lib/Basic/FileManager.cpp +++ clang/lib/Basic/FileManager.cpp @@ -212,11 +212,11 @@ SeenFileInsertResult.first->second.getError()); // Construct and return and FileEntryRef, unless it's a redirect to another // filename. - SeenFileEntryOrRedirect Value = *SeenFileInsertResult.first->second; + SeenFileTableValue Value = *SeenFileInsertResult.first->second; FileEntry *FE; - if (LLVM_LIKELY(FE = Value.dyn_cast())) - return FileEntryRef(SeenFileInsertResult.first->first(), *FE); - return getFileRef(*Value.get(), openFile, CacheFailure); + if (LLVM_LIKELY(FE = Value.V.dyn_cast())) + return FileEntryRef(*SeenFileInsertResult.first); + return FileEntryRef(*Value.V.get()); } // We've not seen this before. Fill it in. @@ -268,24 +268,24 @@ // This occurs when one dir is symlinked to another, for example. FileEntry &UFE = UniqueRealFiles[Status.getUniqueID()]; - NamedFileEnt->second = &UFE; - - // If the name returned by getStatValue is different than Filename, re-intern - // the name. - if (Status.getName() != Filename) { - auto &NewNamedFileEnt = - *SeenFileEntries.insert({Status.getName(), &UFE}).first; - assert((*NewNamedFileEnt.second).get() == &UFE && + if (Status.getName() == Filename) { + // The name matches. Set the FileEntry. + NamedFileEnt->second = SeenFileTableValue(UFE); + } else { + // Name mismatch. We need a redirect. First grab the actual entry we want + // to return. + auto &Redirection = + *SeenFileEntries.insert({Status.getName(), SeenFileTableValue(UFE)}) + .first; + assert(Redirection.second->V.get() == &UFE && "filename from getStatValue() refers to wrong file"); - InterndFileName = NewNamedFileEnt.first().data(); - // In addition to re-interning the name, construct a redirecting seen file - // entry, that will point to the name the filesystem actually wants to use. - StringRef *Redirect = new (CanonicalNameStorage) StringRef(InterndFileName); - auto SeenFileInsertResultIt = SeenFileEntries.find(Filename); - assert(SeenFileInsertResultIt != SeenFileEntries.end() && - "unexpected SeenFileEntries cache miss"); - SeenFileInsertResultIt->second = Redirect; - NamedFileEnt = &*SeenFileInsertResultIt; + + // Cache the redirection in the previously-inserted entry, still available + // in the tentative return value. + NamedFileEnt->second = SeenFileTableValue(Redirection); + + // Fix the tentative return value. + NamedFileEnt = &Redirection; } if (UFE.isValid()) { // Already have an entry with this inode, return it. @@ -306,13 +306,10 @@ // corresponding FileEntry. // FIXME: The Name should be removed from FileEntry once all clients // adopt FileEntryRef. - UFE.Name = InterndFileName; - - return FileEntryRef(InterndFileName, UFE); + return *(UFE.LastRef = FileEntryRef(*NamedFileEnt)); } // Otherwise, we don't have this file yet, add it. - UFE.Name = InterndFileName; UFE.Size = Status.getSize(); UFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); UFE.Dir = DirInfo; @@ -329,24 +326,28 @@ // We should still fill the path even if we aren't opening the file. fillRealPathName(&UFE, InterndFileName); } - return FileEntryRef(InterndFileName, UFE); + return *(UFE.LastRef = FileEntryRef(*NamedFileEnt)); } 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. auto &NamedFileEnt = *SeenFileEntries.insert( {Filename, std::errc::no_such_file_or_directory}).first; if (NamedFileEnt.second) { - SeenFileEntryOrRedirect Value = *NamedFileEnt.second; + SeenFileTableValue Value = *NamedFileEnt.second; FileEntry *FE; - if (LLVM_LIKELY(FE = Value.dyn_cast())) - return FE; - return getVirtualFile(*Value.get(), Size, - ModificationTime); + if (LLVM_LIKELY(FE = Value.V.dyn_cast())) + return FileEntryRef(NamedFileEnt); + return FileEntryRef(*Value.V.get()); } // We've not seen this before, or the file is cached as non-existent. @@ -372,7 +373,7 @@ Status.getUser(), Status.getGroup(), Size, Status.getType(), Status.getPermissions()); - NamedFileEnt.second = UFE; + NamedFileEnt.second = SeenFileTableValue(*UFE); // If we had already opened this file, close it now so we don't // leak the descriptor. We're not going to use the file @@ -381,8 +382,11 @@ UFE->closeFile(); // If we already have an entry with this inode, return it. + // + // FIXME: Surely this should add a reference by the new name, and return + // it instead... if (UFE->isValid()) - return UFE; + return UFE->getLastRef(); UFE->UniqueID = Status.getUniqueID(); UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; @@ -390,17 +394,28 @@ } else { VirtualFileEntries.push_back(std::make_unique()); UFE = VirtualFileEntries.back().get(); - NamedFileEnt.second = UFE; + NamedFileEnt.second = SeenFileTableValue(*UFE); } - UFE->Name = InterndFileName; UFE->Size = Size; UFE->ModTime = ModificationTime; UFE->Dir = *DirInfo; UFE->UID = NextFileUID++; UFE->IsValid = true; UFE->File.reset(); - return UFE; + return *(UFE->LastRef = FileEntryRef(NamedFileEnt)); +} + +Optional FileManager::addAliasForFile(StringRef Filename, + const FileEntry &FE) { + // See if there is already an entry in the map for an existing file. + auto Insertion = SeenFileEntries.insert( + {Filename, std::errc::no_such_file_or_directory}); + if (!Insertion.second) + return None; // Failed to insert... + + Insertion.first->second = SeenFileTableValue(const_cast(FE)); + return FileEntryRef(*Insertion.first); } llvm::Optional FileManager::getBypassFile(FileEntryRef VF) { @@ -409,17 +424,30 @@ if (getStatValue(VF.getName(), Status, /*isFile=*/true, /*F=*/nullptr)) return None; - // Fill it in from the stat. + if (!SeenBypassFileEntries) + SeenBypassFileEntries = + std::make_unique>>(); + + // If we've already bypassed just use the existing one. + auto Insertion = SeenBypassFileEntries->insert( + {VF.getName(), std::errc::no_such_file_or_directory}); + if (!Insertion.second) + return FileEntryRef(*Insertion.first); + + // Fill in the new entry from the stat. BypassFileEntries.push_back(std::make_unique()); const FileEntry &VFE = VF.getFileEntry(); FileEntry &BFE = *BypassFileEntries.back(); - BFE.Name = VFE.getName(); + Insertion.first->second = SeenFileTableValue(BFE); + BFE.LastRef = FileEntryRef(*Insertion.first); BFE.Size = Status.getSize(); BFE.Dir = VFE.Dir; BFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); BFE.UID = NextFileUID++; BFE.IsValid = true; - return FileEntryRef(VF.getName(), BFE); + + // Save the entry in the bypass table and return. + return FileEntryRef(*Insertion.first); } bool FileManager::FixupRelativePath(SmallVectorImpl &path) const { @@ -534,13 +562,13 @@ UIDToFiles.resize(NextFileUID); // Map file entries - for (llvm::StringMap, + for (llvm::StringMap, llvm::BumpPtrAllocator>::const_iterator FE = SeenFileEntries.begin(), FEEnd = SeenFileEntries.end(); FE != FEEnd; ++FE) - if (llvm::ErrorOr Entry = FE->getValue()) { - if (const auto *FE = (*Entry).dyn_cast()) + if (llvm::ErrorOr Entry = FE->getValue()) { + if (const auto *FE = Entry->V.dyn_cast()) UIDToFiles[FE->getUID()] = FE; } Index: clang/lib/Basic/SourceManager.cpp =================================================================== --- clang/lib/Basic/SourceManager.cpp +++ clang/lib/Basic/SourceManager.cpp @@ -345,7 +345,7 @@ bool SourceManager::isMainFile(FileEntryRef SourceFile) { assert(MainFileID.isValid() && "expected initialized SourceManager"); - auto FE = getFileEntryRefForID(MainFileID); + auto FE = getFileEntryForID(MainFileID); if (!FE) return false; return FE->getUID() == SourceFile.getUID(); @@ -708,7 +708,7 @@ SourceManager::bypassFileContentsOverride(const FileEntry &File) { assert(isFileOverridden(&File)); llvm::Optional BypassFile = - FileMgr.getBypassFile(FileEntryRef(File.getName(), File)); + FileMgr.getBypassFile(File.getLastRef()); // If the file can't be found in the FS, give up. if (!BypassFile) @@ -724,18 +724,6 @@ const_cast(CC)->IsTransient = true; } -Optional SourceManager::getFileEntryRefForID(FileID FID) const { - bool Invalid = false; - const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); - if (Invalid || !Entry.isFile()) - return None; - - const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache(); - if (!Content || !Content->OrigEntry) - return None; - return FileEntryRef(Entry.getFile().getName(), *Content->OrigEntry); -} - StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { auto B = getBufferDataOrNone(FID); if (Invalid) Index: clang/lib/Frontend/DependencyFile.cpp =================================================================== --- clang/lib/Frontend/DependencyFile.cpp +++ clang/lib/Frontend/DependencyFile.cpp @@ -46,8 +46,7 @@ // Dependency generation really does want to go all the way to the // file entry for a source location to find out what is depended on. // We do not want #line markers to affect dependency generation! - Optional File = - SM.getFileEntryRefForID(SM.getFileID(SM.getExpansionLoc(Loc))); + auto File = SM.getFileInfoForID(SM.getFileID(SM.getExpansionLoc(Loc))); if (!File) return; Index: clang/lib/Lex/HeaderSearch.cpp =================================================================== --- clang/lib/Lex/HeaderSearch.cpp +++ clang/lib/Lex/HeaderSearch.cpp @@ -765,8 +765,7 @@ // This is the header that MSVC's header search would have found. ModuleMap::KnownHeader MSSuggestedModule; - const FileEntry *MSFE_FE = nullptr; - StringRef MSFE_Name; + Optional MSFE; // Unless disabled, check to see if the file is in the #includer's // directory. This cannot be based on CurDir, because each includer could be @@ -841,8 +840,7 @@ if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) { return FE; } else { - MSFE_FE = &FE->getFileEntry(); - MSFE_Name = FE->getName(); + MSFE = FE; if (SuggestedModule) { MSSuggestedModule = *SuggestedModule; *SuggestedModule = ModuleMap::KnownHeader(); @@ -854,9 +852,6 @@ } } - Optional MSFE(MSFE_FE ? FileEntryRef(MSFE_Name, *MSFE_FE) - : Optional()); - CurDir = nullptr; // If this is a system #include, ignore the user #include locs. Index: clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -77,8 +77,7 @@ // Dependency generation really does want to go all the way to the // file entry for a source location to find out what is depended on. // We do not want #line markers to affect dependency generation! - Optional File = - SM.getFileEntryRefForID(SM.getFileID(SM.getExpansionLoc(Loc))); + auto File = SM.getFileInfoForID(SM.getFileID(SM.getExpansionLoc(Loc))); if (!File) return; Index: clang/unittests/Basic/FileManagerTest.cpp =================================================================== --- clang/unittests/Basic/FileManagerTest.cpp +++ clang/unittests/Basic/FileManagerTest.cpp @@ -485,29 +485,34 @@ // Set up a virtual file with a different size than FakeStatCache uses. const FileEntry *File = Manager.getVirtualFile("/tmp/test", /*Size=*/10, 0); ASSERT_TRUE(File); - FileEntryRef Ref("/tmp/test", *File); - EXPECT_TRUE(Ref.isValid()); - EXPECT_EQ(Ref.getSize(), 10); + const FileEntry &FE = *File; + EXPECT_TRUE(FE.isValid()); + EXPECT_EQ(FE.getSize(), 10); // Calling a second time should not affect the UID or size. - unsigned VirtualUID = Ref.getUID(); - EXPECT_EQ(*expectedToOptional(Manager.getFileRef("/tmp/test")), Ref); - EXPECT_EQ(Ref.getUID(), VirtualUID); - EXPECT_EQ(Ref.getSize(), 10); + unsigned VirtualUID = FE.getUID(); + EXPECT_EQ( + &FE, + &expectedToOptional(Manager.getFileRef("/tmp/test"))->getFileEntry()); + EXPECT_EQ(FE.getUID(), VirtualUID); + EXPECT_EQ(FE.getSize(), 10); // Bypass the file. - llvm::Optional BypassRef = Manager.getBypassFile(Ref); + llvm::Optional BypassRef = + Manager.getBypassFile(File->getLastRef()); ASSERT_TRUE(BypassRef); EXPECT_TRUE(BypassRef->isValid()); - EXPECT_EQ(BypassRef->getName(), Ref.getName()); + EXPECT_EQ("/tmp/test", BypassRef->getName()); // Check that it's different in the right ways. EXPECT_NE(&BypassRef->getFileEntry(), File); EXPECT_NE(BypassRef->getUID(), VirtualUID); - EXPECT_NE(BypassRef->getSize(), Ref.getSize()); + EXPECT_NE(BypassRef->getSize(), FE.getSize()); // The virtual file should still be returned when searching. - EXPECT_EQ(*expectedToOptional(Manager.getFileRef("/tmp/test")), Ref); + EXPECT_EQ( + &FE, + &expectedToOptional(Manager.getFileRef("/tmp/test"))->getFileEntry()); } } // anonymous namespace Index: clang/unittests/Basic/SourceManagerTest.cpp =================================================================== --- clang/unittests/Basic/SourceManagerTest.cpp +++ clang/unittests/Basic/SourceManagerTest.cpp @@ -496,23 +496,26 @@ std::unique_ptr Buf = llvm::MemoryBuffer::getMemBuffer(Source); - const FileEntry *SourceFile = - FileMgr.getVirtualFile("mainFile.cpp", Buf->getBufferSize(), 0); - SourceMgr.overrideFileContents(SourceFile, std::move(Buf)); + auto SourceFile = + FileMgr.getVirtualFileRef("mainFile.cpp", Buf->getBufferSize(), 0); + SourceMgr.overrideFileContents(&SourceFile.getFileEntry(), std::move(Buf)); std::unique_ptr Buf2 = llvm::MemoryBuffer::getMemBuffer(Source); - const FileEntry *SecondFile = - FileMgr.getVirtualFile("file2.cpp", Buf2->getBufferSize(), 0); - SourceMgr.overrideFileContents(SecondFile, std::move(Buf2)); + auto SecondFile = + FileMgr.getVirtualFileRef("file2.cpp", Buf2->getBufferSize(), 0); + SourceMgr.overrideFileContents(&SecondFile.getFileEntry(), std::move(Buf2)); - FileID MainFileID = SourceMgr.getOrCreateFileID(SourceFile, SrcMgr::C_User); + FileID MainFileID = + SourceMgr.getOrCreateFileID(&SourceFile.getFileEntry(), SrcMgr::C_User); SourceMgr.setMainFileID(MainFileID); - EXPECT_TRUE(SourceMgr.isMainFile(FileEntryRef("mainFile.cpp", *SourceFile))); - EXPECT_TRUE( - SourceMgr.isMainFile(FileEntryRef("anotherName.cpp", *SourceFile))); - EXPECT_FALSE(SourceMgr.isMainFile(FileEntryRef("mainFile.cpp", *SecondFile))); + auto MainAlias = + FileMgr.addAliasForFile("anotherName.cpp", SourceFile.getFileEntry()); + + EXPECT_TRUE(SourceMgr.isMainFile(SourceFile)); + EXPECT_TRUE(SourceMgr.isMainFile(*MainAlias)); + EXPECT_FALSE(SourceMgr.isMainFile(SecondFile)); } #endif