diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp new file mode 100644 index 0000000..6cd960b --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp @@ -0,0 +1,272 @@ +//===--- 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/Frontend/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/AnalysisConsumer.h" +#include "clang/Frontend/ASTConsumers.h" +#include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FixItRewriter.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/Utils.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Support/raw_ostream.h" +using namespace clang; + +//===----------------------------------------------------------------------===// +// Custom Actions +//===----------------------------------------------------------------------===// + +ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return new ASTConsumer(); +} + +void InitOnlyAction::ExecuteAction() { +} + +//===----------------------------------------------------------------------===// +// AST Consumer Actions +//===----------------------------------------------------------------------===// + +ASTConsumer *AnalysisAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return CreateAnalysisConsumer(CI.getPreprocessor(), + CI.getFrontendOpts().OutputFile, + CI.getAnalyzerOpts()); +} + +ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) + return CreateASTPrinter(OS); + return 0; +} + +ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml")) + return CreateASTPrinterXML(OS); + return 0; +} + +ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return CreateASTDumper(); +} + +ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return CreateASTViewer(); +} + +ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return CreateDeclContextPrinter(); +} + +ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot; + if (CI.getFrontendOpts().RelocatablePCH && + Sysroot.empty()) { + CI.getDiagnostics().Report(diag::err_relocatable_without_without_isysroot); + return 0; + } + + llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, InFile); + if (!OS) + return 0; + + if (CI.getFrontendOpts().RelocatablePCH) + return CreatePCHGenerator(CI.getPreprocessor(), OS, Sysroot.c_str()); + + return CreatePCHGenerator(CI.getPreprocessor(), OS); +} + +ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) + return CreateHTMLPrinter(OS, CI.getPreprocessor()); + return 0; +} + +ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance); +} + +FixItAction::FixItAction() {} +FixItAction::~FixItAction() {} + +ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return new ASTConsumer(); +} + +class FixItActionSuffixInserter : public FixItPathRewriter { + std::string NewSuffix; + +public: + explicit FixItActionSuffixInserter(std::string NewSuffix) + : NewSuffix(NewSuffix) {} + + std::string RewriteFilename(const std::string &Filename) { + llvm::sys::Path Path(Filename); + std::string Suffix = Path.getSuffix(); + Path.eraseSuffix(); + Path.appendSuffix(NewSuffix + "." + Suffix); + return Path.c_str(); + } +}; + +bool FixItAction::BeginSourceFileAction(CompilerInstance &CI, + llvm::StringRef Filename) { + const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts(); + if (!FEOpts.FixItSuffix.empty()) { + PathRewriter.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix)); + } else { + PathRewriter.reset(); + } + Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(), + CI.getLangOpts(), PathRewriter.get())); + return true; +} + +void FixItAction::EndSourceFileAction() { + // Otherwise rewrite all files. + Rewriter->WriteFixedFiles(); +} + +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; +} + +ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return new ASTConsumer(); +} + +//===----------------------------------------------------------------------===// +// Preprocessor Actions +//===----------------------------------------------------------------------===// + +void DumpRawTokensAction::ExecuteAction() { + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + SourceManager &SM = PP.getSourceManager(); + + // Start lexing the specified input file. + const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID()); + Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions()); + RawLex.SetKeepWhitespaceMode(true); + + Token RawTok; + RawLex.LexFromRawLexer(RawTok); + while (RawTok.isNot(tok::eof)) { + PP.DumpToken(RawTok, true); + llvm::errs() << "\n"; + RawLex.LexFromRawLexer(RawTok); + } +} + +void DumpTokensAction::ExecuteAction() { + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + // Start preprocessing the specified input file. + Token Tok; + PP.EnterMainSourceFile(); + do { + PP.Lex(Tok); + PP.DumpToken(Tok, true); + llvm::errs() << "\n"; + } while (Tok.isNot(tok::eof)); +} + +void GeneratePTHAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + if (CI.getFrontendOpts().OutputFile.empty() || + CI.getFrontendOpts().OutputFile == "-") { + // FIXME: Don't fail this way. + // FIXME: Verify that we can actually seek in the given file. + llvm::report_fatal_error("PTH requires a seekable file for output!"); + } + llvm::raw_fd_ostream *OS = + CI.createDefaultOutputFile(true, getCurrentFile()); + if (!OS) return; + + CacheTokens(CI.getPreprocessor(), OS); +} + +void ParseOnlyAction::ExecuteAction() { + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + llvm::OwningPtr<Action> PA(new MinimalAction(PP)); + + Parser P(PP, *PA); + PP.EnterMainSourceFile(); + P.ParseTranslationUnit(); +} + +void PreprocessOnlyAction::ExecuteAction() { + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + + Token Tok; + // Start parsing the specified input file. + PP.EnterMainSourceFile(); + do { + PP.Lex(Tok); + } while (Tok.isNot(tok::eof)); +} + +void PrintParseAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile()); + if (!OS) return; + + llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS)); + + Parser P(PP, *PA); + PP.EnterMainSourceFile(); + P.ParseTranslationUnit(); +} + +void PrintPreprocessedAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + // Output file needs to be set to 'Binary', to avoid converting Unix style + // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>). + llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); + if (!OS) return; + + DoPrintPreprocessedInput(CI.getPreprocessor(), OS, + CI.getPreprocessorOutputOpts()); +} + +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); +} |