ExecuteCompilerInvocation.cpp revision 263508
1//===--- ExecuteCompilerInvocation.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// This file holds ExecuteCompilerInvocation(). It is split into its own file to
11// minimize the impact of pulling in essentially everything else in Clang.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/FrontendTool/Utils.h"
16#include "clang/ARCMigrate/ARCMTActions.h"
17#include "clang/CodeGen/CodeGenAction.h"
18#include "clang/Driver/Options.h"
19#include "clang/Frontend/CompilerInstance.h"
20#include "clang/Frontend/CompilerInvocation.h"
21#include "clang/Frontend/FrontendActions.h"
22#include "clang/Frontend/FrontendDiagnostic.h"
23#include "clang/Frontend/FrontendPluginRegistry.h"
24#include "clang/Rewrite/Frontend/FrontendActions.h"
25#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
26#include "llvm/Option/OptTable.h"
27#include "llvm/Option/Option.h"
28#include "llvm/Support/DynamicLibrary.h"
29#include "llvm/Support/ErrorHandling.h"
30using namespace clang;
31using namespace llvm::opt;
32
33static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
34  using namespace clang::frontend;
35  StringRef Action("unknown");
36
37  switch (CI.getFrontendOpts().ProgramAction) {
38  case ASTDeclList:            return new ASTDeclListAction();
39  case ASTDump:                return new ASTDumpAction();
40  case ASTPrint:               return new ASTPrintAction();
41  case ASTView:                return new ASTViewAction();
42  case DumpRawTokens:          return new DumpRawTokensAction();
43  case DumpTokens:             return new DumpTokensAction();
44  case EmitAssembly:           return new EmitAssemblyAction();
45  case EmitBC:                 return new EmitBCAction();
46#ifdef CLANG_ENABLE_REWRITER
47  case EmitHTML:               return new HTMLPrintAction();
48#else
49  case EmitHTML:               Action = "EmitHTML"; break;
50#endif
51  case EmitLLVM:               return new EmitLLVMAction();
52  case EmitLLVMOnly:           return new EmitLLVMOnlyAction();
53  case EmitCodeGenOnly:        return new EmitCodeGenOnlyAction();
54  case EmitObj:                return new EmitObjAction();
55#ifdef CLANG_ENABLE_REWRITER
56  case FixIt:                  return new FixItAction();
57#else
58  case FixIt:                  Action = "FixIt"; break;
59#endif
60  case GenerateModule:         return new GenerateModuleAction;
61  case GeneratePCH:            return new GeneratePCHAction;
62  case GeneratePTH:            return new GeneratePTHAction();
63  case InitOnly:               return new InitOnlyAction();
64  case ParseSyntaxOnly:        return new SyntaxOnlyAction();
65  case ModuleFileInfo:         return new DumpModuleInfoAction();
66
67  case PluginAction: {
68    for (FrontendPluginRegistry::iterator it =
69           FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
70         it != ie; ++it) {
71      if (it->getName() == CI.getFrontendOpts().ActionName) {
72        OwningPtr<PluginASTAction> P(it->instantiate());
73        if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs))
74          return 0;
75        return P.take();
76      }
77    }
78
79    CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
80      << CI.getFrontendOpts().ActionName;
81    return 0;
82  }
83
84  case PrintDeclContext:       return new DeclContextPrintAction();
85  case PrintPreamble:          return new PrintPreambleAction();
86  case PrintPreprocessedInput: {
87    if (CI.getPreprocessorOutputOpts().RewriteIncludes) {
88#ifdef CLANG_ENABLE_REWRITER
89      return new RewriteIncludesAction();
90#else
91      Action = "RewriteIncludesAction";
92      break;
93#endif
94    }
95    return new PrintPreprocessedAction();
96  }
97
98#ifdef CLANG_ENABLE_REWRITER
99  case RewriteMacros:          return new RewriteMacrosAction();
100  case RewriteObjC:            return new RewriteObjCAction();
101  case RewriteTest:            return new RewriteTestAction();
102#else
103  case RewriteMacros:          Action = "RewriteMacros"; break;
104  case RewriteObjC:            Action = "RewriteObjC"; break;
105  case RewriteTest:            Action = "RewriteTest"; break;
106#endif
107#ifdef CLANG_ENABLE_ARCMT
108  case MigrateSource:          return new arcmt::MigrateSourceAction();
109#else
110  case MigrateSource:          Action = "MigrateSource"; break;
111#endif
112#ifdef CLANG_ENABLE_STATIC_ANALYZER
113  case RunAnalysis:            return new ento::AnalysisAction();
114#else
115  case RunAnalysis:            Action = "RunAnalysis"; break;
116#endif
117  case RunPreprocessorOnly:    return new PreprocessOnlyAction();
118  }
119
120#if !defined(CLANG_ENABLE_ARCMT) || !defined(CLANG_ENABLE_STATIC_ANALYZER) \
121  || !defined(CLANG_ENABLE_REWRITER)
122  CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;
123  return 0;
124#else
125  llvm_unreachable("Invalid program action!");
126#endif
127}
128
129static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
130  // Create the underlying action.
131  FrontendAction *Act = CreateFrontendBaseAction(CI);
132  if (!Act)
133    return 0;
134
135  const FrontendOptions &FEOpts = CI.getFrontendOpts();
136
137#ifdef CLANG_ENABLE_REWRITER
138  if (FEOpts.FixAndRecompile) {
139    Act = new FixItRecompile(Act);
140  }
141#endif
142
143#ifdef CLANG_ENABLE_ARCMT
144  if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource) {
145    // Potentially wrap the base FE action in an ARC Migrate Tool action.
146    switch (FEOpts.ARCMTAction) {
147    case FrontendOptions::ARCMT_None:
148      break;
149    case FrontendOptions::ARCMT_Check:
150      Act = new arcmt::CheckAction(Act);
151      break;
152    case FrontendOptions::ARCMT_Modify:
153      Act = new arcmt::ModifyAction(Act);
154      break;
155    case FrontendOptions::ARCMT_Migrate:
156      Act = new arcmt::MigrateAction(Act,
157                                     FEOpts.MTMigrateDir,
158                                     FEOpts.ARCMTMigrateReportOut,
159                                     FEOpts.ARCMTMigrateEmitARCErrors);
160      break;
161    }
162
163    if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
164      Act = new arcmt::ObjCMigrateAction(Act, FEOpts.MTMigrateDir,
165                                         FEOpts.ObjCMTAction);
166    }
167  }
168#endif
169
170  // If there are any AST files to merge, create a frontend action
171  // adaptor to perform the merge.
172  if (!FEOpts.ASTMergeFiles.empty())
173    Act = new ASTMergeAction(Act, FEOpts.ASTMergeFiles);
174
175  return Act;
176}
177
178bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
179  // Honor -help.
180  if (Clang->getFrontendOpts().ShowHelp) {
181    OwningPtr<OptTable> Opts(driver::createDriverOptTable());
182    Opts->PrintHelp(llvm::outs(), "clang -cc1",
183                    "LLVM 'Clang' Compiler: http://clang.llvm.org",
184                    /*Include=*/ driver::options::CC1Option, /*Exclude=*/ 0);
185    return true;
186  }
187
188  // Honor -version.
189  //
190  // FIXME: Use a better -version message?
191  if (Clang->getFrontendOpts().ShowVersion) {
192    llvm::cl::PrintVersionMessage();
193    return true;
194  }
195
196  // Load any requested plugins.
197  for (unsigned i = 0,
198         e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) {
199    const std::string &Path = Clang->getFrontendOpts().Plugins[i];
200    std::string Error;
201    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
202      Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
203        << Path << Error;
204  }
205
206  // Honor -mllvm.
207  //
208  // FIXME: Remove this, one day.
209  // This should happen AFTER plugins have been loaded!
210  if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
211    unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
212    const char **Args = new const char*[NumArgs + 2];
213    Args[0] = "clang (LLVM option parsing)";
214    for (unsigned i = 0; i != NumArgs; ++i)
215      Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
216    Args[NumArgs + 1] = 0;
217    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
218  }
219
220#ifdef CLANG_ENABLE_STATIC_ANALYZER
221  // Honor -analyzer-checker-help.
222  // This should happen AFTER plugins have been loaded!
223  if (Clang->getAnalyzerOpts()->ShowCheckerHelp) {
224    ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins);
225    return true;
226  }
227#endif
228
229  // If there were errors in processing arguments, don't do anything else.
230  if (Clang->getDiagnostics().hasErrorOccurred())
231    return false;
232  // Create and execute the frontend action.
233  OwningPtr<FrontendAction> Act(CreateFrontendAction(*Clang));
234  if (!Act)
235    return false;
236  bool Success = Clang->ExecuteAction(*Act);
237  if (Clang->getFrontendOpts().DisableFree)
238    Act.take();
239  return Success;
240}
241