-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang-include-cleaner] Fix incorrect directory issue for writing files #111375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
23b90bb
eef397c
2409d6f
0c9477d
dec9be8
b39f36e
3a0f02e
c65d828
11f78a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -173,9 +173,11 @@ class Action : public clang::ASTFrontendAction { | |
| if (!HTMLReportPath.empty()) | ||
| writeHTML(); | ||
|
|
||
| llvm::StringRef Path = | ||
| SM.getFileEntryRefForID(SM.getMainFileID())->getName(); | ||
| assert(!Path.empty() && "Main file path not known?"); | ||
| // Source File's path of compiler invocation, converted to absolute path. | ||
| llvm::SmallString<256> AbsPath( | ||
| SM.getFileEntryRefForID(SM.getMainFileID())->getName()); | ||
| assert(!AbsPath.empty() && "Main file path not known?"); | ||
| SM.getFileManager().makeAbsolutePath(AbsPath); | ||
| llvm::StringRef Code = SM.getBufferData(SM.getMainFileID()); | ||
|
|
||
| auto Results = | ||
|
|
@@ -185,7 +187,7 @@ class Action : public clang::ASTFrontendAction { | |
| Results.Missing.clear(); | ||
| if (!Remove) | ||
| Results.Unused.clear(); | ||
| std::string Final = fixIncludes(Results, Path, Code, getStyle(Path)); | ||
| std::string Final = fixIncludes(Results, AbsPath, Code, getStyle(AbsPath)); | ||
|
|
||
| if (Print.getNumOccurrences()) { | ||
| switch (Print) { | ||
|
|
@@ -202,7 +204,7 @@ class Action : public clang::ASTFrontendAction { | |
| } | ||
|
|
||
| if (!Results.Missing.empty() || !Results.Unused.empty()) | ||
| EditedFiles.try_emplace(Path, Final); | ||
| EditedFiles.try_emplace(AbsPath, Final); | ||
| } | ||
|
|
||
| void writeHTML() { | ||
|
|
@@ -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); | ||
| } | ||
| } | ||
|
||
|
|
||
| clang::tooling::ClangTool Tool(CDB, OptionsParser->getSourcePathList()); | ||
|
|
||
| auto HeaderFilter = headerFilter(); | ||
| if (!HeaderFilter) | ||
|
|
@@ -316,6 +356,10 @@ int main(int argc, const char **argv) { | |
| if (Edit) { | ||
| for (const auto &NameAndContent : Factory.editedFiles()) { | ||
| llvm::StringRef FileName = NameAndContent.first(); | ||
| if (auto It = CDBToAbsPaths.find(FileName.str()); | ||
| It != CDBToAbsPaths.end()) | ||
| FileName = It->second; | ||
|
|
||
| const std::string &FinalCode = NameAndContent.second; | ||
| if (auto Err = llvm::writeToOutput( | ||
| FileName, [&](llvm::raw_ostream &OS) -> llvm::Error { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you also drop the mention of
Editfrom the comment?