xref: /openbsd-src/gnu/llvm/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
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