xref: /freebsd/contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp (revision be092bcde96bdcfde9013d60e442cca023bfbd1b)
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    // 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);
186  
187    return Act;
188  }
189  
190  bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
191    // Honor -help.
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);
198      return true;
199    }
200  
201    // Honor -version.
202    //
203    // FIXME: Use a better -version message?
204    if (Clang->getFrontendOpts().ShowVersion) {
205      llvm::cl::PrintVersionMessage();
206      return true;
207    }
208  
209    Clang->LoadRequestedPlugins();
210  
211    // Honor -mllvm.
212    //
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());
223    }
224  
225  #if CLANG_ENABLE_STATIC_ANALYZER
226    // These should happen AFTER plugins have been loaded!
227  
228    AnalyzerOptions &AnOpts = *Clang->getAnalyzerOpts();
229  
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);
234      return true;
235    }
236  
237    // Honor -analyzer-checker-option-help.
238    if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||
239        AnOpts.ShowCheckerOptionDeveloperList) {
240      ento::printCheckerConfigList(llvm::outs(), *Clang);
241      return true;
242    }
243  
244    // Honor -analyzer-list-enabled-checkers.
245    if (AnOpts.ShowEnabledCheckerList) {
246      ento::printEnabledCheckerList(llvm::outs(), *Clang);
247      return true;
248    }
249  
250    // Honor -analyzer-config-help.
251    if (AnOpts.ShowConfigOptionsList) {
252      ento::printAnalyzerConfigList(llvm::outs());
253      return true;
254    }
255  #endif
256  
257    // If there were errors in processing arguments, don't do anything else.
258    if (Clang->getDiagnostics().hasErrorOccurred())
259      return false;
260    // Create and execute the frontend action.
261    std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
262    if (!Act)
263      return false;
264    bool Success = Clang->ExecuteAction(*Act);
265    if (Clang->getFrontendOpts().DisableFree)
266      llvm::BuryPointer(std::move(Act));
267    return Success;
268  }
269  
270  } // namespace clang
271