FrontendActions.cpp revision 9b414d3e2d0cb84512b55a3275a98490b090162a
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/Frontend/FrontendActions.h" 11#include "clang/AST/ASTConsumer.h" 12#include "clang/Lex/Pragma.h" 13#include "clang/Lex/Preprocessor.h" 14#include "clang/Parse/Parser.h" 15#include "clang/Basic/FileManager.h" 16#include "clang/Frontend/ASTConsumers.h" 17#include "clang/Frontend/ASTUnit.h" 18#include "clang/Frontend/CompilerInstance.h" 19#include "clang/Frontend/FrontendDiagnostic.h" 20#include "clang/Frontend/Utils.h" 21#include "llvm/ADT/OwningPtr.h" 22#include "llvm/Support/raw_ostream.h" 23using namespace clang; 24 25//===----------------------------------------------------------------------===// 26// Custom Actions 27//===----------------------------------------------------------------------===// 28 29ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, 30 llvm::StringRef InFile) { 31 return new ASTConsumer(); 32} 33 34void InitOnlyAction::ExecuteAction() { 35} 36 37//===----------------------------------------------------------------------===// 38// AST Consumer Actions 39//===----------------------------------------------------------------------===// 40 41ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, 42 llvm::StringRef InFile) { 43 if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) 44 return CreateASTPrinter(OS); 45 return 0; 46} 47 48ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI, 49 llvm::StringRef InFile) { 50 if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml")) 51 return CreateASTPrinterXML(OS); 52 return 0; 53} 54 55ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, 56 llvm::StringRef InFile) { 57 return CreateASTDumper(); 58} 59 60ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI, 61 llvm::StringRef InFile) { 62 return CreateASTViewer(); 63} 64 65ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI, 66 llvm::StringRef InFile) { 67 return CreateDeclContextPrinter(); 68} 69 70ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, 71 llvm::StringRef InFile) { 72 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot; 73 if (CI.getFrontendOpts().RelocatablePCH && 74 Sysroot.empty()) { 75 CI.getDiagnostics().Report(diag::err_relocatable_without_without_isysroot); 76 return 0; 77 } 78 79 llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, InFile); 80 if (!OS) 81 return 0; 82 83 if (CI.getFrontendOpts().RelocatablePCH) 84 return CreatePCHGenerator(CI.getPreprocessor(), OS, Sysroot.c_str()); 85 86 return CreatePCHGenerator(CI.getPreprocessor(), OS); 87} 88 89ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI, 90 llvm::StringRef InFile) { 91 return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance); 92} 93 94ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, 95 llvm::StringRef InFile) { 96 return new ASTConsumer(); 97} 98 99//===----------------------------------------------------------------------===// 100// Preprocessor Actions 101//===----------------------------------------------------------------------===// 102 103void DumpRawTokensAction::ExecuteAction() { 104 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 105 SourceManager &SM = PP.getSourceManager(); 106 107 // Start lexing the specified input file. 108 const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID()); 109 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions()); 110 RawLex.SetKeepWhitespaceMode(true); 111 112 Token RawTok; 113 RawLex.LexFromRawLexer(RawTok); 114 while (RawTok.isNot(tok::eof)) { 115 PP.DumpToken(RawTok, true); 116 llvm::errs() << "\n"; 117 RawLex.LexFromRawLexer(RawTok); 118 } 119} 120 121void DumpTokensAction::ExecuteAction() { 122 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 123 // Start preprocessing the specified input file. 124 Token Tok; 125 PP.EnterMainSourceFile(); 126 do { 127 PP.Lex(Tok); 128 PP.DumpToken(Tok, true); 129 llvm::errs() << "\n"; 130 } while (Tok.isNot(tok::eof)); 131} 132 133void GeneratePTHAction::ExecuteAction() { 134 CompilerInstance &CI = getCompilerInstance(); 135 if (CI.getFrontendOpts().OutputFile.empty() || 136 CI.getFrontendOpts().OutputFile == "-") { 137 // FIXME: Don't fail this way. 138 // FIXME: Verify that we can actually seek in the given file. 139 llvm::report_fatal_error("PTH requires a seekable file for output!"); 140 } 141 llvm::raw_fd_ostream *OS = 142 CI.createDefaultOutputFile(true, getCurrentFile()); 143 if (!OS) return; 144 145 CacheTokens(CI.getPreprocessor(), OS); 146} 147 148void ParseOnlyAction::ExecuteAction() { 149 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 150 llvm::OwningPtr<Action> PA(new MinimalAction(PP)); 151 152 Parser P(PP, *PA); 153 PP.EnterMainSourceFile(); 154 P.ParseTranslationUnit(); 155} 156 157void PreprocessOnlyAction::ExecuteAction() { 158 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 159 160 // Ignore unknown pragmas. 161 PP.AddPragmaHandler(0, new EmptyPragmaHandler()); 162 163 Token Tok; 164 // Start parsing the specified input file. 165 PP.EnterMainSourceFile(); 166 do { 167 PP.Lex(Tok); 168 } while (Tok.isNot(tok::eof)); 169} 170 171void PrintParseAction::ExecuteAction() { 172 CompilerInstance &CI = getCompilerInstance(); 173 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 174 llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile()); 175 if (!OS) return; 176 177 llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS)); 178 179 Parser P(PP, *PA); 180 PP.EnterMainSourceFile(); 181 P.ParseTranslationUnit(); 182} 183 184void PrintPreprocessedAction::ExecuteAction() { 185 CompilerInstance &CI = getCompilerInstance(); 186 // Output file needs to be set to 'Binary', to avoid converting Unix style 187 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>). 188 llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); 189 if (!OS) return; 190 191 DoPrintPreprocessedInput(CI.getPreprocessor(), OS, 192 CI.getPreprocessorOutputOpts()); 193} 194