@@ -282,6 +282,48 @@ std::function<bool(llvm::StringRef)> headerFilter() {
282282 };
283283}
284284
285+ // Maps absolute path of each files of each compilation commands to the
286+ // absolute path of the input file.
287+ llvm::Expected<std::map<std::string, std::string>>
288+ mapInputsToAbsPaths (clang::tooling::CompilationDatabase &CDB,
289+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
290+ const std::vector<std::string> &Inputs) {
291+ std::map<std::string, std::string> CDBToAbsPaths;
292+ // Factory.editedFiles()` will contain the final code, along with the
293+ // path given in the compilation database. That path can be
294+ // absolute or relative, and if it is relative, it is relative to the
295+ // "Directory" field in the compilation database. We need to make it
296+ // absolute to write the final code to the correct path.
297+ for (auto &Source : Inputs) {
298+ llvm::SmallString<256 > AbsPath (Source);
299+ if (auto Err = VFS->makeAbsolute (AbsPath)) {
300+ llvm::errs () << " Failed to get absolute path for " << Source << " : "
301+ << Err.message () << ' \n ' ;
302+ return std::move (llvm::errorCodeToError (Err));
303+ }
304+ std::vector<clang::tooling::CompileCommand> Cmds =
305+ CDB.getCompileCommands (AbsPath);
306+ if (Cmds.empty ()) {
307+ // It should be found in the compilation database, even user didn't
308+ // specify the compilation database, the `FixedCompilationDatabase` will
309+ // create an entry from the arguments. So it is an error if we can't
310+ // find the compile commands.
311+ std::string ErrorMsg =
312+ llvm::formatv (" No compile commands found for {0}" , AbsPath).str ();
313+ llvm::errs () << ErrorMsg << ' \n ' ;
314+ return llvm::make_error<llvm::StringError>(
315+ ErrorMsg, llvm::inconvertibleErrorCode ());
316+ }
317+ for (const auto &Cmd : Cmds) {
318+ llvm::SmallString<256 > CDBPath (Cmd.Filename );
319+ std::string Directory (Cmd.Directory );
320+ llvm::sys::fs::make_absolute (Cmd.Directory , CDBPath);
321+ CDBToAbsPaths[std::string (CDBPath)] = std::string (AbsPath);
322+ }
323+ }
324+ return CDBToAbsPaths;
325+ }
326+
285327} // namespace
286328} // namespace include_cleaner
287329} // namespace clang
@@ -311,40 +353,10 @@ int main(int argc, const char **argv) {
311353 auto &CDB = OptionsParser->getCompilations ();
312354 // CDBToAbsPaths is a map from the path in the compilation database to the
313355 // writable absolute path of the file.
314- std::map<std::string, std::string> CDBToAbsPaths;
315- // if Edit is enabled, `Factory.editedFiles()` will contain the final code,
316- // along with the path given in the compilation database. That path can be
317- // absolute or relative, and if it is relative, it is relative to the
318- // "Directory" field in the compilation database. We need to make it
319- // absolute to write the final code to the correct path.
320- for (auto &Source : OptionsParser->getSourcePathList ()) {
321- llvm::SmallString<256 > AbsPath (Source);
322- if (auto Err = VFS->makeAbsolute (AbsPath)) {
323- llvm::errs () << " Failed to get absolute path for " << Source << " : "
324- << Err.message () << ' \n ' ;
325- return 1 ;
326- }
327- std::vector<clang::tooling::CompileCommand> Cmds =
328- CDB.getCompileCommands (AbsPath);
329- if (Cmds.empty ()) {
330- // Try with the original path.
331- Cmds = CDB.getCompileCommands (Source);
332- if (Cmds.empty ()) {
333- // It should be found in the compilation database, even user didn't
334- // specify the compilation database, the `FixedCompilationDatabase` will
335- // create an entry from the arguments. So it is an error if we can't
336- // find the compile commands.
337- llvm::errs () << " No compile commands found for " << Source << ' \n ' ;
338- return 1 ;
339- }
340- }
341- for (const auto &Cmd : Cmds) {
342- llvm::SmallString<256 > CDBPath (Cmd.Filename );
343- std::string Directory (Cmd.Directory );
344- llvm::sys::fs::make_absolute (Cmd.Directory , CDBPath);
345- CDBToAbsPaths[std::string (CDBPath)] = std::string (AbsPath);
346- }
347- }
356+ auto CDBToAbsPaths =
357+ mapInputsToAbsPaths (CDB, VFS, OptionsParser->getSourcePathList ());
358+ if (!CDBToAbsPaths)
359+ return 1 ;
348360
349361 clang::tooling::ClangTool Tool (CDB, OptionsParser->getSourcePathList ());
350362
@@ -356,8 +368,8 @@ int main(int argc, const char **argv) {
356368 if (Edit) {
357369 for (const auto &NameAndContent : Factory.editedFiles ()) {
358370 llvm::StringRef FileName = NameAndContent.first ();
359- if (auto It = CDBToAbsPaths. find (FileName.str ());
360- It != CDBToAbsPaths. end ())
371+ if (auto It = CDBToAbsPaths-> find (FileName.str ());
372+ It != CDBToAbsPaths-> end ())
361373 FileName = It->second ;
362374
363375 const std::string &FinalCode = NameAndContent.second ;
0 commit comments