Path: blob/main/contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
35232 views
//===--- ExecuteCompilerInvocation.cpp ------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file holds ExecuteCompilerInvocation(). It is split into its own file to9// minimize the impact of pulling in essentially everything else in Clang.10//11//===----------------------------------------------------------------------===//1213#include "clang/ARCMigrate/ARCMTActions.h"14#include "clang/CodeGen/CodeGenAction.h"15#include "clang/Config/config.h"16#include "clang/Driver/Options.h"17#include "clang/ExtractAPI/FrontendActions.h"18#include "clang/Frontend/CompilerInstance.h"19#include "clang/Frontend/CompilerInvocation.h"20#include "clang/Frontend/FrontendActions.h"21#include "clang/Frontend/FrontendDiagnostic.h"22#include "clang/Frontend/FrontendPluginRegistry.h"23#include "clang/Frontend/Utils.h"24#include "clang/FrontendTool/Utils.h"25#include "clang/Rewrite/Frontend/FrontendActions.h"26#include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"27#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"28#include "llvm/Option/OptTable.h"29#include "llvm/Option/Option.h"30#include "llvm/Support/BuryPointer.h"31#include "llvm/Support/DynamicLibrary.h"32#include "llvm/Support/ErrorHandling.h"33using namespace clang;34using namespace llvm::opt;3536namespace clang {3738static std::unique_ptr<FrontendAction>39CreateFrontendBaseAction(CompilerInstance &CI) {40using namespace clang::frontend;41StringRef Action("unknown");42(void)Action;4344switch (CI.getFrontendOpts().ProgramAction) {45case ASTDeclList: return std::make_unique<ASTDeclListAction>();46case ASTDump: return std::make_unique<ASTDumpAction>();47case ASTPrint: return std::make_unique<ASTPrintAction>();48case ASTView: return std::make_unique<ASTViewAction>();49case DumpCompilerOptions:50return std::make_unique<DumpCompilerOptionsAction>();51case DumpRawTokens: return std::make_unique<DumpRawTokensAction>();52case DumpTokens: return std::make_unique<DumpTokensAction>();53case EmitAssembly: return std::make_unique<EmitAssemblyAction>();54case EmitBC: return std::make_unique<EmitBCAction>();55case EmitCIR:56llvm_unreachable("CIR suppport not built into clang");57case EmitHTML: return std::make_unique<HTMLPrintAction>();58case EmitLLVM: return std::make_unique<EmitLLVMAction>();59case EmitLLVMOnly: return std::make_unique<EmitLLVMOnlyAction>();60case EmitCodeGenOnly: return std::make_unique<EmitCodeGenOnlyAction>();61case EmitObj: return std::make_unique<EmitObjAction>();62case ExtractAPI:63return std::make_unique<ExtractAPIAction>();64case FixIt: return std::make_unique<FixItAction>();65case GenerateModule:66return std::make_unique<GenerateModuleFromModuleMapAction>();67case GenerateModuleInterface:68return std::make_unique<GenerateModuleInterfaceAction>();69case GenerateReducedModuleInterface:70return std::make_unique<GenerateReducedModuleInterfaceAction>();71case GenerateHeaderUnit:72return std::make_unique<GenerateHeaderUnitAction>();73case GeneratePCH: return std::make_unique<GeneratePCHAction>();74case GenerateInterfaceStubs:75return std::make_unique<GenerateInterfaceStubsAction>();76case InitOnly: return std::make_unique<InitOnlyAction>();77case ParseSyntaxOnly: return std::make_unique<SyntaxOnlyAction>();78case ModuleFileInfo: return std::make_unique<DumpModuleInfoAction>();79case VerifyPCH: return std::make_unique<VerifyPCHAction>();80case TemplightDump: return std::make_unique<TemplightDumpAction>();8182case PluginAction: {83for (const FrontendPluginRegistry::entry &Plugin :84FrontendPluginRegistry::entries()) {85if (Plugin.getName() == CI.getFrontendOpts().ActionName) {86std::unique_ptr<PluginASTAction> P(Plugin.instantiate());87if ((P->getActionType() != PluginASTAction::ReplaceAction &&88P->getActionType() != PluginASTAction::CmdlineAfterMainAction) ||89!P->ParseArgs(90CI,91CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())]))92return nullptr;93return std::move(P);94}95}9697CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)98<< CI.getFrontendOpts().ActionName;99return nullptr;100}101102case PrintPreamble: return std::make_unique<PrintPreambleAction>();103case PrintPreprocessedInput: {104if (CI.getPreprocessorOutputOpts().RewriteIncludes ||105CI.getPreprocessorOutputOpts().RewriteImports)106return std::make_unique<RewriteIncludesAction>();107return std::make_unique<PrintPreprocessedAction>();108}109110case RewriteMacros: return std::make_unique<RewriteMacrosAction>();111case RewriteTest: return std::make_unique<RewriteTestAction>();112#if CLANG_ENABLE_OBJC_REWRITER113case RewriteObjC: return std::make_unique<RewriteObjCAction>();114#else115case RewriteObjC: Action = "RewriteObjC"; break;116#endif117#if CLANG_ENABLE_ARCMT118case MigrateSource:119return std::make_unique<arcmt::MigrateSourceAction>();120#else121case MigrateSource: Action = "MigrateSource"; break;122#endif123#if CLANG_ENABLE_STATIC_ANALYZER124case RunAnalysis: return std::make_unique<ento::AnalysisAction>();125#else126case RunAnalysis: Action = "RunAnalysis"; break;127#endif128case RunPreprocessorOnly: return std::make_unique<PreprocessOnlyAction>();129case PrintDependencyDirectivesSourceMinimizerOutput:130return std::make_unique<PrintDependencyDirectivesSourceMinimizerAction>();131}132133#if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \134|| !CLANG_ENABLE_OBJC_REWRITER135CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;136return 0;137#else138llvm_unreachable("Invalid program action!");139#endif140}141142std::unique_ptr<FrontendAction>143CreateFrontendAction(CompilerInstance &CI) {144// Create the underlying action.145std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI);146if (!Act)147return nullptr;148149const FrontendOptions &FEOpts = CI.getFrontendOpts();150151if (FEOpts.FixAndRecompile) {152Act = std::make_unique<FixItRecompile>(std::move(Act));153}154155#if CLANG_ENABLE_ARCMT156if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource &&157CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) {158// Potentially wrap the base FE action in an ARC Migrate Tool action.159switch (FEOpts.ARCMTAction) {160case FrontendOptions::ARCMT_None:161break;162case FrontendOptions::ARCMT_Check:163Act = std::make_unique<arcmt::CheckAction>(std::move(Act));164break;165case FrontendOptions::ARCMT_Modify:166Act = std::make_unique<arcmt::ModifyAction>(std::move(Act));167break;168case FrontendOptions::ARCMT_Migrate:169Act = std::make_unique<arcmt::MigrateAction>(std::move(Act),170FEOpts.MTMigrateDir,171FEOpts.ARCMTMigrateReportOut,172FEOpts.ARCMTMigrateEmitARCErrors);173break;174}175176if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) {177Act = std::make_unique<arcmt::ObjCMigrateAction>(std::move(Act),178FEOpts.MTMigrateDir,179FEOpts.ObjCMTAction);180}181}182#endif183184// Wrap the base FE action in an extract api action to generate185// symbol graph as a biproduct of compilation (enabled with186// --emit-symbol-graph option)187if (FEOpts.EmitSymbolGraph) {188if (FEOpts.SymbolGraphOutputDir.empty()) {189CI.getDiagnostics().Report(diag::warn_missing_symbol_graph_dir);190CI.getFrontendOpts().SymbolGraphOutputDir = ".";191}192CI.getCodeGenOpts().ClearASTBeforeBackend = false;193Act = std::make_unique<WrappingExtractAPIAction>(std::move(Act));194}195196// If there are any AST files to merge, create a frontend action197// adaptor to perform the merge.198if (!FEOpts.ASTMergeFiles.empty())199Act = std::make_unique<ASTMergeAction>(std::move(Act),200FEOpts.ASTMergeFiles);201202return Act;203}204205bool ExecuteCompilerInvocation(CompilerInstance *Clang) {206// Honor -help.207if (Clang->getFrontendOpts().ShowHelp) {208driver::getDriverOptTable().printHelp(209llvm::outs(), "clang -cc1 [options] file...",210"LLVM 'Clang' Compiler: http://clang.llvm.org",211/*ShowHidden=*/false, /*ShowAllAliases=*/false,212llvm::opt::Visibility(driver::options::CC1Option));213return true;214}215216// Honor -version.217//218// FIXME: Use a better -version message?219if (Clang->getFrontendOpts().ShowVersion) {220llvm::cl::PrintVersionMessage();221return true;222}223224Clang->LoadRequestedPlugins();225226// Honor -mllvm.227//228// FIXME: Remove this, one day.229// This should happen AFTER plugins have been loaded!230if (!Clang->getFrontendOpts().LLVMArgs.empty()) {231unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();232auto Args = std::make_unique<const char*[]>(NumArgs + 2);233Args[0] = "clang (LLVM option parsing)";234for (unsigned i = 0; i != NumArgs; ++i)235Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();236Args[NumArgs + 1] = nullptr;237llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());238}239240#if CLANG_ENABLE_STATIC_ANALYZER241// These should happen AFTER plugins have been loaded!242243AnalyzerOptions &AnOpts = Clang->getAnalyzerOpts();244245// Honor -analyzer-checker-help and -analyzer-checker-help-hidden.246if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha ||247AnOpts.ShowCheckerHelpDeveloper) {248ento::printCheckerHelp(llvm::outs(), *Clang);249return true;250}251252// Honor -analyzer-checker-option-help.253if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||254AnOpts.ShowCheckerOptionDeveloperList) {255ento::printCheckerConfigList(llvm::outs(), *Clang);256return true;257}258259// Honor -analyzer-list-enabled-checkers.260if (AnOpts.ShowEnabledCheckerList) {261ento::printEnabledCheckerList(llvm::outs(), *Clang);262return true;263}264265// Honor -analyzer-config-help.266if (AnOpts.ShowConfigOptionsList) {267ento::printAnalyzerConfigList(llvm::outs());268return true;269}270#endif271272// If there were errors in processing arguments, don't do anything else.273if (Clang->getDiagnostics().hasErrorOccurred())274return false;275// Create and execute the frontend action.276std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));277if (!Act)278return false;279bool Success = Clang->ExecuteAction(*Act);280if (Clang->getFrontendOpts().DisableFree)281llvm::BuryPointer(std::move(Act));282return Success;283}284285} // namespace clang286287288