Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
35232 views
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
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;
36
37
namespace clang {
38
39
static std::unique_ptr<FrontendAction>
40
CreateFrontendBaseAction(CompilerInstance &CI) {
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>();
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 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>();
68
case GenerateModuleInterface:
69
return std::make_unique<GenerateModuleInterfaceAction>();
70
case GenerateReducedModuleInterface:
71
return std::make_unique<GenerateReducedModuleInterfaceAction>();
72
case GenerateHeaderUnit:
73
return std::make_unique<GenerateHeaderUnitAction>();
74
case GeneratePCH: return std::make_unique<GeneratePCHAction>();
75
case GenerateInterfaceStubs:
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)
99
<< CI.getFrontendOpts().ActionName;
100
return nullptr;
101
}
102
103
case PrintPreamble: return std::make_unique<PrintPreambleAction>();
104
case PrintPreprocessedInput: {
105
if (CI.getPreprocessorOutputOpts().RewriteIncludes ||
106
CI.getPreprocessorOutputOpts().RewriteImports)
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>();
130
case PrintDependencyDirectivesSourceMinimizerOutput:
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>
144
CreateFrontendAction(CompilerInstance &CI) {
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
157
if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource &&
158
CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) {
159
// Potentially wrap the base FE action in an ARC Migrate Tool action.
160
switch (FEOpts.ARCMTAction) {
161
case FrontendOptions::ARCMT_None:
162
break;
163
case FrontendOptions::ARCMT_Check:
164
Act = std::make_unique<arcmt::CheckAction>(std::move(Act));
165
break;
166
case FrontendOptions::ARCMT_Modify:
167
Act = std::make_unique<arcmt::ModifyAction>(std::move(Act));
168
break;
169
case FrontendOptions::ARCMT_Migrate:
170
Act = std::make_unique<arcmt::MigrateAction>(std::move(Act),
171
FEOpts.MTMigrateDir,
172
FEOpts.ARCMTMigrateReportOut,
173
FEOpts.ARCMTMigrateEmitARCErrors);
174
break;
175
}
176
177
if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
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);
191
CI.getFrontendOpts().SymbolGraphOutputDir = ".";
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
206
bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
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,
213
llvm::opt::Visibility(driver::options::CC1Option));
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 ||
255
AnOpts.ShowCheckerOptionDeveloperList) {
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
287
288