================
@@ -1858,6 +1851,70 @@ ASTReader::readSLocOffset(ModuleFile *F, unsigned Index) 
{
   }
 }
 
+void ASTReader::buildLoadedInputFiles() {
+  LoadedInputFiles.emplace();
+  // Modules are visited in index order, which is fixed before this runs, so 
the
+  // copy chosen for a file is the same on every write of this module.
+  for (ModuleFile &F : ModuleMgr) {
+    for (unsigned I = 0, N = F.InputFilesLoaded.size(); I != N; ++I) {
+      InputFileInfo FI = getInputFileInfo(F, I + 1);
+      if (FI.UnresolvedImportedFilename.empty())
+        continue;
+      // An overridden input holds a buffer rather than the file named by its
+      // path, so its path and size cannot identify matching contents.
+      if (FI.Overridden)
+        continue;
+      (*LoadedInputFiles)[FI.StoredSize].push_back({&F, I + 1});
+    }
+  }
+}
+
+InputFileLoc ASTReader::getLoadedFileLoc(StringRef Path, off_t Size) {
+  if (!LoadedInputFiles)
+    buildLoadedInputFiles();
+
+  auto Known = LoadedInputFiles->find(Size);
+  if (Known == LoadedInputFiles->end())
+    return InputFileLoc();
+
+  StringRef WantedName = llvm::sys::path::filename(Path);
+  SmallString<128> Wanted;
+
+  for (const LoadedInputModuleFile &In : Known->second) {
+    InputFileInfo FI = getInputFileInfo(*In.F, In.InputID);
+
+    StringRef Unresolved = FI.UnresolvedImportedFilename;
+    if (llvm::sys::path::filename(Unresolved) != WantedName)
+      continue;
+
+    // Two directories can hold files that agree on name and on size, so the
+    // whole path decides.
+    if (Wanted.empty()) {
+      Wanted = Path;
+      FileMgr.makeAbsolutePath(Wanted, /*Canonicalize=*/true);
+    }
+    SmallString<128> Candidate;
+    {
+      auto Filename = ResolveImportedPath(PathBuf, Unresolved, *In.F);
+      Candidate = *Filename;
+    }
+    FileMgr.makeAbsolutePath(Candidate, /*Canonicalize=*/true);
+    if (StringRef(Candidate) != StringRef(Wanted))
+      continue;
----------------
ayokunle321 wrote:

I see `HeaderFileInfoTrait` checks size first, then mtime, and finally falls 
back to `FileEntry`.

I originally used `FileEntryRef` too, if you remember, but dropped it because 
resolving every file through `FileManager` caused unnecessary stat traffic. 
That was much earlier though when we were walking every file during module 
loading to find duplicates.

I then switched to name + size + mtime to avoid stat traffic, but dropped mtime 
per @rnk’s point, since the same file can have different mtimes across 
checkouts, copies, and filesystems.

And then that eventually evolved into this `makeAbsolutePath` approach you see 
here.

I think we can now follow the same approach as `HeaderFileInfoTrait`, minus 
mtime, falling back to `FileEntryRef` to handle the real-world files like 
symlinks and case-insensitive filesystems.

See 
[8098949](https://github.com/llvm/llvm-project/pull/209795/commits/80989491fd0d49d4d1d206f8c0ca29e49773d805)
 and let me know if you're happy with it.

https://github.com/llvm/llvm-project/pull/209795
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to