[clang-tools-extra] [clang-include-cleaner] Fix incorrect directory issue for writing files (PR #111375)

kadir çetinkaya via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 14 05:19:18 PDT 2024


================
@@ -305,8 +307,46 @@ int main(int argc, const char **argv) {
     }
   }
 
-  clang::tooling::ClangTool Tool(OptionsParser->getCompilations(),
-                                 OptionsParser->getSourcePathList());
+  auto VFS = llvm::vfs::getRealFileSystem();
+  auto &CDB = OptionsParser->getCompilations();
+  // CDBToAbsPaths is a map from the path in the compilation database to the
+  // writable absolute path of the file.
+  std::map<std::string, std::string> CDBToAbsPaths;
+  // if Edit is enabled, `Factory.editedFiles()` will contain the final code,
+  // along with the path given in the compilation database. That path can be
+  // absolute or relative, and if it is relative, it is relative to the
+  // "Directory" field in the compilation database. We need to make it
+  // absolute to write the final code to the correct path.
+  for (auto &Source : OptionsParser->getSourcePathList()) {
+    llvm::SmallString<256> AbsPath(Source);
+    if (auto Err = VFS->makeAbsolute(AbsPath)) {
+      llvm::errs() << "Failed to get absolute path for " << Source << " : "
+                   << Err.message() << '\n';
+      return 1;
+    }
+    std::vector<clang::tooling::CompileCommand> Cmds =
+        CDB.getCompileCommands(AbsPath);
+    if (Cmds.empty()) {
+      // Try with the original path.
+      Cmds = CDB.getCompileCommands(Source);
+      if (Cmds.empty()) {
+        // It should be found in the compilation database, even user didn't
+        // specify the compilation database, the `FixedCompilationDatabase` will
+        // create an entry from the arguments. So it is an error if we can't
+        // find the compile commands.
+        llvm::errs() << "No compile commands found for " << Source << '\n';
+        return 1;
+      }
+    }
+    for (const auto &Cmd : Cmds) {
+      llvm::SmallString<256> CDBPath(Cmd.Filename);
+      std::string Directory(Cmd.Directory);
+      llvm::sys::fs::make_absolute(Cmd.Directory, CDBPath);
+      CDBToAbsPaths[std::string(CDBPath)] = std::string(AbsPath);
+    }
+  }
----------------
kadircet wrote:

nit: you can extract all of this logic to a helper function:
```cpp
llvm::Expected<std::map<...>> mapInputsToAbsPaths(...);
...
int main(...) {
  ...
  auto CDBToAbsPaths = mapInputsToAbsPaths(CDB, Opts->OptionsParser->getSourcePathList());
  if (!CDBToAbsPaths) {
    return 1;
  }
  ...
}

https://github.com/llvm/llvm-project/pull/111375


More information about the cfe-commits mailing list