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