xref: /freebsd/contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp (revision 46b606c8fd9aabfdc880ca98241df443450b5791)
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 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>();
61    case ExtractAPI:
62      return std::make_unique<ExtractAPIAction>();
63    case FixIt:                  return std::make_unique<FixItAction>();
64    case GenerateModule:
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>();
78  
79    case PluginAction: {
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) ||
86              !P->ParseArgs(
87                  CI,
88                  CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())]))
89            return nullptr;
90          return std::move(P);
91        }
92      }
93  
94      CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
95        << CI.getFrontendOpts().ActionName;
96      return nullptr;
97    }
98  
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>();
105    }
106  
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>();
111  #else
112    case RewriteObjC:            Action = "RewriteObjC"; break;
113  #endif
114  #if CLANG_ENABLE_ARCMT
115    case MigrateSource:
116      return std::make_unique<arcmt::MigrateSourceAction>();
117  #else
118    case MigrateSource:          Action = "MigrateSource"; break;
119  #endif
120  #if CLANG_ENABLE_STATIC_ANALYZER
121    case RunAnalysis:            return std::make_unique<ento::AnalysisAction>();
122  #else
123    case RunAnalysis:            Action = "RunAnalysis"; break;
124  #endif
125    case RunPreprocessorOnly:    return std::make_unique<PreprocessOnlyAction>();
126    case PrintDependencyDirectivesSourceMinimizerOutput:
127      return std::make_unique<PrintDependencyDirectivesSourceMinimizerAction>();
128    }
129  
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;
133    return 0;
134  #else
135    llvm_unreachable("Invalid program action!");
136  #endif
137  }
138  
139  std::unique_ptr<FrontendAction>
140  CreateFrontendAction(CompilerInstance &CI) {
141    // Create the underlying action.
142    std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI);
143    if (!Act)
144      return nullptr;
145  
146    const FrontendOptions &FEOpts = CI.getFrontendOpts();
147  
148    if (FEOpts.FixAndRecompile) {
149      Act = std::make_unique<FixItRecompile>(std::move(Act));
150    }
151  
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:
158        break;
159      case FrontendOptions::ARCMT_Check:
160        Act = std::make_unique<arcmt::CheckAction>(std::move(Act));
161        break;
162      case FrontendOptions::ARCMT_Modify:
163        Act = std::make_unique<arcmt::ModifyAction>(std::move(Act));
164        break;
165      case FrontendOptions::ARCMT_Migrate:
166        Act = std::make_unique<arcmt::MigrateAction>(std::move(Act),
167                                       FEOpts.MTMigrateDir,
168                                       FEOpts.ARCMTMigrateReportOut,
169                                       FEOpts.ARCMTMigrateEmitARCErrors);
170        break;
171      }
172  
173      if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
174        Act = std::make_unique<arcmt::ObjCMigrateAction>(std::move(Act),
175                                                          FEOpts.MTMigrateDir,
176                                                          FEOpts.ObjCMTAction);
177      }
178    }
179  #endif
180  
181    // Wrap the base FE action in an extract api action to generate
182    // symbol graph as a biproduct of comilation ( enabled with
183    // --emit-symbol-graph option )
184    if (!FEOpts.SymbolGraphOutputDir.empty()) {
185      CI.getCodeGenOpts().ClearASTBeforeBackend = false;
186      Act = std::make_unique<WrappingExtractAPIAction>(std::move(Act));
187    }
188  
189    // If there are any AST files to merge, create a frontend action
190    // adaptor to perform the merge.
191    if (!FEOpts.ASTMergeFiles.empty())
192      Act = std::make_unique<ASTMergeAction>(std::move(Act),
193                                              FEOpts.ASTMergeFiles);
194  
195    return Act;
196  }
197  
198  bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
199    // Honor -help.
200    if (Clang->getFrontendOpts().ShowHelp) {
201      driver::getDriverOptTable().printHelp(
202          llvm::outs(), "clang -cc1 [options] file...",
203          "LLVM 'Clang' Compiler: http://clang.llvm.org",
204          /*ShowHidden=*/false, /*ShowAllAliases=*/false,
205          llvm::opt::Visibility(driver::options::CC1Option));
206      return true;
207    }
208  
209    // Honor -version.
210    //
211    // FIXME: Use a better -version message?
212    if (Clang->getFrontendOpts().ShowVersion) {
213      llvm::cl::PrintVersionMessage();
214      return true;
215    }
216  
217    Clang->LoadRequestedPlugins();
218  
219    // Honor -mllvm.
220    //
221    // FIXME: Remove this, one day.
222    // This should happen AFTER plugins have been loaded!
223    if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
224      unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
225      auto Args = std::make_unique<const char*[]>(NumArgs + 2);
226      Args[0] = "clang (LLVM option parsing)";
227      for (unsigned i = 0; i != NumArgs; ++i)
228        Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
229      Args[NumArgs + 1] = nullptr;
230      llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
231    }
232  
233  #if CLANG_ENABLE_STATIC_ANALYZER
234    // These should happen AFTER plugins have been loaded!
235  
236    AnalyzerOptions &AnOpts = Clang->getAnalyzerOpts();
237  
238    // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
239    if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha ||
240        AnOpts.ShowCheckerHelpDeveloper) {
241      ento::printCheckerHelp(llvm::outs(), *Clang);
242      return true;
243    }
244  
245    // Honor -analyzer-checker-option-help.
246    if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||
247        AnOpts.ShowCheckerOptionDeveloperList) {
248      ento::printCheckerConfigList(llvm::outs(), *Clang);
249      return true;
250    }
251  
252    // Honor -analyzer-list-enabled-checkers.
253    if (AnOpts.ShowEnabledCheckerList) {
254      ento::printEnabledCheckerList(llvm::outs(), *Clang);
255      return true;
256    }
257  
258    // Honor -analyzer-config-help.
259    if (AnOpts.ShowConfigOptionsList) {
260      ento::printAnalyzerConfigList(llvm::outs());
261      return true;
262    }
263  #endif
264  
265    // If there were errors in processing arguments, don't do anything else.
266    if (Clang->getDiagnostics().hasErrorOccurred())
267      return false;
268    // Create and execute the frontend action.
269    std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
270    if (!Act)
271      return false;
272    bool Success = Clang->ExecuteAction(*Act);
273    if (Clang->getFrontendOpts().DisableFree)
274      llvm::BuryPointer(std::move(Act));
275    return Success;
276  }
277  
278  } // namespace clang
279