19b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//===--- FrontendActions.cpp ----------------------------------------------===//
29b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//
39b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//                     The LLVM Compiler Infrastructure
49b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//
59b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar// This file is distributed under the University of Illinois Open Source
69b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar// License. See LICENSE.TXT for details.
79b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//
89b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//===----------------------------------------------------------------------===//
99b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
109b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Rewrite/FrontendActions.h"
119b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/AST/ASTConsumer.h"
129b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Lex/Preprocessor.h"
139b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Parse/Parser.h"
149b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Basic/FileManager.h"
159b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Frontend/CompilerInstance.h"
169b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h"
179b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Frontend/Utils.h"
189b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Rewrite/ASTConsumers.h"
199b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Rewrite/FixItRewriter.h"
209b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Rewrite/Rewriters.h"
219b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "llvm/ADT/OwningPtr.h"
229b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "llvm/Support/raw_ostream.h"
2303013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h"
249b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbarusing namespace clang;
259b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
269b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//===----------------------------------------------------------------------===//
279b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar// AST Consumer Actions
289b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//===----------------------------------------------------------------------===//
299b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
309b414d3e2d0cb84512b55a3275a98490b090162aDaniel DunbarASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI,
315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                                StringRef InFile) {
325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
339b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar    return CreateHTMLPrinter(OS, CI.getPreprocessor());
349b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  return 0;
359b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar}
369b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
379b414d3e2d0cb84512b55a3275a98490b090162aDaniel DunbarFixItAction::FixItAction() {}
389b414d3e2d0cb84512b55a3275a98490b090162aDaniel DunbarFixItAction::~FixItAction() {}
399b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
409b414d3e2d0cb84512b55a3275a98490b090162aDaniel DunbarASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI,
415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                            StringRef InFile) {
429b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  return new ASTConsumer();
439b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar}
449b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
4579ba2a6379f87fa137377c3f55ff993b9e5cc144Benjamin Kramernamespace {
4696872c44700bcfc184bf99a6755898e7930f65edNick Lewyckyclass FixItRewriteInPlace : public FixItOptions {
4796872c44700bcfc184bf99a6755898e7930f65edNick Lewyckypublic:
4896872c44700bcfc184bf99a6755898e7930f65edNick Lewycky  std::string RewriteFilename(const std::string &Filename) { return Filename; }
4996872c44700bcfc184bf99a6755898e7930f65edNick Lewycky};
5096872c44700bcfc184bf99a6755898e7930f65edNick Lewycky
511450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewyckyclass FixItActionSuffixInserter : public FixItOptions {
529b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  std::string NewSuffix;
539b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
549b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbarpublic:
551450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky  FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan)
561450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky    : NewSuffix(NewSuffix) {
571450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky      this->FixWhatYouCan = FixWhatYouCan;
581450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky  }
599b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
609b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  std::string RewriteFilename(const std::string &Filename) {
61d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer    llvm::SmallString<128> Path(Filename);
62d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer    llvm::sys::path::replace_extension(Path,
63d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer      NewSuffix + llvm::sys::path::extension(Path));
64d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer    return Path.str();
659b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  }
669b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar};
6779ba2a6379f87fa137377c3f55ff993b9e5cc144Benjamin Kramer} // end anonymous namespace
689b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
699b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbarbool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                        StringRef Filename) {
719b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
729b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  if (!FEOpts.FixItSuffix.empty()) {
731450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky    FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix,
741450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky                                                  FEOpts.FixWhatYouCan));
759b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  } else {
7696872c44700bcfc184bf99a6755898e7930f65edNick Lewycky    FixItOpts.reset(new FixItRewriteInPlace);
7796872c44700bcfc184bf99a6755898e7930f65edNick Lewycky    FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
789b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  }
799b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
801450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky                                   CI.getLangOpts(), FixItOpts.get()));
819b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  return true;
829b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar}
839b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
849b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbarvoid FixItAction::EndSourceFileAction() {
859b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  // Otherwise rewrite all files.
869b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  Rewriter->WriteFixedFiles();
879b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar}
889b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
899b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//===----------------------------------------------------------------------===//
909b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar// Preprocessor Actions
919b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//===----------------------------------------------------------------------===//
929b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
939b414d3e2d0cb84512b55a3275a98490b090162aDaniel DunbarASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,
945f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                                  StringRef InFile) {
955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp"))
969b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar    return CreateObjCRewriter(InFile, OS,
979b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar                              CI.getDiagnostics(), CI.getLangOpts(),
989b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar                              CI.getDiagnosticOpts().NoRewriteMacros);
999b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  return 0;
1009b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar}
1019b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
1029b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbarvoid RewriteMacrosAction::ExecuteAction() {
1039b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  CompilerInstance &CI = getCompilerInstance();
1045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
1059b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  if (!OS) return;
1069b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
1079b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  RewriteMacrosInInput(CI.getPreprocessor(), OS);
1089b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar}
1099b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
1109b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbarvoid RewriteTestAction::ExecuteAction() {
1119b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  CompilerInstance &CI = getCompilerInstance();
1125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
1139b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  if (!OS) return;
1149b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar
1159b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar  DoRewriteTest(CI.getPreprocessor(), OS);
1169b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar}
117