[clang-tools-extra] [clang-include-cleaner] Fix incorrect directory issue for writing files (PR #111375)
Byoungchan Lee via cfe-commits
cfe-commits at lists.llvm.org
Sun Oct 13 04:25:52 PDT 2024
================
@@ -305,8 +307,84 @@ 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) {
+ // 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.
+ // There are several cases to consider:
+ // 1. The "Directory" field isn't same as the current working directory.
+ // 2. The file path resolved from the "Directory" field is not writable.
+ // For these cases, we need to find a writable path for the file.
+ // To effectively handle these cases, we only need to consider
+ // the files from `getSourcePathList()` that are present in the compilation
+ // database.
+ 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()) {
+ continue;
+ }
+ }
+ // We only need the first command to get the directory.
+ auto Cmd = Cmds[0];
+ llvm::SmallString<256> CDBPath(Cmd.Filename);
+ std::string Directory(Cmd.Directory);
+
+ if (llvm::sys::path::is_absolute(CDBPath)) {
+ // If the path in the compilation database is already absolute, we don't
+ // need to do anything.
+ CDBToAbsPaths[static_cast<std::string>(CDBPath)] =
+ static_cast<std::string>(AbsPath);
+ } else {
+ auto Sept = llvm::sys::path::get_separator();
+ // First, try to find the file based on the compilation database.
+ llvm::Twine FilePathTwine = Directory + Sept + CDBPath;
+ llvm::SmallString<256> FilePath;
+ FilePathTwine.toVector(FilePath);
+ // Check if it is writable.
+ if (llvm::sys::fs::access(FilePath, llvm::sys::fs::AccessMode::Write) !=
+ std::error_code()) {
----------------
bc-lee wrote:
It turns out we don't need to check for this. I removed those checks.
https://github.com/llvm/llvm-project/pull/111375
More information about the cfe-commits
mailing list