FrontendActions.cpp revision 7377399fbd7de555def64a5a9c64c71b11792528
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/Basic/FileManager.h" 13#include "clang/Frontend/AnalysisConsumer.h" 14#include "clang/Frontend/ASTConsumers.h" 15#include "clang/Frontend/ASTUnit.h" 16#include "clang/Frontend/CompilerInstance.h" 17#include "clang/Frontend/FixItRewriter.h" 18#include "clang/Frontend/FrontendDiagnostic.h" 19#include "clang/Frontend/Utils.h" 20#include "llvm/Support/raw_ostream.h" 21using namespace clang; 22 23ASTConsumer *AnalysisAction::CreateASTConsumer(CompilerInstance &CI, 24 llvm::StringRef InFile) { 25 return CreateAnalysisConsumer(CI.getPreprocessor(), 26 CI.getFrontendOpts().OutputFile, 27 CI.getAnalyzerOpts()); 28} 29 30ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, 31 llvm::StringRef InFile) { 32 return CreateASTPrinter(CI.createDefaultOutputFile(false, InFile)); 33} 34 35ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI, 36 llvm::StringRef InFile) { 37 return CreateASTPrinterXML(CI.createDefaultOutputFile(false, InFile, 38 "xml")); 39} 40 41ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, 42 llvm::StringRef InFile) { 43 return CreateASTDumper(); 44} 45 46ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI, 47 llvm::StringRef InFile) { 48 return CreateASTViewer(); 49} 50 51ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI, 52 llvm::StringRef InFile) { 53 return CreateDeclContextPrinter(); 54} 55 56ASTConsumer *DumpRecordAction::CreateASTConsumer(CompilerInstance &CI, 57 llvm::StringRef InFile) { 58 return CreateRecordLayoutDumper(); 59} 60 61ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, 62 llvm::StringRef InFile) { 63 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot; 64 if (CI.getFrontendOpts().RelocatablePCH && 65 Sysroot.empty()) { 66 CI.getDiagnostics().Report(diag::err_relocatable_without_without_isysroot); 67 return 0; 68 } 69 70 llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, InFile); 71 if (CI.getFrontendOpts().RelocatablePCH) 72 return CreatePCHGenerator(CI.getPreprocessor(), OS, Sysroot.c_str()); 73 74 return CreatePCHGenerator(CI.getPreprocessor(), OS); 75} 76 77ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, 78 llvm::StringRef InFile) { 79 return CreateHTMLPrinter(CI.createDefaultOutputFile(false, InFile), 80 CI.getPreprocessor()); 81} 82 83ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI, 84 llvm::StringRef InFile) { 85 return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance); 86} 87 88FixItAction::FixItAction() {} 89FixItAction::~FixItAction() {} 90 91ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI, 92 llvm::StringRef InFile) { 93 return new ASTConsumer(); 94} 95 96/// AddFixItLocations - Add any individual user specified "fix-it" locations, 97/// and return true on success. 98static bool AddFixItLocations(CompilerInstance &CI, 99 FixItRewriter &FixItRewrite) { 100 const std::vector<ParsedSourceLocation> &Locs = 101 CI.getFrontendOpts().FixItLocations; 102 for (unsigned i = 0, e = Locs.size(); i != e; ++i) { 103 const FileEntry *File = CI.getFileManager().getFile(Locs[i].FileName); 104 if (!File) { 105 CI.getDiagnostics().Report(diag::err_fe_unable_to_find_fixit_file) 106 << Locs[i].FileName; 107 return false; 108 } 109 110 RequestedSourceLocation Requested; 111 Requested.File = File; 112 Requested.Line = Locs[i].Line; 113 Requested.Column = Locs[i].Column; 114 FixItRewrite.addFixItLocation(Requested); 115 } 116 117 return true; 118} 119 120bool FixItAction::BeginSourceFileAction(CompilerInstance &CI, 121 llvm::StringRef Filename) { 122 Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(), 123 CI.getLangOpts())); 124 if (!AddFixItLocations(CI, *Rewriter)) 125 return false; 126 127 return true; 128} 129 130void FixItAction::EndSourceFileAction() { 131 const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts(); 132 Rewriter->WriteFixedFile(getCurrentFile(), FEOpts.OutputFile); 133} 134 135ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, 136 llvm::StringRef InFile) { 137 return CreateObjCRewriter(InFile, 138 CI.createDefaultOutputFile(true, InFile, "cpp"), 139 CI.getDiagnostics(), CI.getLangOpts(), 140 CI.getDiagnosticOpts().NoRewriteMacros); 141} 142 143ASTConsumer *RewriteBlocksAction::CreateASTConsumer(CompilerInstance &CI, 144 llvm::StringRef InFile) { 145 return CreateBlockRewriter(InFile, CI.getDiagnostics(), CI.getLangOpts()); 146} 147 148ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, 149 llvm::StringRef InFile) { 150 return new ASTConsumer(); 151} 152 153CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {} 154 155ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, 156 llvm::StringRef InFile) { 157 BackendAction BA = static_cast<BackendAction>(Act); 158 llvm::OwningPtr<llvm::raw_ostream> OS; 159 if (BA == Backend_EmitAssembly) 160 OS.reset(CI.createDefaultOutputFile(false, InFile, "s")); 161 else if (BA == Backend_EmitLL) 162 OS.reset(CI.createDefaultOutputFile(false, InFile, "ll")); 163 else if (BA == Backend_EmitBC) 164 OS.reset(CI.createDefaultOutputFile(true, InFile, "bc")); 165 166 return CreateBackendConsumer(BA, CI.getDiagnostics(), CI.getLangOpts(), 167 CI.getCodeGenOpts(), InFile, OS.take(), 168 CI.getLLVMContext()); 169} 170 171EmitAssemblyAction::EmitAssemblyAction() 172 : CodeGenAction(Backend_EmitAssembly) {} 173 174EmitBCAction::EmitBCAction() : CodeGenAction(Backend_EmitBC) {} 175 176EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {} 177 178EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {} 179