From 5f3b997e28899972e2ba23ec25e830d4066fa59a Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 14 Nov 2009 10:42:57 +0000 Subject: [PATCH] Add FrontendActions for all preprocessor based clang-cc actions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88774 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/FrontendActions.h | 59 ++++++++++++- lib/Frontend/FrontendActions.cpp | 105 ++++++++++++++++++++++- 2 files changed, 162 insertions(+), 2 deletions(-) diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index 3d6aab7fae..e755fe1b1b 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -15,6 +15,10 @@ namespace clang { class FixItRewriter; +//===----------------------------------------------------------------------===// +// AST Consumer Actions +//===----------------------------------------------------------------------===// + class AnalysisAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, @@ -121,7 +125,9 @@ public: virtual bool hasCodeCompletionSupport() const { return true; } }; -// Code Gen Actions +//===----------------------------------------------------------------------===// +// Code Gen AST Actions +//===----------------------------------------------------------------------===// class CodeGenAction : public ASTFrontendAction { private: @@ -154,6 +160,57 @@ public: EmitLLVMOnlyAction(); }; +//===----------------------------------------------------------------------===// +// Preprocessor Actions +//===----------------------------------------------------------------------===// + +class DumpRawTokensAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class DumpTokensAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class GeneratePTHAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class ParseOnlyAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class PreprocessOnlyAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class PrintParseAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class PrintPreprocessedAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); + + virtual bool hasPCHSupport() const { return true; } +}; + +class RewriteMacrosAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class RewriteTestAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + } // end namespace clang #endif diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 4494f87f34..3222471efc 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -9,6 +9,8 @@ #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" @@ -20,6 +22,10 @@ #include "llvm/Support/raw_ostream.h" using namespace clang; +//===----------------------------------------------------------------------===// +// AST Consumer Actions +//===----------------------------------------------------------------------===// + ASTConsumer *AnalysisAction::CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) { return CreateAnalysisConsumer(CI.getPreprocessor(), @@ -89,7 +95,7 @@ FixItAction::FixItAction() {} FixItAction::~FixItAction() {} ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile) { + llvm::StringRef InFile) { return new ASTConsumer(); } @@ -176,3 +182,100 @@ EmitBCAction::EmitBCAction() : CodeGenAction(Backend_EmitBC) {} EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {} EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {} + +//===----------------------------------------------------------------------===// +// Preprocessor Actions +//===----------------------------------------------------------------------===// + +void DumpRawTokensAction::ExecuteAction() { + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + SourceManager &SM = PP.getSourceManager(); + + // Start lexing the specified input file. + Lexer RawLex(SM.getMainFileID(), SM, PP.getLangOptions()); + RawLex.SetKeepWhitespaceMode(true); + + Token RawTok; + RawLex.LexFromRawLexer(RawTok); + while (RawTok.isNot(tok::eof)) { + PP.DumpToken(RawTok, true); + fprintf(stderr, "\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); + fprintf(stderr, "\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::errs() << "ERROR: PTH requires an seekable file for output!\n"; + ::exit(1); + } + llvm::raw_fd_ostream *OS = + CI.createDefaultOutputFile(true, getCurrentFile()); + CacheTokens(CI.getPreprocessor(), OS); +} + +void ParseOnlyAction::ExecuteAction() { + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + llvm::OwningPtr 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()); + llvm::OwningPtr PA(CreatePrintParserActionsAction(PP, OS)); + + Parser P(PP, *PA); + PP.EnterMainSourceFile(); + P.ParseTranslationUnit(); +} + +void PrintPreprocessedAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile()); + DoPrintPreprocessedInput(CI.getPreprocessor(), OS, + CI.getPreprocessorOutputOpts()); +} + +void RewriteMacrosAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); + RewriteMacrosInInput(CI.getPreprocessor(), OS); +} + +void RewriteTestAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile()); + DoRewriteTest(CI.getPreprocessor(), OS); +} -- 2.40.0