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"
34 using namespace clang
;
35 using namespace llvm::opt
;
39 static std::unique_ptr
<FrontendAction
>
40 CreateFrontendBaseAction(CompilerInstance
&CI
) {
41 using namespace clang::frontend
;
42 StringRef
Action("unknown");
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
>();
50 case DumpCompilerOptions
:
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 EmitHTML
: return std::make_unique
<HTMLPrintAction
>();
57 case EmitLLVM
: return std::make_unique
<EmitLLVMAction
>();
58 case EmitLLVMOnly
: return std::make_unique
<EmitLLVMOnlyAction
>();
59 case EmitCodeGenOnly
: return std::make_unique
<EmitCodeGenOnlyAction
>();
60 case EmitObj
: return std::make_unique
<EmitObjAction
>();
62 return std::make_unique
<ExtractAPIAction
>();
63 case FixIt
: return std::make_unique
<FixItAction
>();
65 return std::make_unique
<GenerateModuleFromModuleMapAction
>();
66 case GenerateModuleInterface
:
67 return std::make_unique
<GenerateModuleInterfaceAction
>();
68 case GenerateHeaderUnit
:
69 return std::make_unique
<GenerateHeaderUnitAction
>();
70 case GeneratePCH
: return std::make_unique
<GeneratePCHAction
>();
71 case GenerateInterfaceStubs
:
72 return std::make_unique
<GenerateInterfaceStubsAction
>();
73 case InitOnly
: return std::make_unique
<InitOnlyAction
>();
74 case ParseSyntaxOnly
: return std::make_unique
<SyntaxOnlyAction
>();
75 case ModuleFileInfo
: return std::make_unique
<DumpModuleInfoAction
>();
76 case VerifyPCH
: return std::make_unique
<VerifyPCHAction
>();
77 case TemplightDump
: return std::make_unique
<TemplightDumpAction
>();
80 for (const FrontendPluginRegistry::entry
&Plugin
:
81 FrontendPluginRegistry::entries()) {
82 if (Plugin
.getName() == CI
.getFrontendOpts().ActionName
) {
83 std::unique_ptr
<PluginASTAction
> P(Plugin
.instantiate());
84 if ((P
->getActionType() != PluginASTAction::ReplaceAction
&&
85 P
->getActionType() != PluginASTAction::CmdlineAfterMainAction
) ||
88 CI
.getFrontendOpts().PluginArgs
[std::string(Plugin
.getName())]))
94 CI
.getDiagnostics().Report(diag::err_fe_invalid_plugin_name
)
95 << CI
.getFrontendOpts().ActionName
;
99 case PrintPreamble
: return std::make_unique
<PrintPreambleAction
>();
100 case PrintPreprocessedInput
: {
101 if (CI
.getPreprocessorOutputOpts().RewriteIncludes
||
102 CI
.getPreprocessorOutputOpts().RewriteImports
)
103 return std::make_unique
<RewriteIncludesAction
>();
104 return std::make_unique
<PrintPreprocessedAction
>();
107 case RewriteMacros
: return std::make_unique
<RewriteMacrosAction
>();
108 case RewriteTest
: return std::make_unique
<RewriteTestAction
>();
109 #if CLANG_ENABLE_OBJC_REWRITER
110 case RewriteObjC
: return std::make_unique
<RewriteObjCAction
>();
112 case RewriteObjC
: Action
= "RewriteObjC"; break;
114 #if CLANG_ENABLE_ARCMT
116 return std::make_unique
<arcmt::MigrateSourceAction
>();
118 case MigrateSource
: Action
= "MigrateSource"; break;
120 #if CLANG_ENABLE_STATIC_ANALYZER
121 case RunAnalysis
: return std::make_unique
<ento::AnalysisAction
>();
123 case RunAnalysis
: Action
= "RunAnalysis"; break;
125 case RunPreprocessorOnly
: return std::make_unique
<PreprocessOnlyAction
>();
126 case PrintDependencyDirectivesSourceMinimizerOutput
:
127 return std::make_unique
<PrintDependencyDirectivesSourceMinimizerAction
>();
130 #if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \
131 || !CLANG_ENABLE_OBJC_REWRITER
132 CI
.getDiagnostics().Report(diag::err_fe_action_not_available
) << Action
;
135 llvm_unreachable("Invalid program action!");
139 std::unique_ptr
<FrontendAction
>
140 CreateFrontendAction(CompilerInstance
&CI
) {
141 // Create the underlying action.
142 std::unique_ptr
<FrontendAction
> Act
= CreateFrontendBaseAction(CI
);
146 const FrontendOptions
&FEOpts
= CI
.getFrontendOpts();
148 if (FEOpts
.FixAndRecompile
) {
149 Act
= std::make_unique
<FixItRecompile
>(std::move(Act
));
152 #if CLANG_ENABLE_ARCMT
153 if (CI
.getFrontendOpts().ProgramAction
!= frontend::MigrateSource
&&
154 CI
.getFrontendOpts().ProgramAction
!= frontend::GeneratePCH
) {
155 // Potentially wrap the base FE action in an ARC Migrate Tool action.
156 switch (FEOpts
.ARCMTAction
) {
157 case FrontendOptions::ARCMT_None
:
159 case FrontendOptions::ARCMT_Check
:
160 Act
= std::make_unique
<arcmt::CheckAction
>(std::move(Act
));
162 case FrontendOptions::ARCMT_Modify
:
163 Act
= std::make_unique
<arcmt::ModifyAction
>(std::move(Act
));
165 case FrontendOptions::ARCMT_Migrate
:
166 Act
= std::make_unique
<arcmt::MigrateAction
>(std::move(Act
),
168 FEOpts
.ARCMTMigrateReportOut
,
169 FEOpts
.ARCMTMigrateEmitARCErrors
);
173 if (FEOpts
.ObjCMTAction
!= FrontendOptions::ObjCMT_None
) {
174 Act
= std::make_unique
<arcmt::ObjCMigrateAction
>(std::move(Act
),
176 FEOpts
.ObjCMTAction
);
181 // If there are any AST files to merge, create a frontend action
182 // adaptor to perform the merge.
183 if (!FEOpts
.ASTMergeFiles
.empty())
184 Act
= std::make_unique
<ASTMergeAction
>(std::move(Act
),
185 FEOpts
.ASTMergeFiles
);
190 bool ExecuteCompilerInvocation(CompilerInstance
*Clang
) {
192 if (Clang
->getFrontendOpts().ShowHelp
) {
193 driver::getDriverOptTable().printHelp(
194 llvm::outs(), "clang -cc1 [options] file...",
195 "LLVM 'Clang' Compiler: http://clang.llvm.org",
196 /*Include=*/driver::options::CC1Option
,
197 /*Exclude=*/0, /*ShowAllAliases=*/false);
203 // FIXME: Use a better -version message?
204 if (Clang
->getFrontendOpts().ShowVersion
) {
205 llvm::cl::PrintVersionMessage();
209 Clang
->LoadRequestedPlugins();
213 // FIXME: Remove this, one day.
214 // This should happen AFTER plugins have been loaded!
215 if (!Clang
->getFrontendOpts().LLVMArgs
.empty()) {
216 unsigned NumArgs
= Clang
->getFrontendOpts().LLVMArgs
.size();
217 auto Args
= std::make_unique
<const char*[]>(NumArgs
+ 2);
218 Args
[0] = "clang (LLVM option parsing)";
219 for (unsigned i
= 0; i
!= NumArgs
; ++i
)
220 Args
[i
+ 1] = Clang
->getFrontendOpts().LLVMArgs
[i
].c_str();
221 Args
[NumArgs
+ 1] = nullptr;
222 llvm::cl::ParseCommandLineOptions(NumArgs
+ 1, Args
.get());
225 #if CLANG_ENABLE_STATIC_ANALYZER
226 // These should happen AFTER plugins have been loaded!
228 AnalyzerOptions
&AnOpts
= *Clang
->getAnalyzerOpts();
230 // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
231 if (AnOpts
.ShowCheckerHelp
|| AnOpts
.ShowCheckerHelpAlpha
||
232 AnOpts
.ShowCheckerHelpDeveloper
) {
233 ento::printCheckerHelp(llvm::outs(), *Clang
);
237 // Honor -analyzer-checker-option-help.
238 if (AnOpts
.ShowCheckerOptionList
|| AnOpts
.ShowCheckerOptionAlphaList
||
239 AnOpts
.ShowCheckerOptionDeveloperList
) {
240 ento::printCheckerConfigList(llvm::outs(), *Clang
);
244 // Honor -analyzer-list-enabled-checkers.
245 if (AnOpts
.ShowEnabledCheckerList
) {
246 ento::printEnabledCheckerList(llvm::outs(), *Clang
);
250 // Honor -analyzer-config-help.
251 if (AnOpts
.ShowConfigOptionsList
) {
252 ento::printAnalyzerConfigList(llvm::outs());
257 // If there were errors in processing arguments, don't do anything else.
258 if (Clang
->getDiagnostics().hasErrorOccurred())
260 // Create and execute the frontend action.
261 std::unique_ptr
<FrontendAction
> Act(CreateFrontendAction(*Clang
));
264 bool Success
= Clang
->ExecuteAction(*Act
);
265 if (Clang
->getFrontendOpts().DisableFree
)
266 llvm::BuryPointer(std::move(Act
));