clang  19.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"
24 #include "clang/Frontend/Utils.h"
29 #include "llvm/Option/OptTable.h"
30 #include "llvm/Option/Option.h"
31 #include "llvm/Support/BuryPointer.h"
32 #include "llvm/Support/DynamicLibrary.h"
33 #include "llvm/Support/ErrorHandling.h"
34 using namespace clang;
35 using namespace llvm::opt;
36 
37 namespace clang {
38 
39 static std::unique_ptr<FrontendAction>
41  using namespace clang::frontend;
42  StringRef Action("unknown");
43  (void)Action;
44 
45  switch (CI.getFrontendOpts().ProgramAction) {
46  case ASTDeclList: return std::make_unique<ASTDeclListAction>();
47  case ASTDump: return std::make_unique<ASTDumpAction>();
48  case ASTPrint: return std::make_unique<ASTPrintAction>();
49  case ASTView: return std::make_unique<ASTViewAction>();
51  return std::make_unique<DumpCompilerOptionsAction>();
52  case DumpRawTokens: return std::make_unique<DumpRawTokensAction>();
53  case DumpTokens: return std::make_unique<DumpTokensAction>();
54  case EmitAssembly: return std::make_unique<EmitAssemblyAction>();
55  case EmitBC: return std::make_unique<EmitBCAction>();
56  case EmitCIR:
57  llvm_unreachable("CIR suppport not built into clang");
58  case EmitHTML: return std::make_unique<HTMLPrintAction>();
59  case EmitLLVM: return std::make_unique<EmitLLVMAction>();
60  case EmitLLVMOnly: return std::make_unique<EmitLLVMOnlyAction>();
61  case EmitCodeGenOnly: return std::make_unique<EmitCodeGenOnlyAction>();
62  case EmitObj: return std::make_unique<EmitObjAction>();
63  case ExtractAPI:
64  return std::make_unique<ExtractAPIAction>();
65  case FixIt: return std::make_unique<FixItAction>();
66  case GenerateModule:
67  return std::make_unique<GenerateModuleFromModuleMapAction>();
69  return std::make_unique<GenerateModuleInterfaceAction>();
71  return std::make_unique<GenerateReducedModuleInterfaceAction>();
72  case GenerateHeaderUnit:
73  return std::make_unique<GenerateHeaderUnitAction>();
74  case GeneratePCH: return std::make_unique<GeneratePCHAction>();
76  return std::make_unique<GenerateInterfaceStubsAction>();
77  case InitOnly: return std::make_unique<InitOnlyAction>();
78  case ParseSyntaxOnly: return std::make_unique<SyntaxOnlyAction>();
79  case ModuleFileInfo: return std::make_unique<DumpModuleInfoAction>();
80  case VerifyPCH: return std::make_unique<VerifyPCHAction>();
81  case TemplightDump: return std::make_unique<TemplightDumpAction>();
82 
83  case PluginAction: {
84  for (const FrontendPluginRegistry::entry &Plugin :
85  FrontendPluginRegistry::entries()) {
86  if (Plugin.getName() == CI.getFrontendOpts().ActionName) {
87  std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
88  if ((P->getActionType() != PluginASTAction::ReplaceAction &&
89  P->getActionType() != PluginASTAction::CmdlineAfterMainAction) ||
90  !P->ParseArgs(
91  CI,
92  CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())]))
93  return nullptr;
94  return std::move(P);
95  }
96  }
97 
98  CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
100  return nullptr;
101  }
102 
103  case PrintPreamble: return std::make_unique<PrintPreambleAction>();
104  case PrintPreprocessedInput: {
107  return std::make_unique<RewriteIncludesAction>();
108  return std::make_unique<PrintPreprocessedAction>();
109  }
110 
111  case RewriteMacros: return std::make_unique<RewriteMacrosAction>();
112  case RewriteTest: return std::make_unique<RewriteTestAction>();
113 #if CLANG_ENABLE_OBJC_REWRITER
114  case RewriteObjC: return std::make_unique<RewriteObjCAction>();
115 #else
116  case RewriteObjC: Action = "RewriteObjC"; break;
117 #endif
118 #if CLANG_ENABLE_ARCMT
119  case MigrateSource:
120  return std::make_unique<arcmt::MigrateSourceAction>();
121 #else
122  case MigrateSource: Action = "MigrateSource"; break;
123 #endif
124 #if CLANG_ENABLE_STATIC_ANALYZER
125  case RunAnalysis: return std::make_unique<ento::AnalysisAction>();
126 #else
127  case RunAnalysis: Action = "RunAnalysis"; break;
128 #endif
129  case RunPreprocessorOnly: return std::make_unique<PreprocessOnlyAction>();
131  return std::make_unique<PrintDependencyDirectivesSourceMinimizerAction>();
132  }
133 
134 #if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \
135  || !CLANG_ENABLE_OBJC_REWRITER
136  CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;
137  return 0;
138 #else
139  llvm_unreachable("Invalid program action!");
140 #endif
141 }
142 
143 std::unique_ptr<FrontendAction>
145  // Create the underlying action.
146  std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI);
147  if (!Act)
148  return nullptr;
149 
150  const FrontendOptions &FEOpts = CI.getFrontendOpts();
151 
152  if (FEOpts.FixAndRecompile) {
153  Act = std::make_unique<FixItRecompile>(std::move(Act));
154  }
155 
156 #if CLANG_ENABLE_ARCMT
159  // Potentially wrap the base FE action in an ARC Migrate Tool action.
160  switch (FEOpts.ARCMTAction) {
162  break;
164  Act = std::make_unique<arcmt::CheckAction>(std::move(Act));
165  break;
167  Act = std::make_unique<arcmt::ModifyAction>(std::move(Act));
168  break;
170  Act = std::make_unique<arcmt::MigrateAction>(std::move(Act),
171  FEOpts.MTMigrateDir,
172  FEOpts.ARCMTMigrateReportOut,
174  break;
175  }
176 
178  Act = std::make_unique<arcmt::ObjCMigrateAction>(std::move(Act),
179  FEOpts.MTMigrateDir,
180  FEOpts.ObjCMTAction);
181  }
182  }
183 #endif
184 
185  // Wrap the base FE action in an extract api action to generate
186  // symbol graph as a biproduct of compilation (enabled with
187  // --emit-symbol-graph option)
188  if (FEOpts.EmitSymbolGraph) {
189  if (FEOpts.SymbolGraphOutputDir.empty()) {
190  CI.getDiagnostics().Report(diag::warn_missing_symbol_graph_dir);
192  }
193  CI.getCodeGenOpts().ClearASTBeforeBackend = false;
194  Act = std::make_unique<WrappingExtractAPIAction>(std::move(Act));
195  }
196 
197  // If there are any AST files to merge, create a frontend action
198  // adaptor to perform the merge.
199  if (!FEOpts.ASTMergeFiles.empty())
200  Act = std::make_unique<ASTMergeAction>(std::move(Act),
201  FEOpts.ASTMergeFiles);
202 
203  return Act;
204 }
205 
207  // Honor -help.
208  if (Clang->getFrontendOpts().ShowHelp) {
209  driver::getDriverOptTable().printHelp(
210  llvm::outs(), "clang -cc1 [options] file...",
211  "LLVM 'Clang' Compiler: http://clang.llvm.org",
212  /*ShowHidden=*/false, /*ShowAllAliases=*/false,
214  return true;
215  }
216 
217  // Honor -version.
218  //
219  // FIXME: Use a better -version message?
220  if (Clang->getFrontendOpts().ShowVersion) {
221  llvm::cl::PrintVersionMessage();
222  return true;
223  }
224 
225  Clang->LoadRequestedPlugins();
226 
227  // Honor -mllvm.
228  //
229  // FIXME: Remove this, one day.
230  // This should happen AFTER plugins have been loaded!
231  if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
232  unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
233  auto Args = std::make_unique<const char*[]>(NumArgs + 2);
234  Args[0] = "clang (LLVM option parsing)";
235  for (unsigned i = 0; i != NumArgs; ++i)
236  Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
237  Args[NumArgs + 1] = nullptr;
238  llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
239  }
240 
241 #if CLANG_ENABLE_STATIC_ANALYZER
242  // These should happen AFTER plugins have been loaded!
243 
244  AnalyzerOptions &AnOpts = Clang->getAnalyzerOpts();
245 
246  // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
247  if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha ||
248  AnOpts.ShowCheckerHelpDeveloper) {
249  ento::printCheckerHelp(llvm::outs(), *Clang);
250  return true;
251  }
252 
253  // Honor -analyzer-checker-option-help.
254  if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||
256  ento::printCheckerConfigList(llvm::outs(), *Clang);
257  return true;
258  }
259 
260  // Honor -analyzer-list-enabled-checkers.
261  if (AnOpts.ShowEnabledCheckerList) {
262  ento::printEnabledCheckerList(llvm::outs(), *Clang);
263  return true;
264  }
265 
266  // Honor -analyzer-config-help.
267  if (AnOpts.ShowConfigOptionsList) {
268  ento::printAnalyzerConfigList(llvm::outs());
269  return true;
270  }
271 #endif
272 
273  // If there were errors in processing arguments, don't do anything else.
274  if (Clang->getDiagnostics().hasErrorOccurred())
275  return false;
276  // Create and execute the frontend action.
277  std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
278  if (!Act)
279  return false;
280  bool Success = Clang->ExecuteAction(*Act);
281  if (Clang->getFrontendOpts().DisableFree)
282  llvm::BuryPointer(std::move(Act));
283  return Success;
284 }
285 
286 } // namespace clang
StringRef P
This file defines the ExtractAPIAction and WrappingExtractAPIAction frontend actions.
Stores options for the analyzer from the command line.
unsigned ShowCheckerOptionDeveloperList
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
CodeGenOptions & getCodeGenOpts()
FrontendOptions & getFrontendOpts()
void LoadRequestedPlugins()
Load the list of plugins requested in the FrontendOptions.
AnalyzerOptions & getAnalyzerOpts()
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
bool ExecuteAction(FrontendAction &Act)
ExecuteAction - Execute the provided action against the compiler's CompilerInvocation object.
PreprocessorOutputOptions & getPreprocessorOutputOpts()
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
bool hasErrorOccurred() const
Definition: Diagnostic.h:849
FrontendOptions - Options for controlling the behavior of the frontend.
unsigned EmitSymbolGraph
Whether to emit symbol graph files as a side effect of compilation.
std::map< std::string, std::vector< std::string > > PluginArgs
Args to pass to the plugins.
std::vector< std::string > LLVMArgs
A list of arguments to forward to LLVM's option processing; this should only be used for debugging an...
unsigned ShowHelp
Show the -help text.
unsigned FixAndRecompile
Apply fixes and recompile.
std::string ActionName
The name of the action to run when using a plugin action.
enum clang::FrontendOptions::@198 ARCMTAction
std::string ARCMTMigrateReportOut
unsigned ShowVersion
Show the -version text.
unsigned ARCMTMigrateEmitARCErrors
Emit ARC errors even if the migrator can fix them.
std::string SymbolGraphOutputDir
std::vector< std::string > ASTMergeFiles
The list of AST files to merge.
unsigned DisableFree
Disable memory freeing on exit.
frontend::ActionKind ProgramAction
The frontend action to perform.
@ ReplaceAction
Replace the main action.
@ CmdlineAfterMainAction
Execute the action after the main action if on the command line.
unsigned RewriteIncludes
Preprocess include directives only.
unsigned RewriteImports
Include contents of transitively-imported modules.
const llvm::opt::OptTable & getDriverOptTable()
void printEnabledCheckerList(llvm::raw_ostream &OS, CompilerInstance &CI)
void printCheckerHelp(llvm::raw_ostream &OS, CompilerInstance &CI)
void printAnalyzerConfigList(llvm::raw_ostream &OS)
void printCheckerConfigList(llvm::raw_ostream &OS, CompilerInstance &CI)
@ GenerateHeaderUnit
Generate a C++20 header unit module from a header file.
@ VerifyPCH
Load and verify that a PCH file is usable.
@ PrintPreprocessedInput
-E mode.
@ RewriteTest
Rewriter playground.
@ ParseSyntaxOnly
Parse and perform semantic analysis.
@ TemplightDump
Dump template instantiations.
@ EmitBC
Emit a .bc file.
@ GenerateModuleInterface
Generate pre-compiled module from a standard C++ module interface unit.
@ EmitLLVM
Emit a .ll file.
@ PrintPreamble
Print the "preamble" of the input file.
@ MigrateSource
Run migrator.
@ InitOnly
Only execute frontend initialization.
@ ASTView
Parse ASTs and view them in Graphviz.
@ PluginAction
Run a plugin action,.
@ EmitObj
Emit a .o file.
@ DumpRawTokens
Dump out raw tokens.
@ PrintDependencyDirectivesSourceMinimizerOutput
Print the output of the dependency directives source minimizer.
@ RewriteObjC
ObjC->C Rewriter.
@ RunPreprocessorOnly
Just lex, no output.
@ ModuleFileInfo
Dump information about a module file.
@ EmitCIR
Emit a .cir file.
@ DumpCompilerOptions
Dump the compiler configuration.
@ RunAnalysis
Run one or more source code analyses.
@ ASTPrint
Parse ASTs and print them.
@ GenerateReducedModuleInterface
Generate reduced module interface for a standard C++ module interface unit.
@ GenerateInterfaceStubs
Generate Interface Stub Files.
@ ASTDump
Parse ASTs and dump them.
@ DumpTokens
Dump out preprocessed tokens.
@ FixIt
Parse and apply any fixits to the source.
@ EmitAssembly
Emit a .s file.
@ EmitCodeGenOnly
Generate machine code, but don't emit anything.
@ RewriteMacros
Expand macros but not #includes.
@ EmitHTML
Translate input source into HTML.
@ GeneratePCH
Generate pre-compiled header.
@ EmitLLVMOnly
Generate LLVM IR, but do not emit anything.
@ GenerateModule
Generate pre-compiled module from a module map.
@ ASTDeclList
Parse ASTs and list Decl nodes.
The JSON file list parser is used to communicate input to InstallAPI.
bool ExecuteCompilerInvocation(CompilerInstance *Clang)
ExecuteCompilerInvocation - Execute the given actions described by the compiler invocation object in ...
static std::unique_ptr< FrontendAction > CreateFrontendBaseAction(CompilerInstance &CI)
std::unique_ptr< FrontendAction > CreateFrontendAction(CompilerInstance &CI)
Construct the FrontendAction of a compiler invocation based on the options specified for the compiler...
Visibility
Describes the different kinds of visibility that a declaration may have.
Definition: Visibility.h:34