clang  12.0.0git
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"
28 #include "llvm/Option/OptTable.h"
29 #include "llvm/Option/Option.h"
30 #include "llvm/Support/BuryPointer.h"
31 #include "llvm/Support/DynamicLibrary.h"
32 #include "llvm/Support/ErrorHandling.h"
33 using namespace clang;
34 using namespace llvm::opt;
35 
36 namespace clang {
37 
38 static std::unique_ptr<FrontendAction>
40  using namespace clang::frontend;
41  StringRef Action("unknown");
42  (void)Action;
43 
44  switch (CI.getFrontendOpts().ProgramAction) {
45  case ASTDeclList: return std::make_unique<ASTDeclListAction>();
46  case ASTDump: return std::make_unique<ASTDumpAction>();
47  case ASTPrint: return std::make_unique<ASTPrintAction>();
48  case ASTView: return std::make_unique<ASTViewAction>();
50  return std::make_unique<DumpCompilerOptionsAction>();
51  case DumpRawTokens: return std::make_unique<DumpRawTokensAction>();
52  case DumpTokens: return std::make_unique<DumpTokensAction>();
53  case EmitAssembly: return std::make_unique<EmitAssemblyAction>();
54  case EmitBC: return std::make_unique<EmitBCAction>();
55  case EmitHTML: return std::make_unique<HTMLPrintAction>();
56  case EmitLLVM: return std::make_unique<EmitLLVMAction>();
57  case EmitLLVMOnly: return std::make_unique<EmitLLVMOnlyAction>();
58  case EmitCodeGenOnly: return std::make_unique<EmitCodeGenOnlyAction>();
59  case EmitObj: return std::make_unique<EmitObjAction>();
60  case FixIt: return std::make_unique<FixItAction>();
61  case GenerateModule:
62  return std::make_unique<GenerateModuleFromModuleMapAction>();
64  return std::make_unique<GenerateModuleInterfaceAction>();
66  return std::make_unique<GenerateHeaderModuleAction>();
67  case GeneratePCH: return std::make_unique<GeneratePCHAction>();
69  return std::make_unique<GenerateInterfaceStubsAction>();
70  case InitOnly: return std::make_unique<InitOnlyAction>();
71  case ParseSyntaxOnly: return std::make_unique<SyntaxOnlyAction>();
72  case ModuleFileInfo: return std::make_unique<DumpModuleInfoAction>();
73  case VerifyPCH: return std::make_unique<VerifyPCHAction>();
74  case TemplightDump: return std::make_unique<TemplightDumpAction>();
75 
76  case PluginAction: {
77  for (const FrontendPluginRegistry::entry &Plugin :
78  FrontendPluginRegistry::entries()) {
79  if (Plugin.getName() == CI.getFrontendOpts().ActionName) {
80  std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
81  if ((P->getActionType() != PluginASTAction::ReplaceAction &&
82  P->getActionType() != PluginASTAction::Cmdline) ||
83  !P->ParseArgs(
84  CI,
85  CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())]))
86  return nullptr;
87  return std::move(P);
88  }
89  }
90 
91  CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
93  return nullptr;
94  }
95 
96  case PrintPreamble: return std::make_unique<PrintPreambleAction>();
100  return std::make_unique<RewriteIncludesAction>();
101  return std::make_unique<PrintPreprocessedAction>();
102  }
103 
104  case RewriteMacros: return std::make_unique<RewriteMacrosAction>();
105  case RewriteTest: return std::make_unique<RewriteTestAction>();
106 #if CLANG_ENABLE_OBJC_REWRITER
107  case RewriteObjC: return std::make_unique<RewriteObjCAction>();
108 #else
109  case RewriteObjC: Action = "RewriteObjC"; break;
110 #endif
111 #if CLANG_ENABLE_ARCMT
112  case MigrateSource:
113  return std::make_unique<arcmt::MigrateSourceAction>();
114 #else
115  case MigrateSource: Action = "MigrateSource"; break;
116 #endif
117 #if CLANG_ENABLE_STATIC_ANALYZER
118  case RunAnalysis: return std::make_unique<ento::AnalysisAction>();
119 #else
120  case RunAnalysis: Action = "RunAnalysis"; break;
121 #endif
122  case RunPreprocessorOnly: return std::make_unique<PreprocessOnlyAction>();
124  return std::make_unique<PrintDependencyDirectivesSourceMinimizerAction>();
125  }
126 
127 #if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \
128  || !CLANG_ENABLE_OBJC_REWRITER
129  CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;
130  return 0;
131 #else
132  llvm_unreachable("Invalid program action!");
133 #endif
134 }
135 
136 std::unique_ptr<FrontendAction>
138  // Create the underlying action.
139  std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI);
140  if (!Act)
141  return nullptr;
142 
143  const FrontendOptions &FEOpts = CI.getFrontendOpts();
144 
145  if (FEOpts.FixAndRecompile) {
146  Act = std::make_unique<FixItRecompile>(std::move(Act));
147  }
148 
149 #if CLANG_ENABLE_ARCMT
152  // Potentially wrap the base FE action in an ARC Migrate Tool action.
153  switch (FEOpts.ARCMTAction) {
155  break;
157  Act = std::make_unique<arcmt::CheckAction>(std::move(Act));
158  break;
160  Act = std::make_unique<arcmt::ModifyAction>(std::move(Act));
161  break;
163  Act = std::make_unique<arcmt::MigrateAction>(std::move(Act),
164  FEOpts.MTMigrateDir,
165  FEOpts.ARCMTMigrateReportOut,
167  break;
168  }
169 
171  Act = std::make_unique<arcmt::ObjCMigrateAction>(std::move(Act),
172  FEOpts.MTMigrateDir,
173  FEOpts.ObjCMTAction);
174  }
175  }
176 #endif
177 
178  // If there are any AST files to merge, create a frontend action
179  // adaptor to perform the merge.
180  if (!FEOpts.ASTMergeFiles.empty())
181  Act = std::make_unique<ASTMergeAction>(std::move(Act),
182  FEOpts.ASTMergeFiles);
183 
184  return Act;
185 }
186 
188  // Honor -help.
189  if (Clang->getFrontendOpts().ShowHelp) {
190  driver::getDriverOptTable().PrintHelp(
191  llvm::outs(), "clang -cc1 [options] file...",
192  "LLVM 'Clang' Compiler: http://clang.llvm.org",
193  /*Include=*/driver::options::CC1Option,
194  /*Exclude=*/0, /*ShowAllAliases=*/false);
195  return true;
196  }
197 
198  // Honor -version.
199  //
200  // FIXME: Use a better -version message?
201  if (Clang->getFrontendOpts().ShowVersion) {
202  llvm::cl::PrintVersionMessage();
203  return true;
204  }
205 
206  // Load any requested plugins.
207  for (const std::string &Path : Clang->getFrontendOpts().Plugins) {
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 (const FrontendPluginRegistry::entry &Plugin :
216  FrontendPluginRegistry::entries()) {
217  std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
218  if (P->getActionType() == PluginASTAction::ReplaceAction) {
220  Clang->getFrontendOpts().ActionName = Plugin.getName().str();
221  break;
222  }
223  }
224 
225  // Honor -mllvm.
226  //
227  // FIXME: Remove this, one day.
228  // This should happen AFTER plugins have been loaded!
229  if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
230  unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
231  auto Args = std::make_unique<const char*[]>(NumArgs + 2);
232  Args[0] = "clang (LLVM option parsing)";
233  for (unsigned i = 0; i != NumArgs; ++i)
234  Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
235  Args[NumArgs + 1] = nullptr;
236  llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
237  }
238 
239 #if CLANG_ENABLE_STATIC_ANALYZER
240  // These should happen AFTER plugins have been loaded!
241 
242  AnalyzerOptions &AnOpts = *Clang->getAnalyzerOpts();
243 
244  // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
245  if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha ||
246  AnOpts.ShowCheckerHelpDeveloper) {
247  ento::printCheckerHelp(llvm::outs(), *Clang);
248  return true;
249  }
250 
251  // Honor -analyzer-checker-option-help.
252  if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||
253  AnOpts.ShowCheckerOptionDeveloperList) {
254  ento::printCheckerConfigList(llvm::outs(), *Clang);
255  return true;
256  }
257 
258  // Honor -analyzer-list-enabled-checkers.
259  if (AnOpts.ShowEnabledCheckerList) {
260  ento::printEnabledCheckerList(llvm::outs(), *Clang);
261  return true;
262  }
263 
264  // Honor -analyzer-config-help.
265  if (AnOpts.ShowConfigOptionsList) {
266  ento::printAnalyzerConfigList(llvm::outs());
267  return true;
268  }
269 #endif
270 
271  // If there were errors in processing arguments, don't do anything else.
272  if (Clang->getDiagnostics().hasErrorOccurred())
273  return false;
274  // Create and execute the frontend action.
275  std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
276  if (!Act)
277  return false;
278  bool Success = Clang->ExecuteAction(*Act);
279  if (Clang->getFrontendOpts().DisableFree)
280  llvm::BuryPointer(std::move(Act));
281  return Success;
282 }
283 
284 } // namespace clang
Expand macros but not #includes.
bool hasErrorOccurred() const
Definition: Diagnostic.h:757
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:1330
void printAnalyzerConfigList(llvm::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()
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.
void printEnabledCheckerList(llvm::raw_ostream &OS, CompilerInstance &CI)
Only execute frontend initialization.
Print the "preamble" of the input file.
Rewriter playground.
Generate Interface Stub Files.
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.
enum clang::FrontendOptions::@185 ARCMTAction
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.
void printCheckerConfigList(llvm::raw_ostream &OS, CompilerInstance &CI)
Dataflow Directional Tag Classes.
frontend::ActionKind ProgramAction
The frontend action to perform.
std::string ARCMTMigrateReportOut
void printCheckerHelp(llvm::raw_ostream &OS, CompilerInstance &CI)
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 ...
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.