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 //===----------------------------------------------------------------------===//
131e462fafSAndrzej Warzynski //
141e462fafSAndrzej Warzynski // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
151e462fafSAndrzej Warzynski //
161e462fafSAndrzej Warzynski //===----------------------------------------------------------------------===//
17257b2971SCaroline Concatto
18257b2971SCaroline Concatto #include "flang/Frontend/CompilerInstance.h"
194c5906cfSCaroline Concatto #include "flang/Frontend/FrontendActions.h"
20f52fc591SStuart Ellis #include "flang/Frontend/FrontendPluginRegistry.h"
211e462fafSAndrzej Warzynski
221e462fafSAndrzej Warzynski #include "mlir/IR/MLIRContext.h"
231e462fafSAndrzej Warzynski #include "mlir/Pass/PassManager.h"
24257b2971SCaroline Concatto #include "clang/Driver/Options.h"
25257b2971SCaroline Concatto #include "llvm/Option/OptTable.h"
264c5906cfSCaroline Concatto #include "llvm/Option/Option.h"
274c5906cfSCaroline Concatto #include "llvm/Support/BuryPointer.h"
28257b2971SCaroline Concatto #include "llvm/Support/CommandLine.h"
29257b2971SCaroline Concatto
30257b2971SCaroline Concatto namespace Fortran::frontend {
314c5906cfSCaroline Concatto
321e462fafSAndrzej Warzynski static std::unique_ptr<FrontendAction>
createFrontendAction(CompilerInstance & ci)331e462fafSAndrzej Warzynski createFrontendAction(CompilerInstance &ci) {
344c5906cfSCaroline Concatto
351e462fafSAndrzej Warzynski switch (ci.getFrontendOpts().programAction) {
364c5906cfSCaroline Concatto case InputOutputTest:
374c5906cfSCaroline Concatto return std::make_unique<InputOutputTestAction>();
38d28de0d7SCaroline Concatto case PrintPreprocessedInput:
39d28de0d7SCaroline Concatto return std::make_unique<PrintPreprocessedAction>();
407d246cb1SAndrzej Warzynski case ParseSyntaxOnly:
417d246cb1SAndrzej Warzynski return std::make_unique<ParseSyntaxOnlyAction>();
4269c3309dSAndrzej Warzynski case EmitMLIR:
4369c3309dSAndrzej Warzynski return std::make_unique<EmitMLIRAction>();
44e993b20cSAndrzej Warzynski case EmitLLVM:
45e993b20cSAndrzej Warzynski return std::make_unique<EmitLLVMAction>();
46dd56939aSAndrzej Warzynski case EmitLLVMBitcode:
47dd56939aSAndrzej Warzynski return std::make_unique<EmitLLVMBitcodeAction>();
48e5cdb6c5SAndrzej Warzynski case EmitObj:
49bb177edcSAndrzej Warzynski return std::make_unique<EmitObjAction>();
5038101b4eSAndrzej Warzynski case EmitAssembly:
51bb177edcSAndrzej Warzynski return std::make_unique<EmitAssemblyAction>();
5296d229c9SAndrzej Warzynski case DebugUnparse:
5396d229c9SAndrzej Warzynski return std::make_unique<DebugUnparseAction>();
54e81b3401SAndrzej Warzynski case DebugUnparseNoSema:
55e81b3401SAndrzej Warzynski return std::make_unique<DebugUnparseNoSemaAction>();
5696d229c9SAndrzej Warzynski case DebugUnparseWithSymbols:
5796d229c9SAndrzej Warzynski return std::make_unique<DebugUnparseWithSymbolsAction>();
584bd08dabSFaris Rehman case DebugDumpSymbols:
594bd08dabSFaris Rehman return std::make_unique<DebugDumpSymbolsAction>();
604bd08dabSFaris Rehman case DebugDumpParseTree:
614bd08dabSFaris Rehman return std::make_unique<DebugDumpParseTreeAction>();
628321579bSAndrzej Warzynski case DebugDumpPFT:
638321579bSAndrzej Warzynski return std::make_unique<DebugDumpPFTAction>();
64e81b3401SAndrzej Warzynski case DebugDumpParseTreeNoSema:
65e81b3401SAndrzej Warzynski return std::make_unique<DebugDumpParseTreeNoSemaAction>();
66a6be6e31SAndrzej Warzynski case DebugDumpAll:
67a6be6e31SAndrzej Warzynski return std::make_unique<DebugDumpAllAction>();
684bd08dabSFaris Rehman case DebugDumpProvenance:
694bd08dabSFaris Rehman return std::make_unique<DebugDumpProvenanceAction>();
70523d7bc6SAndrzej Warzynski case DebugDumpParsingLog:
71523d7bc6SAndrzej Warzynski return std::make_unique<DebugDumpParsingLogAction>();
72529f7181SFaris Rehman case DebugMeasureParseTree:
73529f7181SFaris Rehman return std::make_unique<DebugMeasureParseTreeAction>();
74529f7181SFaris Rehman case DebugPreFIRTree:
75529f7181SFaris Rehman return std::make_unique<DebugPreFIRTreeAction>();
76dc256a44SAndrzej Warzynski case GetDefinition:
77dc256a44SAndrzej Warzynski return std::make_unique<GetDefinitionAction>();
78eefda605SAndrzej Warzynski case GetSymbolsSources:
79eefda605SAndrzej Warzynski return std::make_unique<GetSymbolsSourcesAction>();
80e1da3297SStuart Ellis case InitOnly:
81e1da3297SStuart Ellis return std::make_unique<InitOnlyAction>();
82f52fc591SStuart Ellis case PluginAction: {
83f52fc591SStuart Ellis for (const FrontendPluginRegistry::entry &plugin :
84f52fc591SStuart Ellis FrontendPluginRegistry::entries()) {
851e462fafSAndrzej Warzynski if (plugin.getName() == ci.getFrontendOpts().actionName) {
86f52fc591SStuart Ellis std::unique_ptr<PluginParseTreeAction> p(plugin.instantiate());
87f52fc591SStuart Ellis return std::move(p);
88f52fc591SStuart Ellis }
89f52fc591SStuart Ellis }
901e462fafSAndrzej Warzynski unsigned diagID = ci.getDiagnostics().getCustomDiagID(
91f52fc591SStuart Ellis clang::DiagnosticsEngine::Error, "unable to find plugin '%0'");
921e462fafSAndrzej Warzynski ci.getDiagnostics().Report(diagID) << ci.getFrontendOpts().actionName;
93f52fc591SStuart Ellis return nullptr;
94f52fc591SStuart Ellis }
954c5906cfSCaroline Concatto }
964c5906cfSCaroline Concatto
97d902dd01SAndrzej Warzynski llvm_unreachable("Invalid program action!");
984c5906cfSCaroline Concatto }
99f52fc591SStuart Ellis
executeCompilerInvocation(CompilerInstance * flang)1001e462fafSAndrzej Warzynski bool executeCompilerInvocation(CompilerInstance *flang) {
101257b2971SCaroline Concatto // Honor -help.
1021e462fafSAndrzej Warzynski if (flang->getFrontendOpts().showHelp) {
103f1e2d585SFangrui Song clang::driver::getDriverOptTable().printHelp(llvm::outs(),
104257b2971SCaroline Concatto "flang-new -fc1 [options] file...", "LLVM 'Flang' Compiler",
10599edb9b7SAndrzej Warzynski /*Include=*/clang::driver::options::FC1Option,
1064c5906cfSCaroline Concatto /*Exclude=*/llvm::opt::DriverFlag::HelpHidden,
1074c5906cfSCaroline Concatto /*ShowAllAliases=*/false);
108257b2971SCaroline Concatto return true;
109257b2971SCaroline Concatto }
110257b2971SCaroline Concatto
111257b2971SCaroline Concatto // Honor -version.
1121e462fafSAndrzej Warzynski if (flang->getFrontendOpts().showVersion) {
113257b2971SCaroline Concatto llvm::cl::PrintVersionMessage();
114257b2971SCaroline Concatto return true;
115257b2971SCaroline Concatto }
116257b2971SCaroline Concatto
117f52fc591SStuart Ellis // Load any requested plugins.
1181e462fafSAndrzej Warzynski for (const std::string &path : flang->getFrontendOpts().plugins) {
1191e462fafSAndrzej Warzynski std::string error;
1201e462fafSAndrzej Warzynski if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(path.c_str(),
1211e462fafSAndrzej Warzynski &error)) {
1221e462fafSAndrzej Warzynski unsigned diagID = flang->getDiagnostics().getCustomDiagID(
123f52fc591SStuart Ellis clang::DiagnosticsEngine::Error, "unable to load plugin '%0': '%1'");
1241e462fafSAndrzej Warzynski flang->getDiagnostics().Report(diagID) << path << error;
125f52fc591SStuart Ellis }
126f52fc591SStuart Ellis }
127f52fc591SStuart Ellis
128a7c08bcfSAndrzej Warzynski // Honor -mllvm. This should happen AFTER plugins have been loaded!
1291e462fafSAndrzej Warzynski if (!flang->getFrontendOpts().llvmArgs.empty()) {
1301e462fafSAndrzej Warzynski unsigned numArgs = flang->getFrontendOpts().llvmArgs.size();
131a7c08bcfSAndrzej Warzynski auto args = std::make_unique<const char *[]>(numArgs + 2);
132a7c08bcfSAndrzej Warzynski args[0] = "flang (LLVM option parsing)";
133a7c08bcfSAndrzej Warzynski
134a7c08bcfSAndrzej Warzynski for (unsigned i = 0; i != numArgs; ++i)
1351e462fafSAndrzej Warzynski args[i + 1] = flang->getFrontendOpts().llvmArgs[i].c_str();
136a7c08bcfSAndrzej Warzynski
137a7c08bcfSAndrzej Warzynski args[numArgs + 1] = nullptr;
138a7c08bcfSAndrzej Warzynski llvm::cl::ParseCommandLineOptions(numArgs + 1, args.get());
139a7c08bcfSAndrzej Warzynski }
140a7c08bcfSAndrzej Warzynski
1416c93e1d3SAndrzej Warzynski // Honor -mmlir. This should happen AFTER plugins have been loaded!
1421e462fafSAndrzej Warzynski if (!flang->getFrontendOpts().mlirArgs.empty()) {
1436c93e1d3SAndrzej Warzynski mlir::registerMLIRContextCLOptions();
1446c93e1d3SAndrzej Warzynski mlir::registerPassManagerCLOptions();
1451e462fafSAndrzej Warzynski unsigned numArgs = flang->getFrontendOpts().mlirArgs.size();
1466c93e1d3SAndrzej Warzynski auto args = std::make_unique<const char *[]>(numArgs + 2);
1476c93e1d3SAndrzej Warzynski args[0] = "flang (MLIR option parsing)";
1486c93e1d3SAndrzej Warzynski
1496c93e1d3SAndrzej Warzynski for (unsigned i = 0; i != numArgs; ++i)
1501e462fafSAndrzej Warzynski args[i + 1] = flang->getFrontendOpts().mlirArgs[i].c_str();
1516c93e1d3SAndrzej Warzynski
1526c93e1d3SAndrzej Warzynski args[numArgs + 1] = nullptr;
1536c93e1d3SAndrzej Warzynski llvm::cl::ParseCommandLineOptions(numArgs + 1, args.get());
1546c93e1d3SAndrzej Warzynski }
1556c93e1d3SAndrzej Warzynski
156f52fc591SStuart Ellis // If there were errors in processing arguments, don't do anything else.
1571e462fafSAndrzej Warzynski if (flang->getDiagnostics().hasErrorOccurred()) {
158f52fc591SStuart Ellis return false;
159f52fc591SStuart Ellis }
160f52fc591SStuart Ellis
161*43084160SPeixin Qiao // Honor color diagnostics.
162*43084160SPeixin Qiao flang->getDiagnosticOpts().ShowColors = flang->getFrontendOpts().showColors;
163*43084160SPeixin Qiao
1644c5906cfSCaroline Concatto // Create and execute the frontend action.
1651e462fafSAndrzej Warzynski std::unique_ptr<FrontendAction> act(createFrontendAction(*flang));
1664c5906cfSCaroline Concatto if (!act)
1674c5906cfSCaroline Concatto return false;
1684c5906cfSCaroline Concatto
1691e462fafSAndrzej Warzynski bool success = flang->executeAction(*act);
1704c5906cfSCaroline Concatto return success;
171257b2971SCaroline Concatto }
172257b2971SCaroline Concatto
173257b2971SCaroline Concatto } // namespace Fortran::frontend
174