1257b2971SCaroline Concatto //===--- ExecuteCompilerInvocation.cpp ------------------------------------===// 2257b2971SCaroline Concatto // 3257b2971SCaroline Concatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4257b2971SCaroline Concatto // See https://llvm.org/LICENSE.txt for license information. 5257b2971SCaroline Concatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6257b2971SCaroline Concatto // 7257b2971SCaroline Concatto //===----------------------------------------------------------------------===// 8257b2971SCaroline Concatto // 9257b2971SCaroline Concatto // This file holds ExecuteCompilerInvocation(). It is split into its own file to 10257b2971SCaroline Concatto // minimize the impact of pulling in essentially everything else in Flang. 11257b2971SCaroline Concatto // 12257b2971SCaroline Concatto //===----------------------------------------------------------------------===// 13257b2971SCaroline Concatto 14257b2971SCaroline Concatto #include "flang/Frontend/CompilerInstance.h" 154c5906cfSCaroline Concatto #include "flang/Frontend/FrontendActions.h" 16f52fc591SStuart Ellis #include "flang/Frontend/FrontendPluginRegistry.h" 17257b2971SCaroline Concatto #include "clang/Driver/Options.h" 18257b2971SCaroline Concatto #include "llvm/Option/OptTable.h" 194c5906cfSCaroline Concatto #include "llvm/Option/Option.h" 204c5906cfSCaroline Concatto #include "llvm/Support/BuryPointer.h" 21257b2971SCaroline Concatto #include "llvm/Support/CommandLine.h" 226c93e1d3SAndrzej Warzynski #include "mlir/IR/MLIRContext.h" 236c93e1d3SAndrzej Warzynski #include "mlir/Pass/PassManager.h" 24257b2971SCaroline Concatto 25257b2971SCaroline Concatto namespace Fortran::frontend { 264c5906cfSCaroline Concatto 27d902dd01SAndrzej Warzynski static std::unique_ptr<FrontendAction> CreateFrontendAction( 284c5906cfSCaroline Concatto CompilerInstance &ci) { 294c5906cfSCaroline Concatto 30d902dd01SAndrzej Warzynski switch (ci.frontendOpts().programAction) { 314c5906cfSCaroline Concatto case InputOutputTest: 324c5906cfSCaroline Concatto return std::make_unique<InputOutputTestAction>(); 33d28de0d7SCaroline Concatto case PrintPreprocessedInput: 34d28de0d7SCaroline Concatto return std::make_unique<PrintPreprocessedAction>(); 357d246cb1SAndrzej Warzynski case ParseSyntaxOnly: 367d246cb1SAndrzej Warzynski return std::make_unique<ParseSyntaxOnlyAction>(); 3769c3309dSAndrzej Warzynski case EmitMLIR: 3869c3309dSAndrzej Warzynski return std::make_unique<EmitMLIRAction>(); 39e993b20cSAndrzej Warzynski case EmitLLVM: 40e993b20cSAndrzej Warzynski return std::make_unique<EmitLLVMAction>(); 41dd56939aSAndrzej Warzynski case EmitLLVMBitcode: 42dd56939aSAndrzej Warzynski return std::make_unique<EmitLLVMBitcodeAction>(); 43e5cdb6c5SAndrzej Warzynski case EmitObj: 44*bb177edcSAndrzej Warzynski return std::make_unique<EmitObjAction>(); 4538101b4eSAndrzej Warzynski case EmitAssembly: 46*bb177edcSAndrzej Warzynski return std::make_unique<EmitAssemblyAction>(); 4796d229c9SAndrzej Warzynski case DebugUnparse: 4896d229c9SAndrzej Warzynski return std::make_unique<DebugUnparseAction>(); 49e81b3401SAndrzej Warzynski case DebugUnparseNoSema: 50e81b3401SAndrzej Warzynski return std::make_unique<DebugUnparseNoSemaAction>(); 5196d229c9SAndrzej Warzynski case DebugUnparseWithSymbols: 5296d229c9SAndrzej Warzynski return std::make_unique<DebugUnparseWithSymbolsAction>(); 534bd08dabSFaris Rehman case DebugDumpSymbols: 544bd08dabSFaris Rehman return std::make_unique<DebugDumpSymbolsAction>(); 554bd08dabSFaris Rehman case DebugDumpParseTree: 564bd08dabSFaris Rehman return std::make_unique<DebugDumpParseTreeAction>(); 578321579bSAndrzej Warzynski case DebugDumpPFT: 588321579bSAndrzej Warzynski return std::make_unique<DebugDumpPFTAction>(); 59e81b3401SAndrzej Warzynski case DebugDumpParseTreeNoSema: 60e81b3401SAndrzej Warzynski return std::make_unique<DebugDumpParseTreeNoSemaAction>(); 61a6be6e31SAndrzej Warzynski case DebugDumpAll: 62a6be6e31SAndrzej Warzynski return std::make_unique<DebugDumpAllAction>(); 634bd08dabSFaris Rehman case DebugDumpProvenance: 644bd08dabSFaris Rehman return std::make_unique<DebugDumpProvenanceAction>(); 65523d7bc6SAndrzej Warzynski case DebugDumpParsingLog: 66523d7bc6SAndrzej Warzynski return std::make_unique<DebugDumpParsingLogAction>(); 67529f7181SFaris Rehman case DebugMeasureParseTree: 68529f7181SFaris Rehman return std::make_unique<DebugMeasureParseTreeAction>(); 69529f7181SFaris Rehman case DebugPreFIRTree: 70529f7181SFaris Rehman return std::make_unique<DebugPreFIRTreeAction>(); 71dc256a44SAndrzej Warzynski case GetDefinition: 72dc256a44SAndrzej Warzynski return std::make_unique<GetDefinitionAction>(); 73eefda605SAndrzej Warzynski case GetSymbolsSources: 74eefda605SAndrzej Warzynski return std::make_unique<GetSymbolsSourcesAction>(); 75e1da3297SStuart Ellis case InitOnly: 76e1da3297SStuart Ellis return std::make_unique<InitOnlyAction>(); 77f52fc591SStuart Ellis case PluginAction: { 78f52fc591SStuart Ellis for (const FrontendPluginRegistry::entry &plugin : 79f52fc591SStuart Ellis FrontendPluginRegistry::entries()) { 80f52fc591SStuart Ellis if (plugin.getName() == ci.frontendOpts().ActionName) { 81f52fc591SStuart Ellis std::unique_ptr<PluginParseTreeAction> p(plugin.instantiate()); 82f52fc591SStuart Ellis return std::move(p); 83f52fc591SStuart Ellis } 84f52fc591SStuart Ellis } 85f52fc591SStuart Ellis unsigned diagID = ci.diagnostics().getCustomDiagID( 86f52fc591SStuart Ellis clang::DiagnosticsEngine::Error, "unable to find plugin '%0'"); 87f52fc591SStuart Ellis ci.diagnostics().Report(diagID) << ci.frontendOpts().ActionName; 88f52fc591SStuart Ellis return nullptr; 89f52fc591SStuart Ellis } 904c5906cfSCaroline Concatto } 914c5906cfSCaroline Concatto 92d902dd01SAndrzej Warzynski llvm_unreachable("Invalid program action!"); 934c5906cfSCaroline Concatto } 94f52fc591SStuart Ellis 95257b2971SCaroline Concatto bool ExecuteCompilerInvocation(CompilerInstance *flang) { 96257b2971SCaroline Concatto // Honor -help. 9723d4c4f3SAndrzej Warzynski if (flang->frontendOpts().showHelp) { 98f1e2d585SFangrui Song clang::driver::getDriverOptTable().printHelp(llvm::outs(), 99257b2971SCaroline Concatto "flang-new -fc1 [options] file...", "LLVM 'Flang' Compiler", 10099edb9b7SAndrzej Warzynski /*Include=*/clang::driver::options::FC1Option, 1014c5906cfSCaroline Concatto /*Exclude=*/llvm::opt::DriverFlag::HelpHidden, 1024c5906cfSCaroline Concatto /*ShowAllAliases=*/false); 103257b2971SCaroline Concatto return true; 104257b2971SCaroline Concatto } 105257b2971SCaroline Concatto 106257b2971SCaroline Concatto // Honor -version. 10723d4c4f3SAndrzej Warzynski if (flang->frontendOpts().showVersion) { 108257b2971SCaroline Concatto llvm::cl::PrintVersionMessage(); 109257b2971SCaroline Concatto return true; 110257b2971SCaroline Concatto } 111257b2971SCaroline Concatto 112f52fc591SStuart Ellis // Load any requested plugins. 113f52fc591SStuart Ellis for (const std::string &Path : flang->frontendOpts().plugins) { 114f52fc591SStuart Ellis std::string Error; 115f52fc591SStuart Ellis if (llvm::sys::DynamicLibrary::LoadLibraryPermanently( 116f52fc591SStuart Ellis Path.c_str(), &Error)) { 117f52fc591SStuart Ellis unsigned diagID = flang->diagnostics().getCustomDiagID( 118f52fc591SStuart Ellis clang::DiagnosticsEngine::Error, "unable to load plugin '%0': '%1'"); 119f52fc591SStuart Ellis flang->diagnostics().Report(diagID) << Path << Error; 120f52fc591SStuart Ellis } 121f52fc591SStuart Ellis } 122f52fc591SStuart Ellis 123a7c08bcfSAndrzej Warzynski // Honor -mllvm. This should happen AFTER plugins have been loaded! 124a7c08bcfSAndrzej Warzynski if (!flang->frontendOpts().llvmArgs.empty()) { 125a7c08bcfSAndrzej Warzynski unsigned numArgs = flang->frontendOpts().llvmArgs.size(); 126a7c08bcfSAndrzej Warzynski auto args = std::make_unique<const char *[]>(numArgs + 2); 127a7c08bcfSAndrzej Warzynski args[0] = "flang (LLVM option parsing)"; 128a7c08bcfSAndrzej Warzynski 129a7c08bcfSAndrzej Warzynski for (unsigned i = 0; i != numArgs; ++i) 130a7c08bcfSAndrzej Warzynski args[i + 1] = flang->frontendOpts().llvmArgs[i].c_str(); 131a7c08bcfSAndrzej Warzynski 132a7c08bcfSAndrzej Warzynski args[numArgs + 1] = nullptr; 133a7c08bcfSAndrzej Warzynski llvm::cl::ParseCommandLineOptions(numArgs + 1, args.get()); 134a7c08bcfSAndrzej Warzynski } 135a7c08bcfSAndrzej Warzynski 1366c93e1d3SAndrzej Warzynski // Honor -mmlir. This should happen AFTER plugins have been loaded! 1376c93e1d3SAndrzej Warzynski if (!flang->frontendOpts().mlirArgs.empty()) { 1386c93e1d3SAndrzej Warzynski mlir::registerMLIRContextCLOptions(); 1396c93e1d3SAndrzej Warzynski mlir::registerPassManagerCLOptions(); 1406c93e1d3SAndrzej Warzynski unsigned numArgs = flang->frontendOpts().mlirArgs.size(); 1416c93e1d3SAndrzej Warzynski auto args = std::make_unique<const char *[]>(numArgs + 2); 1426c93e1d3SAndrzej Warzynski args[0] = "flang (MLIR option parsing)"; 1436c93e1d3SAndrzej Warzynski 1446c93e1d3SAndrzej Warzynski for (unsigned i = 0; i != numArgs; ++i) 1456c93e1d3SAndrzej Warzynski args[i + 1] = flang->frontendOpts().mlirArgs[i].c_str(); 1466c93e1d3SAndrzej Warzynski 1476c93e1d3SAndrzej Warzynski args[numArgs + 1] = nullptr; 1486c93e1d3SAndrzej Warzynski llvm::cl::ParseCommandLineOptions(numArgs + 1, args.get()); 1496c93e1d3SAndrzej Warzynski } 1506c93e1d3SAndrzej Warzynski 151f52fc591SStuart Ellis // If there were errors in processing arguments, don't do anything else. 152f52fc591SStuart Ellis if (flang->diagnostics().hasErrorOccurred()) { 153f52fc591SStuart Ellis return false; 154f52fc591SStuart Ellis } 155f52fc591SStuart Ellis 1564c5906cfSCaroline Concatto // Create and execute the frontend action. 1574c5906cfSCaroline Concatto std::unique_ptr<FrontendAction> act(CreateFrontendAction(*flang)); 1584c5906cfSCaroline Concatto if (!act) 1594c5906cfSCaroline Concatto return false; 1604c5906cfSCaroline Concatto 1614c5906cfSCaroline Concatto bool success = flang->ExecuteAction(*act); 1624c5906cfSCaroline Concatto return success; 163257b2971SCaroline Concatto } 164257b2971SCaroline Concatto 165257b2971SCaroline Concatto } // namespace Fortran::frontend 166