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