1e5dd7070Spatrick //===--- ExecuteCompilerInvocation.cpp ------------------------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file holds ExecuteCompilerInvocation(). It is split into its own file to
10e5dd7070Spatrick // minimize the impact of pulling in essentially everything else in Clang.
11e5dd7070Spatrick //
12e5dd7070Spatrick //===----------------------------------------------------------------------===//
13e5dd7070Spatrick
14e5dd7070Spatrick #include "clang/ARCMigrate/ARCMTActions.h"
15e5dd7070Spatrick #include "clang/CodeGen/CodeGenAction.h"
16e5dd7070Spatrick #include "clang/Config/config.h"
17e5dd7070Spatrick #include "clang/Driver/Options.h"
18*12c85518Srobert #include "clang/ExtractAPI/FrontendActions.h"
19e5dd7070Spatrick #include "clang/Frontend/CompilerInstance.h"
20e5dd7070Spatrick #include "clang/Frontend/CompilerInvocation.h"
21e5dd7070Spatrick #include "clang/Frontend/FrontendActions.h"
22e5dd7070Spatrick #include "clang/Frontend/FrontendDiagnostic.h"
23e5dd7070Spatrick #include "clang/Frontend/FrontendPluginRegistry.h"
24e5dd7070Spatrick #include "clang/Frontend/Utils.h"
25e5dd7070Spatrick #include "clang/FrontendTool/Utils.h"
26e5dd7070Spatrick #include "clang/Rewrite/Frontend/FrontendActions.h"
27ec727ea7Spatrick #include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
28e5dd7070Spatrick #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
29e5dd7070Spatrick #include "llvm/Option/OptTable.h"
30e5dd7070Spatrick #include "llvm/Option/Option.h"
31e5dd7070Spatrick #include "llvm/Support/BuryPointer.h"
32e5dd7070Spatrick #include "llvm/Support/DynamicLibrary.h"
33e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
34e5dd7070Spatrick using namespace clang;
35e5dd7070Spatrick using namespace llvm::opt;
36e5dd7070Spatrick
37e5dd7070Spatrick namespace clang {
38e5dd7070Spatrick
39e5dd7070Spatrick static std::unique_ptr<FrontendAction>
CreateFrontendBaseAction(CompilerInstance & CI)40e5dd7070Spatrick CreateFrontendBaseAction(CompilerInstance &CI) {
41e5dd7070Spatrick using namespace clang::frontend;
42e5dd7070Spatrick StringRef Action("unknown");
43e5dd7070Spatrick (void)Action;
44e5dd7070Spatrick
45e5dd7070Spatrick switch (CI.getFrontendOpts().ProgramAction) {
46e5dd7070Spatrick case ASTDeclList: return std::make_unique<ASTDeclListAction>();
47e5dd7070Spatrick case ASTDump: return std::make_unique<ASTDumpAction>();
48e5dd7070Spatrick case ASTPrint: return std::make_unique<ASTPrintAction>();
49e5dd7070Spatrick case ASTView: return std::make_unique<ASTViewAction>();
50e5dd7070Spatrick case DumpCompilerOptions:
51e5dd7070Spatrick return std::make_unique<DumpCompilerOptionsAction>();
52e5dd7070Spatrick case DumpRawTokens: return std::make_unique<DumpRawTokensAction>();
53e5dd7070Spatrick case DumpTokens: return std::make_unique<DumpTokensAction>();
54e5dd7070Spatrick case EmitAssembly: return std::make_unique<EmitAssemblyAction>();
55e5dd7070Spatrick case EmitBC: return std::make_unique<EmitBCAction>();
56e5dd7070Spatrick case EmitHTML: return std::make_unique<HTMLPrintAction>();
57e5dd7070Spatrick case EmitLLVM: return std::make_unique<EmitLLVMAction>();
58e5dd7070Spatrick case EmitLLVMOnly: return std::make_unique<EmitLLVMOnlyAction>();
59e5dd7070Spatrick case EmitCodeGenOnly: return std::make_unique<EmitCodeGenOnlyAction>();
60e5dd7070Spatrick case EmitObj: return std::make_unique<EmitObjAction>();
61*12c85518Srobert case ExtractAPI:
62*12c85518Srobert return std::make_unique<ExtractAPIAction>();
63e5dd7070Spatrick case FixIt: return std::make_unique<FixItAction>();
64e5dd7070Spatrick case GenerateModule:
65e5dd7070Spatrick return std::make_unique<GenerateModuleFromModuleMapAction>();
66e5dd7070Spatrick case GenerateModuleInterface:
67e5dd7070Spatrick return std::make_unique<GenerateModuleInterfaceAction>();
68*12c85518Srobert case GenerateHeaderUnit:
69*12c85518Srobert return std::make_unique<GenerateHeaderUnitAction>();
70e5dd7070Spatrick case GeneratePCH: return std::make_unique<GeneratePCHAction>();
71ec727ea7Spatrick case GenerateInterfaceStubs:
72ec727ea7Spatrick return std::make_unique<GenerateInterfaceStubsAction>();
73e5dd7070Spatrick case InitOnly: return std::make_unique<InitOnlyAction>();
74e5dd7070Spatrick case ParseSyntaxOnly: return std::make_unique<SyntaxOnlyAction>();
75e5dd7070Spatrick case ModuleFileInfo: return std::make_unique<DumpModuleInfoAction>();
76e5dd7070Spatrick case VerifyPCH: return std::make_unique<VerifyPCHAction>();
77e5dd7070Spatrick case TemplightDump: return std::make_unique<TemplightDumpAction>();
78e5dd7070Spatrick
79e5dd7070Spatrick case PluginAction: {
80ec727ea7Spatrick for (const FrontendPluginRegistry::entry &Plugin :
81ec727ea7Spatrick FrontendPluginRegistry::entries()) {
82ec727ea7Spatrick if (Plugin.getName() == CI.getFrontendOpts().ActionName) {
83ec727ea7Spatrick std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
84e5dd7070Spatrick if ((P->getActionType() != PluginASTAction::ReplaceAction &&
85*12c85518Srobert P->getActionType() != PluginASTAction::CmdlineAfterMainAction) ||
86ec727ea7Spatrick !P->ParseArgs(
87ec727ea7Spatrick CI,
88ec727ea7Spatrick CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())]))
89e5dd7070Spatrick return nullptr;
90e5dd7070Spatrick return std::move(P);
91e5dd7070Spatrick }
92e5dd7070Spatrick }
93e5dd7070Spatrick
94e5dd7070Spatrick CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
95e5dd7070Spatrick << CI.getFrontendOpts().ActionName;
96e5dd7070Spatrick return nullptr;
97e5dd7070Spatrick }
98e5dd7070Spatrick
99e5dd7070Spatrick case PrintPreamble: return std::make_unique<PrintPreambleAction>();
100e5dd7070Spatrick case PrintPreprocessedInput: {
101e5dd7070Spatrick if (CI.getPreprocessorOutputOpts().RewriteIncludes ||
102e5dd7070Spatrick CI.getPreprocessorOutputOpts().RewriteImports)
103e5dd7070Spatrick return std::make_unique<RewriteIncludesAction>();
104e5dd7070Spatrick return std::make_unique<PrintPreprocessedAction>();
105e5dd7070Spatrick }
106e5dd7070Spatrick
107e5dd7070Spatrick case RewriteMacros: return std::make_unique<RewriteMacrosAction>();
108e5dd7070Spatrick case RewriteTest: return std::make_unique<RewriteTestAction>();
109e5dd7070Spatrick #if CLANG_ENABLE_OBJC_REWRITER
110e5dd7070Spatrick case RewriteObjC: return std::make_unique<RewriteObjCAction>();
111e5dd7070Spatrick #else
112e5dd7070Spatrick case RewriteObjC: Action = "RewriteObjC"; break;
113e5dd7070Spatrick #endif
114e5dd7070Spatrick #if CLANG_ENABLE_ARCMT
115e5dd7070Spatrick case MigrateSource:
116e5dd7070Spatrick return std::make_unique<arcmt::MigrateSourceAction>();
117e5dd7070Spatrick #else
118e5dd7070Spatrick case MigrateSource: Action = "MigrateSource"; break;
119e5dd7070Spatrick #endif
120e5dd7070Spatrick #if CLANG_ENABLE_STATIC_ANALYZER
121e5dd7070Spatrick case RunAnalysis: return std::make_unique<ento::AnalysisAction>();
122e5dd7070Spatrick #else
123e5dd7070Spatrick case RunAnalysis: Action = "RunAnalysis"; break;
124e5dd7070Spatrick #endif
125e5dd7070Spatrick case RunPreprocessorOnly: return std::make_unique<PreprocessOnlyAction>();
126e5dd7070Spatrick case PrintDependencyDirectivesSourceMinimizerOutput:
127e5dd7070Spatrick return std::make_unique<PrintDependencyDirectivesSourceMinimizerAction>();
128e5dd7070Spatrick }
129e5dd7070Spatrick
130e5dd7070Spatrick #if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \
131e5dd7070Spatrick || !CLANG_ENABLE_OBJC_REWRITER
132e5dd7070Spatrick CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;
133e5dd7070Spatrick return 0;
134e5dd7070Spatrick #else
135e5dd7070Spatrick llvm_unreachable("Invalid program action!");
136e5dd7070Spatrick #endif
137e5dd7070Spatrick }
138e5dd7070Spatrick
139e5dd7070Spatrick std::unique_ptr<FrontendAction>
CreateFrontendAction(CompilerInstance & CI)140e5dd7070Spatrick CreateFrontendAction(CompilerInstance &CI) {
141e5dd7070Spatrick // Create the underlying action.
142e5dd7070Spatrick std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI);
143e5dd7070Spatrick if (!Act)
144e5dd7070Spatrick return nullptr;
145e5dd7070Spatrick
146e5dd7070Spatrick const FrontendOptions &FEOpts = CI.getFrontendOpts();
147e5dd7070Spatrick
148e5dd7070Spatrick if (FEOpts.FixAndRecompile) {
149e5dd7070Spatrick Act = std::make_unique<FixItRecompile>(std::move(Act));
150e5dd7070Spatrick }
151e5dd7070Spatrick
152e5dd7070Spatrick #if CLANG_ENABLE_ARCMT
153e5dd7070Spatrick if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource &&
154e5dd7070Spatrick CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) {
155e5dd7070Spatrick // Potentially wrap the base FE action in an ARC Migrate Tool action.
156e5dd7070Spatrick switch (FEOpts.ARCMTAction) {
157e5dd7070Spatrick case FrontendOptions::ARCMT_None:
158e5dd7070Spatrick break;
159e5dd7070Spatrick case FrontendOptions::ARCMT_Check:
160e5dd7070Spatrick Act = std::make_unique<arcmt::CheckAction>(std::move(Act));
161e5dd7070Spatrick break;
162e5dd7070Spatrick case FrontendOptions::ARCMT_Modify:
163e5dd7070Spatrick Act = std::make_unique<arcmt::ModifyAction>(std::move(Act));
164e5dd7070Spatrick break;
165e5dd7070Spatrick case FrontendOptions::ARCMT_Migrate:
166e5dd7070Spatrick Act = std::make_unique<arcmt::MigrateAction>(std::move(Act),
167e5dd7070Spatrick FEOpts.MTMigrateDir,
168e5dd7070Spatrick FEOpts.ARCMTMigrateReportOut,
169e5dd7070Spatrick FEOpts.ARCMTMigrateEmitARCErrors);
170e5dd7070Spatrick break;
171e5dd7070Spatrick }
172e5dd7070Spatrick
173e5dd7070Spatrick if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
174e5dd7070Spatrick Act = std::make_unique<arcmt::ObjCMigrateAction>(std::move(Act),
175e5dd7070Spatrick FEOpts.MTMigrateDir,
176e5dd7070Spatrick FEOpts.ObjCMTAction);
177e5dd7070Spatrick }
178e5dd7070Spatrick }
179e5dd7070Spatrick #endif
180e5dd7070Spatrick
181e5dd7070Spatrick // If there are any AST files to merge, create a frontend action
182e5dd7070Spatrick // adaptor to perform the merge.
183e5dd7070Spatrick if (!FEOpts.ASTMergeFiles.empty())
184e5dd7070Spatrick Act = std::make_unique<ASTMergeAction>(std::move(Act),
185e5dd7070Spatrick FEOpts.ASTMergeFiles);
186e5dd7070Spatrick
187e5dd7070Spatrick return Act;
188e5dd7070Spatrick }
189e5dd7070Spatrick
ExecuteCompilerInvocation(CompilerInstance * Clang)190e5dd7070Spatrick bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
191e5dd7070Spatrick // Honor -help.
192e5dd7070Spatrick if (Clang->getFrontendOpts().ShowHelp) {
193a9ac8606Spatrick driver::getDriverOptTable().printHelp(
194e5dd7070Spatrick llvm::outs(), "clang -cc1 [options] file...",
195e5dd7070Spatrick "LLVM 'Clang' Compiler: http://clang.llvm.org",
196e5dd7070Spatrick /*Include=*/driver::options::CC1Option,
197e5dd7070Spatrick /*Exclude=*/0, /*ShowAllAliases=*/false);
198e5dd7070Spatrick return true;
199e5dd7070Spatrick }
200e5dd7070Spatrick
201e5dd7070Spatrick // Honor -version.
202e5dd7070Spatrick //
203e5dd7070Spatrick // FIXME: Use a better -version message?
204e5dd7070Spatrick if (Clang->getFrontendOpts().ShowVersion) {
205e5dd7070Spatrick llvm::cl::PrintVersionMessage();
206e5dd7070Spatrick return true;
207e5dd7070Spatrick }
208e5dd7070Spatrick
209*12c85518Srobert Clang->LoadRequestedPlugins();
210e5dd7070Spatrick
211e5dd7070Spatrick // Honor -mllvm.
212e5dd7070Spatrick //
213e5dd7070Spatrick // FIXME: Remove this, one day.
214e5dd7070Spatrick // This should happen AFTER plugins have been loaded!
215e5dd7070Spatrick if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
216e5dd7070Spatrick unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
217e5dd7070Spatrick auto Args = std::make_unique<const char*[]>(NumArgs + 2);
218e5dd7070Spatrick Args[0] = "clang (LLVM option parsing)";
219e5dd7070Spatrick for (unsigned i = 0; i != NumArgs; ++i)
220e5dd7070Spatrick Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
221e5dd7070Spatrick Args[NumArgs + 1] = nullptr;
222e5dd7070Spatrick llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
223e5dd7070Spatrick }
224e5dd7070Spatrick
225e5dd7070Spatrick #if CLANG_ENABLE_STATIC_ANALYZER
226e5dd7070Spatrick // These should happen AFTER plugins have been loaded!
227e5dd7070Spatrick
228e5dd7070Spatrick AnalyzerOptions &AnOpts = *Clang->getAnalyzerOpts();
229ec727ea7Spatrick
230e5dd7070Spatrick // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
231e5dd7070Spatrick if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha ||
232e5dd7070Spatrick AnOpts.ShowCheckerHelpDeveloper) {
233ec727ea7Spatrick ento::printCheckerHelp(llvm::outs(), *Clang);
234e5dd7070Spatrick return true;
235e5dd7070Spatrick }
236e5dd7070Spatrick
237e5dd7070Spatrick // Honor -analyzer-checker-option-help.
238e5dd7070Spatrick if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||
239e5dd7070Spatrick AnOpts.ShowCheckerOptionDeveloperList) {
240ec727ea7Spatrick ento::printCheckerConfigList(llvm::outs(), *Clang);
241e5dd7070Spatrick return true;
242e5dd7070Spatrick }
243e5dd7070Spatrick
244e5dd7070Spatrick // Honor -analyzer-list-enabled-checkers.
245e5dd7070Spatrick if (AnOpts.ShowEnabledCheckerList) {
246ec727ea7Spatrick ento::printEnabledCheckerList(llvm::outs(), *Clang);
247e5dd7070Spatrick return true;
248e5dd7070Spatrick }
249e5dd7070Spatrick
250e5dd7070Spatrick // Honor -analyzer-config-help.
251e5dd7070Spatrick if (AnOpts.ShowConfigOptionsList) {
252e5dd7070Spatrick ento::printAnalyzerConfigList(llvm::outs());
253e5dd7070Spatrick return true;
254e5dd7070Spatrick }
255e5dd7070Spatrick #endif
256e5dd7070Spatrick
257e5dd7070Spatrick // If there were errors in processing arguments, don't do anything else.
258e5dd7070Spatrick if (Clang->getDiagnostics().hasErrorOccurred())
259e5dd7070Spatrick return false;
260e5dd7070Spatrick // Create and execute the frontend action.
261e5dd7070Spatrick std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
262e5dd7070Spatrick if (!Act)
263e5dd7070Spatrick return false;
264e5dd7070Spatrick bool Success = Clang->ExecuteAction(*Act);
265e5dd7070Spatrick if (Clang->getFrontendOpts().DisableFree)
266e5dd7070Spatrick llvm::BuryPointer(std::move(Act));
267e5dd7070Spatrick return Success;
268e5dd7070Spatrick }
269e5dd7070Spatrick
270e5dd7070Spatrick } // namespace clang
271