1*0b57cec5SDimitry Andric //===--- ExecuteCompilerInvocation.cpp ------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file holds ExecuteCompilerInvocation(). It is split into its own file to 10*0b57cec5SDimitry Andric // minimize the impact of pulling in essentially everything else in Clang. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "clang/ARCMigrate/ARCMTActions.h" 15*0b57cec5SDimitry Andric #include "clang/CodeGen/CodeGenAction.h" 16*0b57cec5SDimitry Andric #include "clang/Config/config.h" 17*0b57cec5SDimitry Andric #include "clang/Driver/Options.h" 18*0b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h" 19*0b57cec5SDimitry Andric #include "clang/Frontend/CompilerInvocation.h" 20*0b57cec5SDimitry Andric #include "clang/Frontend/FrontendActions.h" 21*0b57cec5SDimitry Andric #include "clang/Frontend/FrontendDiagnostic.h" 22*0b57cec5SDimitry Andric #include "clang/Frontend/FrontendPluginRegistry.h" 23*0b57cec5SDimitry Andric #include "clang/Frontend/Utils.h" 24*0b57cec5SDimitry Andric #include "clang/FrontendTool/Utils.h" 25*0b57cec5SDimitry Andric #include "clang/Rewrite/Frontend/FrontendActions.h" 26*0b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" 27*0b57cec5SDimitry Andric #include "llvm/Option/OptTable.h" 28*0b57cec5SDimitry Andric #include "llvm/Option/Option.h" 29*0b57cec5SDimitry Andric #include "llvm/Support/BuryPointer.h" 30*0b57cec5SDimitry Andric #include "llvm/Support/DynamicLibrary.h" 31*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 32*0b57cec5SDimitry Andric using namespace clang; 33*0b57cec5SDimitry Andric using namespace llvm::opt; 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric namespace clang { 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric static std::unique_ptr<FrontendAction> 38*0b57cec5SDimitry Andric CreateFrontendBaseAction(CompilerInstance &CI) { 39*0b57cec5SDimitry Andric using namespace clang::frontend; 40*0b57cec5SDimitry Andric StringRef Action("unknown"); 41*0b57cec5SDimitry Andric (void)Action; 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric switch (CI.getFrontendOpts().ProgramAction) { 44*0b57cec5SDimitry Andric case ASTDeclList: return llvm::make_unique<ASTDeclListAction>(); 45*0b57cec5SDimitry Andric case ASTDump: return llvm::make_unique<ASTDumpAction>(); 46*0b57cec5SDimitry Andric case ASTPrint: return llvm::make_unique<ASTPrintAction>(); 47*0b57cec5SDimitry Andric case ASTView: return llvm::make_unique<ASTViewAction>(); 48*0b57cec5SDimitry Andric case DumpCompilerOptions: 49*0b57cec5SDimitry Andric return llvm::make_unique<DumpCompilerOptionsAction>(); 50*0b57cec5SDimitry Andric case DumpRawTokens: return llvm::make_unique<DumpRawTokensAction>(); 51*0b57cec5SDimitry Andric case DumpTokens: return llvm::make_unique<DumpTokensAction>(); 52*0b57cec5SDimitry Andric case EmitAssembly: return llvm::make_unique<EmitAssemblyAction>(); 53*0b57cec5SDimitry Andric case EmitBC: return llvm::make_unique<EmitBCAction>(); 54*0b57cec5SDimitry Andric case EmitHTML: return llvm::make_unique<HTMLPrintAction>(); 55*0b57cec5SDimitry Andric case EmitLLVM: return llvm::make_unique<EmitLLVMAction>(); 56*0b57cec5SDimitry Andric case EmitLLVMOnly: return llvm::make_unique<EmitLLVMOnlyAction>(); 57*0b57cec5SDimitry Andric case EmitCodeGenOnly: return llvm::make_unique<EmitCodeGenOnlyAction>(); 58*0b57cec5SDimitry Andric case EmitObj: return llvm::make_unique<EmitObjAction>(); 59*0b57cec5SDimitry Andric case FixIt: return llvm::make_unique<FixItAction>(); 60*0b57cec5SDimitry Andric case GenerateModule: 61*0b57cec5SDimitry Andric return llvm::make_unique<GenerateModuleFromModuleMapAction>(); 62*0b57cec5SDimitry Andric case GenerateModuleInterface: 63*0b57cec5SDimitry Andric return llvm::make_unique<GenerateModuleInterfaceAction>(); 64*0b57cec5SDimitry Andric case GenerateHeaderModule: 65*0b57cec5SDimitry Andric return llvm::make_unique<GenerateHeaderModuleAction>(); 66*0b57cec5SDimitry Andric case GeneratePCH: return llvm::make_unique<GeneratePCHAction>(); 67*0b57cec5SDimitry Andric case GenerateInterfaceYAMLExpV1: 68*0b57cec5SDimitry Andric return llvm::make_unique<GenerateInterfaceYAMLExpV1Action>(); 69*0b57cec5SDimitry Andric case GenerateInterfaceTBEExpV1: 70*0b57cec5SDimitry Andric return llvm::make_unique<GenerateInterfaceTBEExpV1Action>(); 71*0b57cec5SDimitry Andric case InitOnly: return llvm::make_unique<InitOnlyAction>(); 72*0b57cec5SDimitry Andric case ParseSyntaxOnly: return llvm::make_unique<SyntaxOnlyAction>(); 73*0b57cec5SDimitry Andric case ModuleFileInfo: return llvm::make_unique<DumpModuleInfoAction>(); 74*0b57cec5SDimitry Andric case VerifyPCH: return llvm::make_unique<VerifyPCHAction>(); 75*0b57cec5SDimitry Andric case TemplightDump: return llvm::make_unique<TemplightDumpAction>(); 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric case PluginAction: { 78*0b57cec5SDimitry Andric for (FrontendPluginRegistry::iterator it = 79*0b57cec5SDimitry Andric FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); 80*0b57cec5SDimitry Andric it != ie; ++it) { 81*0b57cec5SDimitry Andric if (it->getName() == CI.getFrontendOpts().ActionName) { 82*0b57cec5SDimitry Andric std::unique_ptr<PluginASTAction> P(it->instantiate()); 83*0b57cec5SDimitry Andric if ((P->getActionType() != PluginASTAction::ReplaceAction && 84*0b57cec5SDimitry Andric P->getActionType() != PluginASTAction::Cmdline) || 85*0b57cec5SDimitry Andric !P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) 86*0b57cec5SDimitry Andric return nullptr; 87*0b57cec5SDimitry Andric return std::move(P); 88*0b57cec5SDimitry Andric } 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) 92*0b57cec5SDimitry Andric << CI.getFrontendOpts().ActionName; 93*0b57cec5SDimitry Andric return nullptr; 94*0b57cec5SDimitry Andric } 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric case PrintPreamble: return llvm::make_unique<PrintPreambleAction>(); 97*0b57cec5SDimitry Andric case PrintPreprocessedInput: { 98*0b57cec5SDimitry Andric if (CI.getPreprocessorOutputOpts().RewriteIncludes || 99*0b57cec5SDimitry Andric CI.getPreprocessorOutputOpts().RewriteImports) 100*0b57cec5SDimitry Andric return llvm::make_unique<RewriteIncludesAction>(); 101*0b57cec5SDimitry Andric return llvm::make_unique<PrintPreprocessedAction>(); 102*0b57cec5SDimitry Andric } 103*0b57cec5SDimitry Andric 104*0b57cec5SDimitry Andric case RewriteMacros: return llvm::make_unique<RewriteMacrosAction>(); 105*0b57cec5SDimitry Andric case RewriteTest: return llvm::make_unique<RewriteTestAction>(); 106*0b57cec5SDimitry Andric #if CLANG_ENABLE_OBJC_REWRITER 107*0b57cec5SDimitry Andric case RewriteObjC: return llvm::make_unique<RewriteObjCAction>(); 108*0b57cec5SDimitry Andric #else 109*0b57cec5SDimitry Andric case RewriteObjC: Action = "RewriteObjC"; break; 110*0b57cec5SDimitry Andric #endif 111*0b57cec5SDimitry Andric #if CLANG_ENABLE_ARCMT 112*0b57cec5SDimitry Andric case MigrateSource: 113*0b57cec5SDimitry Andric return llvm::make_unique<arcmt::MigrateSourceAction>(); 114*0b57cec5SDimitry Andric #else 115*0b57cec5SDimitry Andric case MigrateSource: Action = "MigrateSource"; break; 116*0b57cec5SDimitry Andric #endif 117*0b57cec5SDimitry Andric #if CLANG_ENABLE_STATIC_ANALYZER 118*0b57cec5SDimitry Andric case RunAnalysis: return llvm::make_unique<ento::AnalysisAction>(); 119*0b57cec5SDimitry Andric #else 120*0b57cec5SDimitry Andric case RunAnalysis: Action = "RunAnalysis"; break; 121*0b57cec5SDimitry Andric #endif 122*0b57cec5SDimitry Andric case RunPreprocessorOnly: return llvm::make_unique<PreprocessOnlyAction>(); 123*0b57cec5SDimitry Andric case PrintDependencyDirectivesSourceMinimizerOutput: 124*0b57cec5SDimitry Andric return llvm::make_unique<PrintDependencyDirectivesSourceMinimizerAction>(); 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric #if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \ 128*0b57cec5SDimitry Andric || !CLANG_ENABLE_OBJC_REWRITER 129*0b57cec5SDimitry Andric CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action; 130*0b57cec5SDimitry Andric return 0; 131*0b57cec5SDimitry Andric #else 132*0b57cec5SDimitry Andric llvm_unreachable("Invalid program action!"); 133*0b57cec5SDimitry Andric #endif 134*0b57cec5SDimitry Andric } 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric std::unique_ptr<FrontendAction> 137*0b57cec5SDimitry Andric CreateFrontendAction(CompilerInstance &CI) { 138*0b57cec5SDimitry Andric // Create the underlying action. 139*0b57cec5SDimitry Andric std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI); 140*0b57cec5SDimitry Andric if (!Act) 141*0b57cec5SDimitry Andric return nullptr; 142*0b57cec5SDimitry Andric 143*0b57cec5SDimitry Andric const FrontendOptions &FEOpts = CI.getFrontendOpts(); 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric if (FEOpts.FixAndRecompile) { 146*0b57cec5SDimitry Andric Act = llvm::make_unique<FixItRecompile>(std::move(Act)); 147*0b57cec5SDimitry Andric } 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric #if CLANG_ENABLE_ARCMT 150*0b57cec5SDimitry Andric if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource && 151*0b57cec5SDimitry Andric CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) { 152*0b57cec5SDimitry Andric // Potentially wrap the base FE action in an ARC Migrate Tool action. 153*0b57cec5SDimitry Andric switch (FEOpts.ARCMTAction) { 154*0b57cec5SDimitry Andric case FrontendOptions::ARCMT_None: 155*0b57cec5SDimitry Andric break; 156*0b57cec5SDimitry Andric case FrontendOptions::ARCMT_Check: 157*0b57cec5SDimitry Andric Act = llvm::make_unique<arcmt::CheckAction>(std::move(Act)); 158*0b57cec5SDimitry Andric break; 159*0b57cec5SDimitry Andric case FrontendOptions::ARCMT_Modify: 160*0b57cec5SDimitry Andric Act = llvm::make_unique<arcmt::ModifyAction>(std::move(Act)); 161*0b57cec5SDimitry Andric break; 162*0b57cec5SDimitry Andric case FrontendOptions::ARCMT_Migrate: 163*0b57cec5SDimitry Andric Act = llvm::make_unique<arcmt::MigrateAction>(std::move(Act), 164*0b57cec5SDimitry Andric FEOpts.MTMigrateDir, 165*0b57cec5SDimitry Andric FEOpts.ARCMTMigrateReportOut, 166*0b57cec5SDimitry Andric FEOpts.ARCMTMigrateEmitARCErrors); 167*0b57cec5SDimitry Andric break; 168*0b57cec5SDimitry Andric } 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) { 171*0b57cec5SDimitry Andric Act = llvm::make_unique<arcmt::ObjCMigrateAction>(std::move(Act), 172*0b57cec5SDimitry Andric FEOpts.MTMigrateDir, 173*0b57cec5SDimitry Andric FEOpts.ObjCMTAction); 174*0b57cec5SDimitry Andric } 175*0b57cec5SDimitry Andric } 176*0b57cec5SDimitry Andric #endif 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric // If there are any AST files to merge, create a frontend action 179*0b57cec5SDimitry Andric // adaptor to perform the merge. 180*0b57cec5SDimitry Andric if (!FEOpts.ASTMergeFiles.empty()) 181*0b57cec5SDimitry Andric Act = llvm::make_unique<ASTMergeAction>(std::move(Act), 182*0b57cec5SDimitry Andric FEOpts.ASTMergeFiles); 183*0b57cec5SDimitry Andric 184*0b57cec5SDimitry Andric return Act; 185*0b57cec5SDimitry Andric } 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric bool ExecuteCompilerInvocation(CompilerInstance *Clang) { 188*0b57cec5SDimitry Andric // Honor -help. 189*0b57cec5SDimitry Andric if (Clang->getFrontendOpts().ShowHelp) { 190*0b57cec5SDimitry Andric std::unique_ptr<OptTable> Opts = driver::createDriverOptTable(); 191*0b57cec5SDimitry Andric Opts->PrintHelp(llvm::outs(), "clang -cc1 [options] file...", 192*0b57cec5SDimitry Andric "LLVM 'Clang' Compiler: http://clang.llvm.org", 193*0b57cec5SDimitry Andric /*Include=*/driver::options::CC1Option, 194*0b57cec5SDimitry Andric /*Exclude=*/0, /*ShowAllAliases=*/false); 195*0b57cec5SDimitry Andric return true; 196*0b57cec5SDimitry Andric } 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric // Honor -version. 199*0b57cec5SDimitry Andric // 200*0b57cec5SDimitry Andric // FIXME: Use a better -version message? 201*0b57cec5SDimitry Andric if (Clang->getFrontendOpts().ShowVersion) { 202*0b57cec5SDimitry Andric llvm::cl::PrintVersionMessage(); 203*0b57cec5SDimitry Andric return true; 204*0b57cec5SDimitry Andric } 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric // Load any requested plugins. 207*0b57cec5SDimitry Andric for (unsigned i = 0, 208*0b57cec5SDimitry Andric e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { 209*0b57cec5SDimitry Andric const std::string &Path = Clang->getFrontendOpts().Plugins[i]; 210*0b57cec5SDimitry Andric std::string Error; 211*0b57cec5SDimitry Andric if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) 212*0b57cec5SDimitry Andric Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) 213*0b57cec5SDimitry Andric << Path << Error; 214*0b57cec5SDimitry Andric } 215*0b57cec5SDimitry Andric 216*0b57cec5SDimitry Andric // Check if any of the loaded plugins replaces the main AST action 217*0b57cec5SDimitry Andric for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), 218*0b57cec5SDimitry Andric ie = FrontendPluginRegistry::end(); 219*0b57cec5SDimitry Andric it != ie; ++it) { 220*0b57cec5SDimitry Andric std::unique_ptr<PluginASTAction> P(it->instantiate()); 221*0b57cec5SDimitry Andric if (P->getActionType() == PluginASTAction::ReplaceAction) { 222*0b57cec5SDimitry Andric Clang->getFrontendOpts().ProgramAction = clang::frontend::PluginAction; 223*0b57cec5SDimitry Andric Clang->getFrontendOpts().ActionName = it->getName(); 224*0b57cec5SDimitry Andric break; 225*0b57cec5SDimitry Andric } 226*0b57cec5SDimitry Andric } 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric // Honor -mllvm. 229*0b57cec5SDimitry Andric // 230*0b57cec5SDimitry Andric // FIXME: Remove this, one day. 231*0b57cec5SDimitry Andric // This should happen AFTER plugins have been loaded! 232*0b57cec5SDimitry Andric if (!Clang->getFrontendOpts().LLVMArgs.empty()) { 233*0b57cec5SDimitry Andric unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size(); 234*0b57cec5SDimitry Andric auto Args = llvm::make_unique<const char*[]>(NumArgs + 2); 235*0b57cec5SDimitry Andric Args[0] = "clang (LLVM option parsing)"; 236*0b57cec5SDimitry Andric for (unsigned i = 0; i != NumArgs; ++i) 237*0b57cec5SDimitry Andric Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str(); 238*0b57cec5SDimitry Andric Args[NumArgs + 1] = nullptr; 239*0b57cec5SDimitry Andric llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); 240*0b57cec5SDimitry Andric } 241*0b57cec5SDimitry Andric 242*0b57cec5SDimitry Andric #if CLANG_ENABLE_STATIC_ANALYZER 243*0b57cec5SDimitry Andric // These should happen AFTER plugins have been loaded! 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric AnalyzerOptions &AnOpts = *Clang->getAnalyzerOpts(); 246*0b57cec5SDimitry Andric // Honor -analyzer-checker-help and -analyzer-checker-help-hidden. 247*0b57cec5SDimitry Andric if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha || 248*0b57cec5SDimitry Andric AnOpts.ShowCheckerHelpDeveloper) { 249*0b57cec5SDimitry Andric ento::printCheckerHelp(llvm::outs(), 250*0b57cec5SDimitry Andric Clang->getFrontendOpts().Plugins, 251*0b57cec5SDimitry Andric AnOpts, 252*0b57cec5SDimitry Andric Clang->getDiagnostics(), 253*0b57cec5SDimitry Andric Clang->getLangOpts()); 254*0b57cec5SDimitry Andric return true; 255*0b57cec5SDimitry Andric } 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric // Honor -analyzer-checker-option-help. 258*0b57cec5SDimitry Andric if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList || 259*0b57cec5SDimitry Andric AnOpts.ShowCheckerOptionDeveloperList) { 260*0b57cec5SDimitry Andric ento::printCheckerConfigList(llvm::outs(), 261*0b57cec5SDimitry Andric Clang->getFrontendOpts().Plugins, 262*0b57cec5SDimitry Andric *Clang->getAnalyzerOpts(), 263*0b57cec5SDimitry Andric Clang->getDiagnostics(), 264*0b57cec5SDimitry Andric Clang->getLangOpts()); 265*0b57cec5SDimitry Andric return true; 266*0b57cec5SDimitry Andric } 267*0b57cec5SDimitry Andric 268*0b57cec5SDimitry Andric // Honor -analyzer-list-enabled-checkers. 269*0b57cec5SDimitry Andric if (AnOpts.ShowEnabledCheckerList) { 270*0b57cec5SDimitry Andric ento::printEnabledCheckerList(llvm::outs(), 271*0b57cec5SDimitry Andric Clang->getFrontendOpts().Plugins, 272*0b57cec5SDimitry Andric AnOpts, 273*0b57cec5SDimitry Andric Clang->getDiagnostics(), 274*0b57cec5SDimitry Andric Clang->getLangOpts()); 275*0b57cec5SDimitry Andric } 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric // Honor -analyzer-config-help. 278*0b57cec5SDimitry Andric if (AnOpts.ShowConfigOptionsList) { 279*0b57cec5SDimitry Andric ento::printAnalyzerConfigList(llvm::outs()); 280*0b57cec5SDimitry Andric return true; 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric #endif 283*0b57cec5SDimitry Andric 284*0b57cec5SDimitry Andric // If there were errors in processing arguments, don't do anything else. 285*0b57cec5SDimitry Andric if (Clang->getDiagnostics().hasErrorOccurred()) 286*0b57cec5SDimitry Andric return false; 287*0b57cec5SDimitry Andric // Create and execute the frontend action. 288*0b57cec5SDimitry Andric std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang)); 289*0b57cec5SDimitry Andric if (!Act) 290*0b57cec5SDimitry Andric return false; 291*0b57cec5SDimitry Andric bool Success = Clang->ExecuteAction(*Act); 292*0b57cec5SDimitry Andric if (Clang->getFrontendOpts().DisableFree) 293*0b57cec5SDimitry Andric llvm::BuryPointer(std::move(Act)); 294*0b57cec5SDimitry Andric return Success; 295*0b57cec5SDimitry Andric } 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric } // namespace clang 298