//===--- FrontendActions.cpp ----------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "clang/Rewrite/FrontendActions.h" #include "clang/AST/ASTConsumer.h" #include "clang/Lex/Preprocessor.h" #include "clang/Parse/Parser.h" #include "clang/Basic/FileManager.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/Utils.h" #include "clang/Rewrite/ASTConsumers.h" #include "clang/Rewrite/FixItRewriter.h" #include "clang/Rewrite/Rewriters.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" using namespace clang; //===----------------------------------------------------------------------===// // AST Consumer Actions //===----------------------------------------------------------------------===// ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) { if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) return CreateHTMLPrinter(OS, CI.getPreprocessor()); return 0; } FixItAction::FixItAction() {} FixItAction::~FixItAction() {} ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) { return new ASTConsumer(); } namespace { class FixItRewriteInPlace : public FixItOptions { public: std::string RewriteFilename(const std::string &Filename) { return Filename; } }; class FixItActionSuffixInserter : public FixItOptions { std::string NewSuffix; public: FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan) : NewSuffix(NewSuffix) { this->FixWhatYouCan = FixWhatYouCan; } std::string RewriteFilename(const std::string &Filename) { llvm::SmallString<128> Path(Filename); llvm::sys::path::replace_extension(Path, NewSuffix + llvm::sys::path::extension(Path)); return Path.str(); } }; } // end anonymous namespace bool FixItAction::BeginSourceFileAction(CompilerInstance &CI, llvm::StringRef Filename) { const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts(); if (!FEOpts.FixItSuffix.empty()) { FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix, FEOpts.FixWhatYouCan)); } else { FixItOpts.reset(new FixItRewriteInPlace); FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan; } Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(), CI.getLangOpts(), FixItOpts.get())); return true; } void FixItAction::EndSourceFileAction() { // Otherwise rewrite all files. Rewriter->WriteFixedFiles(); } //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) { if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) return CreateObjCRewriter(InFile, OS, CI.getDiagnostics(), CI.getLangOpts(), CI.getDiagnosticOpts().NoRewriteMacros); return 0; } void RewriteMacrosAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); if (!OS) return; RewriteMacrosInInput(CI.getPreprocessor(), OS); } void RewriteTestAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile()); if (!OS) return; DoRewriteTest(CI.getPreprocessor(), OS); }