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