diff options
author | Haojian Wu <hokein@google.com> | 2016-08-09 08:26:19 +0000 |
---|---|---|
committer | Haojian Wu <hokein@google.com> | 2016-08-09 08:26:19 +0000 |
commit | c99f72868d1ce70695e2e4b7212d2fcd51e734b6 (patch) | |
tree | 7ce222ab0c03eecaa96b31497a09b574e9e2caf7 /clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp | |
parent | 7e5445267f8adc66db66ca09c2804cf8f6ebb960 (diff) | |
download | bcm5719-llvm-c99f72868d1ce70695e2e4b7212d2fcd51e734b6.tar.gz bcm5719-llvm-c99f72868d1ce70695e2e4b7212d2fcd51e734b6.zip |
[include-fixer] Support processing multiple files in one run.
Summary:
Previously, if we pass multiple files or a file pattern (e.g. /path/to/*.cc) to
include-fixer, include-fixer will apply all replacements to the first argument,
which probably causes crashes.
With this patch, include-fixer can process multiple files now.
Vim and Emacs integration are tested manually.
Reviewers: bkramer
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D23266
llvm-svn: 278102
Diffstat (limited to 'clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp')
-rw-r--r-- | clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp b/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp index 23b25e0b20a..769d7f48504 100644 --- a/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp +++ b/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp @@ -73,6 +73,7 @@ template <> struct MappingTraits<IncludeFixerContext> { static void mapping(IO &IO, IncludeFixerContext &Context) { IO.mapRequired("QuerySymbolInfos", Context.QuerySymbolInfos); IO.mapRequired("HeaderInfos", Context.HeaderInfos); + IO.mapRequired("FilePath", Context.FilePath); } }; } // namespace yaml @@ -203,7 +204,9 @@ createSymbolIndexManager(StringRef FilePath) { void writeToJson(llvm::raw_ostream &OS, const IncludeFixerContext& Context) { OS << "{\n" - " \"QuerySymbolInfos\": [\n"; + << " \"FilePath\": \"" + << llvm::yaml::escape(Context.getFilePath()) << "\",\n" + << " \"QuerySymbolInfos\": [\n"; for (const auto &Info : Context.getQuerySymbolInfos()) { OS << " {\"RawIdentifier\": \"" << Info.RawIdentifier << "\",\n"; OS << " \"Range\":{"; @@ -251,9 +254,6 @@ int includeFixerMain(int argc, const char **argv) { tool.mapVirtualFile(options.getSourcePathList().front(), Code->getBuffer()); } - StringRef FilePath = options.getSourcePathList().front(); - format::FormatStyle InsertStyle = format::getStyle("file", FilePath, Style); - if (!InsertHeader.empty()) { if (!STDINMode) { errs() << "Should be running in STDIN mode\n"; @@ -289,9 +289,10 @@ int includeFixerMain(int argc, const char **argv) { const IncludeFixerContext::HeaderInfo &RHS) { return LHS.QualifiedName == RHS.QualifiedName; }); - + format::FormatStyle InsertStyle = + format::getStyle("file", Context.getFilePath(), Style); auto Replacements = clang::include_fixer::createIncludeFixerReplacements( - Code->getBuffer(), FilePath, Context, InsertStyle, + Code->getBuffer(), Context, InsertStyle, /*AddQualifiers=*/IsUniqueQualifiedName); if (!Replacements) { errs() << "Failed to create replacements: " @@ -316,8 +317,8 @@ int includeFixerMain(int argc, const char **argv) { return 1; // Now run our tool. - include_fixer::IncludeFixerContext Context; - include_fixer::IncludeFixerActionFactory Factory(*SymbolIndexMgr, Context, + std::vector<include_fixer::IncludeFixerContext> Contexts; + include_fixer::IncludeFixerActionFactory Factory(*SymbolIndexMgr, Contexts, Style, MinimizeIncludePaths); if (tool.run(&Factory) != 0) { @@ -326,43 +327,49 @@ int includeFixerMain(int argc, const char **argv) { return 1; } + assert(!Contexts.empty()); + if (OutputHeaders) { - writeToJson(llvm::outs(), Context); + // FIXME: Print contexts of all processing files instead of the first one. + writeToJson(llvm::outs(), Contexts.front()); return 0; } - if (Context.getHeaderInfos().empty()) - return 0; + std::vector<tooling::Replacements> FixerReplacements; + for (const auto &Context : Contexts) { + StringRef FilePath = Context.getFilePath(); + format::FormatStyle InsertStyle = format::getStyle("file", FilePath, Style); + auto Buffer = llvm::MemoryBuffer::getFile(FilePath); + if (!Buffer) { + errs() << "Couldn't open file: " + FilePath.str() + ": " + << Buffer.getError().message() + "\n"; + return 1; + } - auto Buffer = llvm::MemoryBuffer::getFile(FilePath); - if (!Buffer) { - errs() << "Couldn't open file: " << FilePath << ": " - << Buffer.getError().message() << '\n'; - return 1; + auto Replacements = clang::include_fixer::createIncludeFixerReplacements( + Buffer.get()->getBuffer(), Context, InsertStyle); + if (!Replacements) { + errs() << "Failed to create replacement: " + << llvm::toString(Replacements.takeError()) << "\n"; + return 1; + } + FixerReplacements.push_back(*Replacements); } - auto Replacements = clang::include_fixer::createIncludeFixerReplacements( - /*Code=*/Buffer.get()->getBuffer(), FilePath, Context, InsertStyle); - if (!Replacements) { - errs() << "Failed to create header insertion replacement: " - << llvm::toString(Replacements.takeError()) << "\n"; - return 1; + if (!Quiet) { + for (const auto &Context : Contexts) { + if (!Context.getHeaderInfos().empty()) { + llvm::errs() << "Added #include " + << Context.getHeaderInfos().front().Header << " for " + << Context.getFilePath() << "\n"; + } + } } - if (!Quiet) - llvm::errs() << "Added #include " << Context.getHeaderInfos().front().Header - << "\n"; - - // Set up a new source manager for applying the resulting replacements. - IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions); - DiagnosticsEngine Diagnostics(new DiagnosticIDs, &*DiagOpts); - TextDiagnosticPrinter DiagnosticPrinter(outs(), &*DiagOpts); - SourceManager SM(Diagnostics, tool.getFiles()); - Diagnostics.setClient(&DiagnosticPrinter, false); - if (STDINMode) { - auto ChangedCode = - tooling::applyAllReplacements(Code->getBuffer(), *Replacements); + assert(FixerReplacements.size() == 1); + auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), + FixerReplacements.front()); if (!ChangedCode) { llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n"; return 1; @@ -371,9 +378,21 @@ int includeFixerMain(int argc, const char **argv) { return 0; } + // Set up a new source manager for applying the resulting replacements. + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions); + DiagnosticsEngine Diagnostics(new DiagnosticIDs, &*DiagOpts); + TextDiagnosticPrinter DiagnosticPrinter(outs(), &*DiagOpts); + SourceManager SM(Diagnostics, tool.getFiles()); + Diagnostics.setClient(&DiagnosticPrinter, false); + // Write replacements to disk. Rewriter Rewrites(SM, LangOptions()); - tooling::applyAllReplacements(*Replacements, Rewrites); + for (const auto Replacement : FixerReplacements) { + if (!tooling::applyAllReplacements(Replacement, Rewrites)) { + llvm::errs() << "Failed to apply replacements.\n"; + return 1; + } + } return Rewrites.overwriteChangedFiles(); } |