From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/lib/Rewrite/FrontendActions.cpp | 183 ++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 clang/lib/Rewrite/FrontendActions.cpp (limited to 'clang/lib/Rewrite/FrontendActions.cpp') diff --git a/clang/lib/Rewrite/FrontendActions.cpp b/clang/lib/Rewrite/FrontendActions.cpp new file mode 100644 index 0000000..1753325 --- /dev/null +++ b/clang/lib/Rewrite/FrontendActions.cpp @@ -0,0 +1,183 @@ +//===--- 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/FrontendActions.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" +#include "llvm/Support/FileSystem.h" + +using namespace clang; + +//===----------------------------------------------------------------------===// +// AST Consumer Actions +//===----------------------------------------------------------------------===// + +ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) + return CreateHTMLPrinter(OS, CI.getPreprocessor()); + return 0; +} + +FixItAction::FixItAction() {} +FixItAction::~FixItAction() {} + +ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + return new ASTConsumer(); +} + +namespace { +class FixItRewriteInPlace : public FixItOptions { +public: + std::string RewriteFilename(const std::string &Filename, int &fd) { + fd = -1; + 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, int &fd) { + fd = -1; + SmallString<128> Path(Filename); + llvm::sys::path::replace_extension(Path, + NewSuffix + llvm::sys::path::extension(Path)); + return Path.str(); + } +}; + +class FixItRewriteToTemp : public FixItOptions { +public: + std::string RewriteFilename(const std::string &Filename, int &fd) { + SmallString<128> Path; + Path = llvm::sys::path::filename(Filename); + Path += "-%%%%%%%%"; + Path += llvm::sys::path::extension(Filename); + SmallString<128> NewPath; + llvm::sys::fs::unique_file(Path.str(), fd, NewPath); + return NewPath.str(); + } +}; +} // end anonymous namespace + +bool FixItAction::BeginSourceFileAction(CompilerInstance &CI, + 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(); +} + +bool FixItRecompile::BeginInvocation(CompilerInstance &CI) { + + std::vector > RewrittenFiles; + bool err = false; + { + const FrontendOptions &FEOpts = CI.getFrontendOpts(); + OwningPtr FixAction(new SyntaxOnlyAction()); + if (FixAction->BeginSourceFile(CI, FEOpts.Inputs[0])) { + OwningPtr 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); + } else { + err = true; + } + } + if (err) + return false; + CI.getDiagnosticClient().clear(); + CI.getDiagnostics().Reset(); + + PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); + PPOpts.RemappedFiles.insert(PPOpts.RemappedFiles.end(), + RewrittenFiles.begin(), RewrittenFiles.end()); + PPOpts.RemappedFilesKeepOriginalName = false; + + return true; +} + +//===----------------------------------------------------------------------===// +// Preprocessor Actions +//===----------------------------------------------------------------------===// + +ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) { + if (CI.getLangOpts().ObjCNonFragileABI) + return CreateModernObjCRewriter(InFile, OS, + CI.getDiagnostics(), CI.getLangOpts(), + CI.getDiagnosticOpts().NoRewriteMacros); + return CreateObjCRewriter(InFile, OS, + CI.getDiagnostics(), CI.getLangOpts(), + CI.getDiagnosticOpts().NoRewriteMacros); + } + return 0; +} + +void RewriteMacrosAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); + if (!OS) return; + + RewriteMacrosInInput(CI.getPreprocessor(), OS); +} + +void RewriteTestAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile()); + if (!OS) return; + + DoRewriteTest(CI.getPreprocessor(), OS); +} -- cgit v1.2.3