1 //===--- ExecuteCompilerInvocation.cpp ------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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.
12 //===----------------------------------------------------------------------===//
14 #include "clang/ARCMigrate/ARCMTActions.h"
15 #include "clang/CodeGen/CodeGenAction.h"
16 #include "clang/Config/config.h"
17 #include "clang/Driver/Options.h"
18 #include "clang/ExtractAPI/FrontendActions.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/Frontend/Utils.h"
25 #include "clang/FrontendTool/Utils.h"
26 #include "clang/Rewrite/Frontend/FrontendActions.h"
27 #include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
28 #include "clang/StaticAnalyzer/Frontend/FrontendActions.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"
36 #include "clang/CIR/FrontendAction/CIRGenAction.h"
39 using namespace clang
;
40 using namespace llvm::opt
;
44 static std::unique_ptr
<FrontendAction
>
45 CreateFrontendBaseAction(CompilerInstance
&CI
) {
46 using namespace clang::frontend
;
47 StringRef
Action("unknown");
50 unsigned UseCIR
= CI
.getFrontendOpts().UseClangIRPipeline
;
51 frontend::ActionKind Act
= CI
.getFrontendOpts().ProgramAction
;
52 bool EmitsCIR
= Act
== EmitCIR
;
54 if (!UseCIR
&& EmitsCIR
)
55 llvm::report_fatal_error("-emit-cir and only valid when using -fclangir");
57 switch (CI
.getFrontendOpts().ProgramAction
) {
58 case ASTDeclList
: return std::make_unique
<ASTDeclListAction
>();
59 case ASTDump
: return std::make_unique
<ASTDumpAction
>();
60 case ASTPrint
: return std::make_unique
<ASTPrintAction
>();
61 case ASTView
: return std::make_unique
<ASTViewAction
>();
62 case DumpCompilerOptions
:
63 return std::make_unique
<DumpCompilerOptionsAction
>();
64 case DumpRawTokens
: return std::make_unique
<DumpRawTokensAction
>();
65 case DumpTokens
: return std::make_unique
<DumpTokensAction
>();
66 case EmitAssembly
: return std::make_unique
<EmitAssemblyAction
>();
67 case EmitBC
: return std::make_unique
<EmitBCAction
>();
70 return std::make_unique
<cir::EmitCIRAction
>();
72 llvm_unreachable("CIR suppport not built into clang");
74 case EmitHTML
: return std::make_unique
<HTMLPrintAction
>();
75 case EmitLLVM
: return std::make_unique
<EmitLLVMAction
>();
76 case EmitLLVMOnly
: return std::make_unique
<EmitLLVMOnlyAction
>();
77 case EmitCodeGenOnly
: return std::make_unique
<EmitCodeGenOnlyAction
>();
78 case EmitObj
: return std::make_unique
<EmitObjAction
>();
80 return std::make_unique
<ExtractAPIAction
>();
81 case FixIt
: return std::make_unique
<FixItAction
>();
83 return std::make_unique
<GenerateModuleFromModuleMapAction
>();
84 case GenerateModuleInterface
:
85 return std::make_unique
<GenerateModuleInterfaceAction
>();
86 case GenerateReducedModuleInterface
:
87 return std::make_unique
<GenerateReducedModuleInterfaceAction
>();
88 case GenerateHeaderUnit
:
89 return std::make_unique
<GenerateHeaderUnitAction
>();
90 case GeneratePCH
: return std::make_unique
<GeneratePCHAction
>();
91 case GenerateInterfaceStubs
:
92 return std::make_unique
<GenerateInterfaceStubsAction
>();
93 case InitOnly
: return std::make_unique
<InitOnlyAction
>();
94 case ParseSyntaxOnly
: return std::make_unique
<SyntaxOnlyAction
>();
95 case ModuleFileInfo
: return std::make_unique
<DumpModuleInfoAction
>();
96 case VerifyPCH
: return std::make_unique
<VerifyPCHAction
>();
97 case TemplightDump
: return std::make_unique
<TemplightDumpAction
>();
100 for (const FrontendPluginRegistry::entry
&Plugin
:
101 FrontendPluginRegistry::entries()) {
102 if (Plugin
.getName() == CI
.getFrontendOpts().ActionName
) {
103 std::unique_ptr
<PluginASTAction
> P(Plugin
.instantiate());
104 if ((P
->getActionType() != PluginASTAction::ReplaceAction
&&
105 P
->getActionType() != PluginASTAction::CmdlineAfterMainAction
) ||
108 CI
.getFrontendOpts().PluginArgs
[std::string(Plugin
.getName())]))
114 CI
.getDiagnostics().Report(diag::err_fe_invalid_plugin_name
)
115 << CI
.getFrontendOpts().ActionName
;
119 case PrintPreamble
: return std::make_unique
<PrintPreambleAction
>();
120 case PrintPreprocessedInput
: {
121 if (CI
.getPreprocessorOutputOpts().RewriteIncludes
||
122 CI
.getPreprocessorOutputOpts().RewriteImports
)
123 return std::make_unique
<RewriteIncludesAction
>();
124 return std::make_unique
<PrintPreprocessedAction
>();
127 case RewriteMacros
: return std::make_unique
<RewriteMacrosAction
>();
128 case RewriteTest
: return std::make_unique
<RewriteTestAction
>();
129 #if CLANG_ENABLE_OBJC_REWRITER
130 case RewriteObjC
: return std::make_unique
<RewriteObjCAction
>();
132 case RewriteObjC
: Action
= "RewriteObjC"; break;
134 #if CLANG_ENABLE_ARCMT
136 return std::make_unique
<arcmt::MigrateSourceAction
>();
138 case MigrateSource
: Action
= "MigrateSource"; break;
140 #if CLANG_ENABLE_STATIC_ANALYZER
141 case RunAnalysis
: return std::make_unique
<ento::AnalysisAction
>();
143 case RunAnalysis
: Action
= "RunAnalysis"; break;
145 case RunPreprocessorOnly
: return std::make_unique
<PreprocessOnlyAction
>();
146 case PrintDependencyDirectivesSourceMinimizerOutput
:
147 return std::make_unique
<PrintDependencyDirectivesSourceMinimizerAction
>();
150 #if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \
151 || !CLANG_ENABLE_OBJC_REWRITER
152 CI
.getDiagnostics().Report(diag::err_fe_action_not_available
) << Action
;
155 llvm_unreachable("Invalid program action!");
159 std::unique_ptr
<FrontendAction
>
160 CreateFrontendAction(CompilerInstance
&CI
) {
161 // Create the underlying action.
162 std::unique_ptr
<FrontendAction
> Act
= CreateFrontendBaseAction(CI
);
166 const FrontendOptions
&FEOpts
= CI
.getFrontendOpts();
168 if (FEOpts
.FixAndRecompile
) {
169 Act
= std::make_unique
<FixItRecompile
>(std::move(Act
));
172 #if CLANG_ENABLE_ARCMT
173 if (CI
.getFrontendOpts().ProgramAction
!= frontend::MigrateSource
&&
174 CI
.getFrontendOpts().ProgramAction
!= frontend::GeneratePCH
) {
175 // Potentially wrap the base FE action in an ARC Migrate Tool action.
176 switch (FEOpts
.ARCMTAction
) {
177 case FrontendOptions::ARCMT_None
:
179 case FrontendOptions::ARCMT_Check
:
180 Act
= std::make_unique
<arcmt::CheckAction
>(std::move(Act
));
182 case FrontendOptions::ARCMT_Modify
:
183 Act
= std::make_unique
<arcmt::ModifyAction
>(std::move(Act
));
185 case FrontendOptions::ARCMT_Migrate
:
186 Act
= std::make_unique
<arcmt::MigrateAction
>(std::move(Act
),
188 FEOpts
.ARCMTMigrateReportOut
,
189 FEOpts
.ARCMTMigrateEmitARCErrors
);
193 if (FEOpts
.ObjCMTAction
!= FrontendOptions::ObjCMT_None
) {
194 Act
= std::make_unique
<arcmt::ObjCMigrateAction
>(std::move(Act
),
196 FEOpts
.ObjCMTAction
);
201 // Wrap the base FE action in an extract api action to generate
202 // symbol graph as a biproduct of compilation (enabled with
203 // --emit-symbol-graph option)
204 if (FEOpts
.EmitSymbolGraph
) {
205 if (FEOpts
.SymbolGraphOutputDir
.empty()) {
206 CI
.getDiagnostics().Report(diag::warn_missing_symbol_graph_dir
);
207 CI
.getFrontendOpts().SymbolGraphOutputDir
= ".";
209 CI
.getCodeGenOpts().ClearASTBeforeBackend
= false;
210 Act
= std::make_unique
<WrappingExtractAPIAction
>(std::move(Act
));
213 // If there are any AST files to merge, create a frontend action
214 // adaptor to perform the merge.
215 if (!FEOpts
.ASTMergeFiles
.empty())
216 Act
= std::make_unique
<ASTMergeAction
>(std::move(Act
),
217 FEOpts
.ASTMergeFiles
);
222 bool ExecuteCompilerInvocation(CompilerInstance
*Clang
) {
224 if (Clang
->getFrontendOpts().ShowHelp
) {
225 driver::getDriverOptTable().printHelp(
226 llvm::outs(), "clang -cc1 [options] file...",
227 "LLVM 'Clang' Compiler: http://clang.llvm.org",
228 /*ShowHidden=*/false, /*ShowAllAliases=*/false,
229 llvm::opt::Visibility(driver::options::CC1Option
));
235 // FIXME: Use a better -version message?
236 if (Clang
->getFrontendOpts().ShowVersion
) {
237 llvm::cl::PrintVersionMessage();
241 Clang
->LoadRequestedPlugins();
245 // FIXME: Remove this, one day.
246 // This should happen AFTER plugins have been loaded!
247 if (!Clang
->getFrontendOpts().LLVMArgs
.empty()) {
248 unsigned NumArgs
= Clang
->getFrontendOpts().LLVMArgs
.size();
249 auto Args
= std::make_unique
<const char*[]>(NumArgs
+ 2);
250 Args
[0] = "clang (LLVM option parsing)";
251 for (unsigned i
= 0; i
!= NumArgs
; ++i
)
252 Args
[i
+ 1] = Clang
->getFrontendOpts().LLVMArgs
[i
].c_str();
253 Args
[NumArgs
+ 1] = nullptr;
254 llvm::cl::ParseCommandLineOptions(NumArgs
+ 1, Args
.get());
257 #if CLANG_ENABLE_STATIC_ANALYZER
258 // These should happen AFTER plugins have been loaded!
260 AnalyzerOptions
&AnOpts
= Clang
->getAnalyzerOpts();
262 // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
263 if (AnOpts
.ShowCheckerHelp
|| AnOpts
.ShowCheckerHelpAlpha
||
264 AnOpts
.ShowCheckerHelpDeveloper
) {
265 ento::printCheckerHelp(llvm::outs(), *Clang
);
269 // Honor -analyzer-checker-option-help.
270 if (AnOpts
.ShowCheckerOptionList
|| AnOpts
.ShowCheckerOptionAlphaList
||
271 AnOpts
.ShowCheckerOptionDeveloperList
) {
272 ento::printCheckerConfigList(llvm::outs(), *Clang
);
276 // Honor -analyzer-list-enabled-checkers.
277 if (AnOpts
.ShowEnabledCheckerList
) {
278 ento::printEnabledCheckerList(llvm::outs(), *Clang
);
282 // Honor -analyzer-config-help.
283 if (AnOpts
.ShowConfigOptionsList
) {
284 ento::printAnalyzerConfigList(llvm::outs());
289 // If there were errors in processing arguments, don't do anything else.
290 if (Clang
->getDiagnostics().hasErrorOccurred())
292 // Create and execute the frontend action.
293 std::unique_ptr
<FrontendAction
> Act(CreateFrontendAction(*Clang
));
296 bool Success
= Clang
->ExecuteAction(*Act
);
297 if (Clang
->getFrontendOpts().DisableFree
)
298 llvm::BuryPointer(std::move(Act
));