clang  10.0.0svn
ExecuteCompilerInvocation.cpp
Go to the documentation of this file.
1 //===--- ExecuteCompilerInvocation.cpp ------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file holds ExecuteCompilerInvocation(). It is split into its own file to
10 // minimize the impact of pulling in essentially everything else in Clang.
11 //
12 //===----------------------------------------------------------------------===//
13 
16 #include "clang/Config/config.h"
17 #include "clang/Driver/Options.h"
23 #include "clang/Frontend/Utils.h"
27 #include "llvm/Option/OptTable.h"
28 #include "llvm/Option/Option.h"
29 #include "llvm/Support/BuryPointer.h"
30 #include "llvm/Support/DynamicLibrary.h"
31 #include "llvm/Support/ErrorHandling.h"
32 using namespace clang;
33 using namespace llvm::opt;
34 
35 namespace clang {
36 
37 static std::unique_ptr<FrontendAction>
39  using namespace clang::frontend;
40  StringRef Action("unknown");
41  (void)Action;
42 
43  switch (CI.getFrontendOpts().ProgramAction) {
44  case ASTDeclList: return std::make_unique<ASTDeclListAction>();
45  case ASTDump: return std::make_unique<ASTDumpAction>();
46  case ASTPrint: return std::make_unique<ASTPrintAction>();
47  case ASTView: return std::make_unique<ASTViewAction>();
49  return std::make_unique<DumpCompilerOptionsAction>();
50  case DumpRawTokens: return std::make_unique<DumpRawTokensAction>();
51  case DumpTokens: return std::make_unique<DumpTokensAction>();
52  case EmitAssembly: return std::make_unique<EmitAssemblyAction>();
53  case EmitBC: return std::make_unique<EmitBCAction>();
54  case EmitHTML: return std::make_unique<HTMLPrintAction>();
55  case EmitLLVM: return std::make_unique<EmitLLVMAction>();
56  case EmitLLVMOnly: return std::make_unique<EmitLLVMOnlyAction>();
57  case EmitCodeGenOnly: return std::make_unique<EmitCodeGenOnlyAction>();
58  case EmitObj: return std::make_unique<EmitObjAction>();
59  case FixIt: return std::make_unique<FixItAction>();
60  case GenerateModule:
61  return std::make_unique<GenerateModuleFromModuleMapAction>();
63  return std::make_unique<GenerateModuleInterfaceAction>();
65  return std::make_unique<GenerateHeaderModuleAction>();
66  case GeneratePCH: return std::make_unique<GeneratePCHAction>();
68  return std::make_unique<GenerateInterfaceIfsExpV1Action>();
69  case InitOnly: return std::make_unique<InitOnlyAction>();
70  case ParseSyntaxOnly: return std::make_unique<SyntaxOnlyAction>();
71  case ModuleFileInfo: return std::make_unique<DumpModuleInfoAction>();
72  case VerifyPCH: return std::make_unique<VerifyPCHAction>();
73  case TemplightDump: return std::make_unique<TemplightDumpAction>();
74 
75  case PluginAction: {
76  for (FrontendPluginRegistry::iterator it =
77  FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
78  it != ie; ++it) {
79  if (it->getName() == CI.getFrontendOpts().ActionName) {
80  std::unique_ptr<PluginASTAction> P(it->instantiate());
81  if ((P->getActionType() != PluginASTAction::ReplaceAction &&
82  P->getActionType() != PluginASTAction::Cmdline) ||
83  !P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()]))
84  return nullptr;
85  return std::move(P);
86  }
87  }
88 
89  CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
91  return nullptr;
92  }
93 
94  case PrintPreamble: return std::make_unique<PrintPreambleAction>();
98  return std::make_unique<RewriteIncludesAction>();
99  return std::make_unique<PrintPreprocessedAction>();
100  }
101 
102  case RewriteMacros: return std::make_unique<RewriteMacrosAction>();
103  case RewriteTest: return std::make_unique<RewriteTestAction>();
104 #if CLANG_ENABLE_OBJC_REWRITER
105  case RewriteObjC: return std::make_unique<RewriteObjCAction>();
106 #else
107  case RewriteObjC: Action = "RewriteObjC"; break;
108 #endif
109 #if CLANG_ENABLE_ARCMT
110  case MigrateSource:
111  return std::make_unique<arcmt::MigrateSourceAction>();
112 #else
113  case MigrateSource: Action = "MigrateSource"; break;
114 #endif
115 #if CLANG_ENABLE_STATIC_ANALYZER
116  case RunAnalysis: return std::make_unique<ento::AnalysisAction>();
117 #else
118  case RunAnalysis: Action = "RunAnalysis"; break;
119 #endif
120  case RunPreprocessorOnly: return std::make_unique<PreprocessOnlyAction>();
122  return std::make_unique<PrintDependencyDirectivesSourceMinimizerAction>();
123  }
124 
125 #if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \
126  || !CLANG_ENABLE_OBJC_REWRITER
127  CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;
128  return 0;
129 #else
130  llvm_unreachable("Invalid program action!");
131 #endif
132 }
133 
134 std::unique_ptr<FrontendAction>
136  // Create the underlying action.
137  std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI);
138  if (!Act)
139  return nullptr;
140 
141  const FrontendOptions &FEOpts = CI.getFrontendOpts();
142 
143  if (FEOpts.FixAndRecompile) {
144  Act = std::make_unique<FixItRecompile>(std::move(Act));
145  }
146 
147 #if CLANG_ENABLE_ARCMT
150  // Potentially wrap the base FE action in an ARC Migrate Tool action.
151  switch (FEOpts.ARCMTAction) {
153  break;
155  Act = std::make_unique<arcmt::CheckAction>(std::move(Act));
156  break;
158  Act = std::make_unique<arcmt::ModifyAction>(std::move(Act));
159  break;
161  Act = std::make_unique<arcmt::MigrateAction>(std::move(Act),
162  FEOpts.MTMigrateDir,
163  FEOpts.ARCMTMigrateReportOut,
165  break;
166  }
167 
169  Act = std::make_unique<arcmt::ObjCMigrateAction>(std::move(Act),
170  FEOpts.MTMigrateDir,
171  FEOpts.ObjCMTAction);
172  }
173  }
174 #endif
175 
176  // If there are any AST files to merge, create a frontend action
177  // adaptor to perform the merge.
178  if (!FEOpts.ASTMergeFiles.empty())
179  Act = std::make_unique<ASTMergeAction>(std::move(Act),
180  FEOpts.ASTMergeFiles);
181 
182  return Act;
183 }
184 
186  // Honor -help.
187  if (Clang->getFrontendOpts().ShowHelp) {
188  driver::getDriverOptTable().PrintHelp(
189  llvm::outs(), "clang -cc1 [options] file...",
190  "LLVM 'Clang' Compiler: http://clang.llvm.org",
191  /*Include=*/driver::options::CC1Option,
192  /*Exclude=*/0, /*ShowAllAliases=*/false);
193  return true;
194  }
195 
196  // Honor -version.
197  //
198  // FIXME: Use a better -version message?
199  if (Clang->getFrontendOpts().ShowVersion) {
200  llvm::cl::PrintVersionMessage();
201  return true;
202  }
203 
204  // Load any requested plugins.
205  for (unsigned i = 0,
206  e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) {
207  const std::string &Path = Clang->getFrontendOpts().Plugins[i];
208  std::string Error;
209  if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
210  Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
211  << Path << Error;
212  }
213 
214  // Check if any of the loaded plugins replaces the main AST action
215  for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(),
216  ie = FrontendPluginRegistry::end();
217  it != ie; ++it) {
218  std::unique_ptr<PluginASTAction> P(it->instantiate());
219  if (P->getActionType() == PluginASTAction::ReplaceAction) {
221  Clang->getFrontendOpts().ActionName = it->getName();
222  break;
223  }
224  }
225 
226  // Honor -mllvm.
227  //
228  // FIXME: Remove this, one day.
229  // This should happen AFTER plugins have been loaded!
230  if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
231  unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
232  auto Args = std::make_unique<const char*[]>(NumArgs + 2);
233  Args[0] = "clang (LLVM option parsing)";
234  for (unsigned i = 0; i != NumArgs; ++i)
235  Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
236  Args[NumArgs + 1] = nullptr;
237  llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
238  }
239 
240 #if CLANG_ENABLE_STATIC_ANALYZER
241  // These should happen AFTER plugins have been loaded!
242 
243  AnalyzerOptions &AnOpts = *Clang->getAnalyzerOpts();
244  // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
245  if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha ||
246  AnOpts.ShowCheckerHelpDeveloper) {
247  ento::printCheckerHelp(llvm::outs(),
248  Clang->getFrontendOpts().Plugins,
249  AnOpts,
250  Clang->getDiagnostics(),
251  Clang->getLangOpts());
252  return true;
253  }
254 
255  // Honor -analyzer-checker-option-help.
256  if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||
257  AnOpts.ShowCheckerOptionDeveloperList) {
258  ento::printCheckerConfigList(llvm::outs(),
259  Clang->getFrontendOpts().Plugins,
260  *Clang->getAnalyzerOpts(),
261  Clang->getDiagnostics(),
262  Clang->getLangOpts());
263  return true;
264  }
265 
266  // Honor -analyzer-list-enabled-checkers.
267  if (AnOpts.ShowEnabledCheckerList) {
268  ento::printEnabledCheckerList(llvm::outs(),
269  Clang->getFrontendOpts().Plugins,
270  AnOpts,
271  Clang->getDiagnostics(),
272  Clang->getLangOpts());
273  return true;
274  }
275 
276  // Honor -analyzer-config-help.
277  if (AnOpts.ShowConfigOptionsList) {
278  ento::printAnalyzerConfigList(llvm::outs());
279  return true;
280  }
281 #endif
282 
283  // If there were errors in processing arguments, don't do anything else.
284  if (Clang->getDiagnostics().hasErrorOccurred())
285  return false;
286  // Create and execute the frontend action.
287  std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
288  if (!Act)
289  return false;
290  bool Success = Clang->ExecuteAction(*Act);
291  if (Clang->getFrontendOpts().DisableFree)
292  llvm::BuryPointer(std::move(Act));
293  return Success;
294 }
295 
296 } // namespace clang
Expand macros but not #includes.
LangOptions & getLangOpts()
bool hasErrorOccurred() const
Definition: Diagnostic.h:747
void printEnabledCheckerList(raw_ostream &OS, ArrayRef< std::string > plugins, AnalyzerOptions &opts, DiagnosticsEngine &diags, const LangOptions &LangOpts)
Generate pre-compiled module from a module map.
Print the output of the dependency directives source minimizer.
Parse and perform semantic analysis.
Emit a .bc file.
std::unique_ptr< FrontendAction > CreateFrontendAction(CompilerInstance &CI)
Construct the FrontendAction of a compiler invocation based on the options specified for the compiler...
Parse ASTs and print them.
StringRef P
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1290
void printAnalyzerConfigList(raw_ostream &OS)
Parse and apply any fixits to the source.
Translate input source into HTML.
static std::unique_ptr< FrontendAction > CreateFrontendBaseAction(CompilerInstance &CI)
std::vector< std::string > ASTMergeFiles
The list of AST files to merge.
Action is determined by the cc1 command-line.
Generate LLVM IR, but do not emit anything.
FrontendOptions & getFrontendOpts()
PreprocessorOutputOptions & getPreprocessorOutputOpts()
void printCheckerHelp(raw_ostream &OS, ArrayRef< std::string > plugins, AnalyzerOptions &opts, DiagnosticsEngine &diags, const LangOptions &LangOpts)
AnalyzerOptionsRef getAnalyzerOpts()
unsigned FixAndRecompile
Apply fixes and recompile.
Dump the compiler configuration.
Dump template instantiations.
Dump out preprocessed tokens.
const llvm::opt::OptTable & getDriverOptTable()
Generate pre-compiled module from a C++ module interface file.
std::vector< std::string > Plugins
The list of plugins to load.
unsigned RewriteIncludes
Preprocess include directives only.
Generate Interface Stub Files.
Only execute frontend initialization.
Print the "preamble" of the input file.
Rewriter playground.
void printCheckerConfigList(raw_ostream &OS, ArrayRef< std::string > plugins, AnalyzerOptions &opts, DiagnosticsEngine &diags, const LangOptions &LangOpts)
unsigned ARCMTMigrateEmitARCErrors
Emit ARC errors even if the migrator can fix them.
bool ExecuteAction(FrontendAction &Act)
ExecuteAction - Execute the provided action against the compiler&#39;s CompilerInvocation object...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Generate machine code, but don&#39;t emit anything.
Parse ASTs and view them in Graphviz.
Parse ASTs and list Decl nodes.
std::unordered_map< std::string, std::vector< std::string > > PluginArgs
Args to pass to the plugins.
Load and verify that a PCH file is usable.
unsigned ShowVersion
Show the -version text.
unsigned RewriteImports
Include contents of transitively-imported modules.
unsigned ShowHelp
Show the -help text.
Dataflow Directional Tag Classes.
frontend::ActionKind ProgramAction
The frontend action to perform.
std::string ARCMTMigrateReportOut
FrontendOptions - Options for controlling the behavior of the frontend.
Run a plugin action,.
Parse ASTs and dump them.
bool ExecuteCompilerInvocation(CompilerInstance *Clang)
ExecuteCompilerInvocation - Execute the given actions described by the compiler invocation object in ...
enum clang::FrontendOptions::@193 ARCMTAction
Stores options for the analyzer from the command line.
unsigned DisableFree
Disable memory freeing on exit.
Generate pre-compiled header.
Generate pre-compiled module from a set of header files.
std::string ActionName
The name of the action to run when using a plugin action.
Run one or more source code analyses.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
std::vector< std::string > LLVMArgs
A list of arguments to forward to LLVM&#39;s option processing; this should only be used for debugging an...
Dump information about a module file.