diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-01-26 02:40:48 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-01-26 02:40:48 +0000 |
commit | 61d679ab2831b161c857cf3f974312fbd4ef1efd (patch) | |
tree | 28dca5905a35f13993ff40bb855b1fee35af08a9 /lib/Rewrite/FrontendActions.cpp | |
parent | 7a776bec0232a5bf63b8d655194c18a201e5ee47 (diff) |
Introduce 3 new fixit options:
-fixit-recompile
applies fixits and recompiles the result
-fixit-to-temporary
applies fixits to temporary files
-fix-only-warnings">,
applies fixits for warnings only, not errors
Combining "-fixit-recompile -fixit-to-temporary" allows testing the result of fixits
without touching the original sources.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149027 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Rewrite/FrontendActions.cpp')
-rw-r--r-- | lib/Rewrite/FrontendActions.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/lib/Rewrite/FrontendActions.cpp b/lib/Rewrite/FrontendActions.cpp index f00e7fd9c9..c1568cd522 100644 --- a/lib/Rewrite/FrontendActions.cpp +++ b/lib/Rewrite/FrontendActions.cpp @@ -12,6 +12,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Parse/Parser.h" #include "clang/Basic/FileManager.h" +#include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/Utils.h" @@ -21,6 +22,7 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" +#include "llvm/Support/FileSystem.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -64,6 +66,22 @@ public: return Path.str(); } }; + +class FixItRewriteToTemp : public FixItOptions { +public: + std::string RewriteFilename(const std::string &Filename) { + llvm::SmallString<128> Path; + Path = llvm::sys::path::filename(Filename); + Path += "-%%%%%%%%"; + Path += llvm::sys::path::extension(Filename); + int fd; + llvm::SmallString<128> NewPath; + if (llvm::sys::fs::unique_file(Path.str(), fd, NewPath) + == llvm::errc::success) + ::close(fd); + return NewPath.str(); + } +}; } // end anonymous namespace bool FixItAction::BeginSourceFileAction(CompilerInstance &CI, @@ -86,6 +104,45 @@ void FixItAction::EndSourceFileAction() { Rewriter->WriteFixedFiles(); } +bool FixItRecompile::BeginInvocation(CompilerInstance &CI) { + + std::vector<std::pair<std::string, std::string> > RewrittenFiles; + bool err = false; + { + const FrontendOptions &FEOpts = CI.getFrontendOpts(); + llvm::OwningPtr<FrontendAction> FixAction(new SyntaxOnlyAction()); + FixAction->BeginSourceFile(CI, FEOpts.Inputs[0]); + + llvm::OwningPtr<FixItOptions> FixItOpts; + if (FEOpts.FixToTemporaries) + FixItOpts.reset(new FixItRewriteToTemp()); + else + FixItOpts.reset(new FixItRewriteInPlace()); + FixItOpts->Silent = true; + FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan; + FixItOpts->FixOnlyWarnings = FEOpts.FixOnlyWarnings; + FixItRewriter Rewriter(CI.getDiagnostics(), CI.getSourceManager(), + CI.getLangOpts(), FixItOpts.get()); + FixAction->Execute(); + + err = Rewriter.WriteFixedFiles(&RewrittenFiles); + + FixAction->EndSourceFile(); + CI.setSourceManager(0); + CI.setFileManager(0); + } + if (err) + return false; + CI.getDiagnosticClient().clear(); + + PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); + PPOpts.RemappedFiles.insert(PPOpts.RemappedFiles.end(), + RewrittenFiles.begin(), RewrittenFiles.end()); + PPOpts.RemappedFilesKeepOriginalName = false; + + return true; +} + //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// |