Home | History | Annotate | Download | only in Rewrite
      1 //===--- FrontendActions.cpp ----------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "clang/Rewrite/FrontendActions.h"
     11 #include "clang/AST/ASTConsumer.h"
     12 #include "clang/Lex/Preprocessor.h"
     13 #include "clang/Parse/Parser.h"
     14 #include "clang/Basic/FileManager.h"
     15 #include "clang/Frontend/CompilerInstance.h"
     16 #include "clang/Frontend/FrontendDiagnostic.h"
     17 #include "clang/Frontend/Utils.h"
     18 #include "clang/Rewrite/ASTConsumers.h"
     19 #include "clang/Rewrite/FixItRewriter.h"
     20 #include "clang/Rewrite/Rewriters.h"
     21 #include "llvm/ADT/OwningPtr.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 #include "llvm/Support/Path.h"
     24 using namespace clang;
     25 
     26 //===----------------------------------------------------------------------===//
     27 // AST Consumer Actions
     28 //===----------------------------------------------------------------------===//
     29 
     30 ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI,
     31                                                 StringRef InFile) {
     32   if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
     33     return CreateHTMLPrinter(OS, CI.getPreprocessor());
     34   return 0;
     35 }
     36 
     37 FixItAction::FixItAction() {}
     38 FixItAction::~FixItAction() {}
     39 
     40 ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI,
     41                                             StringRef InFile) {
     42   return new ASTConsumer();
     43 }
     44 
     45 namespace {
     46 class FixItRewriteInPlace : public FixItOptions {
     47 public:
     48   std::string RewriteFilename(const std::string &Filename) { return Filename; }
     49 };
     50 
     51 class FixItActionSuffixInserter : public FixItOptions {
     52   std::string NewSuffix;
     53 
     54 public:
     55   FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan)
     56     : NewSuffix(NewSuffix) {
     57       this->FixWhatYouCan = FixWhatYouCan;
     58   }
     59 
     60   std::string RewriteFilename(const std::string &Filename) {
     61     llvm::SmallString<128> Path(Filename);
     62     llvm::sys::path::replace_extension(Path,
     63       NewSuffix + llvm::sys::path::extension(Path));
     64     return Path.str();
     65   }
     66 };
     67 } // end anonymous namespace
     68 
     69 bool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
     70                                         StringRef Filename) {
     71   const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
     72   if (!FEOpts.FixItSuffix.empty()) {
     73     FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix,
     74                                                   FEOpts.FixWhatYouCan));
     75   } else {
     76     FixItOpts.reset(new FixItRewriteInPlace);
     77     FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
     78   }
     79   Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
     80                                    CI.getLangOpts(), FixItOpts.get()));
     81   return true;
     82 }
     83 
     84 void FixItAction::EndSourceFileAction() {
     85   // Otherwise rewrite all files.
     86   Rewriter->WriteFixedFiles();
     87 }
     88 
     89 //===----------------------------------------------------------------------===//
     90 // Preprocessor Actions
     91 //===----------------------------------------------------------------------===//
     92 
     93 ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,
     94                                                   StringRef InFile) {
     95   if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp"))
     96     return CreateObjCRewriter(InFile, OS,
     97                               CI.getDiagnostics(), CI.getLangOpts(),
     98                               CI.getDiagnosticOpts().NoRewriteMacros);
     99   return 0;
    100 }
    101 
    102 void RewriteMacrosAction::ExecuteAction() {
    103   CompilerInstance &CI = getCompilerInstance();
    104   raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
    105   if (!OS) return;
    106 
    107   RewriteMacrosInInput(CI.getPreprocessor(), OS);
    108 }
    109 
    110 void RewriteTestAction::ExecuteAction() {
    111   CompilerInstance &CI = getCompilerInstance();
    112   raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
    113   if (!OS) return;
    114 
    115   DoRewriteTest(CI.getPreprocessor(), OS);
    116 }
    117