1 //===--- ExecuteCompilerInvocation.cpp ------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file holds ExecuteCompilerInvocation(). It is split into its own file to 10 // minimize the impact of pulling in essentially everything else in Flang. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "flang/Frontend/CompilerInstance.h" 15 #include "flang/Frontend/FrontendActions.h" 16 #include "flang/Frontend/FrontendPluginRegistry.h" 17 #include "clang/Driver/Options.h" 18 #include "llvm/Option/OptTable.h" 19 #include "llvm/Option/Option.h" 20 #include "llvm/Support/BuryPointer.h" 21 #include "llvm/Support/CommandLine.h" 22 23 namespace Fortran::frontend { 24 25 static std::unique_ptr<FrontendAction> CreateFrontendBaseAction( 26 CompilerInstance &ci) { 27 28 ActionKind ak = ci.frontendOpts().programAction; 29 switch (ak) { 30 case InputOutputTest: 31 return std::make_unique<InputOutputTestAction>(); 32 case PrintPreprocessedInput: 33 return std::make_unique<PrintPreprocessedAction>(); 34 case ParseSyntaxOnly: 35 return std::make_unique<ParseSyntaxOnlyAction>(); 36 case EmitMLIR: 37 return std::make_unique<EmitMLIRAction>(); 38 case EmitObj: 39 return std::make_unique<EmitObjAction>(); 40 case DebugUnparse: 41 return std::make_unique<DebugUnparseAction>(); 42 case DebugUnparseNoSema: 43 return std::make_unique<DebugUnparseNoSemaAction>(); 44 case DebugUnparseWithSymbols: 45 return std::make_unique<DebugUnparseWithSymbolsAction>(); 46 case DebugDumpSymbols: 47 return std::make_unique<DebugDumpSymbolsAction>(); 48 case DebugDumpParseTree: 49 return std::make_unique<DebugDumpParseTreeAction>(); 50 case DebugDumpParseTreeNoSema: 51 return std::make_unique<DebugDumpParseTreeNoSemaAction>(); 52 case DebugDumpAll: 53 return std::make_unique<DebugDumpAllAction>(); 54 case DebugDumpProvenance: 55 return std::make_unique<DebugDumpProvenanceAction>(); 56 case DebugDumpParsingLog: 57 return std::make_unique<DebugDumpParsingLogAction>(); 58 case DebugMeasureParseTree: 59 return std::make_unique<DebugMeasureParseTreeAction>(); 60 case DebugPreFIRTree: 61 return std::make_unique<DebugPreFIRTreeAction>(); 62 case GetDefinition: 63 return std::make_unique<GetDefinitionAction>(); 64 case GetSymbolsSources: 65 return std::make_unique<GetSymbolsSourcesAction>(); 66 case InitOnly: 67 return std::make_unique<InitOnlyAction>(); 68 case PluginAction: { 69 for (const FrontendPluginRegistry::entry &plugin : 70 FrontendPluginRegistry::entries()) { 71 if (plugin.getName() == ci.frontendOpts().ActionName) { 72 std::unique_ptr<PluginParseTreeAction> p(plugin.instantiate()); 73 return std::move(p); 74 } 75 } 76 unsigned diagID = ci.diagnostics().getCustomDiagID( 77 clang::DiagnosticsEngine::Error, "unable to find plugin '%0'"); 78 ci.diagnostics().Report(diagID) << ci.frontendOpts().ActionName; 79 return nullptr; 80 } 81 default: 82 break; 83 // TODO: 84 // case ParserSyntaxOnly: 85 // case EmitLLVM: 86 // case EmitLLVMOnly: 87 // case EmitCodeGenOnly: 88 // (...) 89 } 90 return 0; 91 } 92 93 std::unique_ptr<FrontendAction> CreateFrontendAction(CompilerInstance &ci) { 94 // Create the underlying action. 95 std::unique_ptr<FrontendAction> act = CreateFrontendBaseAction(ci); 96 if (!act) 97 return nullptr; 98 99 return act; 100 } 101 102 bool ExecuteCompilerInvocation(CompilerInstance *flang) { 103 // Honor -help. 104 if (flang->frontendOpts().showHelp) { 105 clang::driver::getDriverOptTable().printHelp(llvm::outs(), 106 "flang-new -fc1 [options] file...", "LLVM 'Flang' Compiler", 107 /*Include=*/clang::driver::options::FC1Option, 108 /*Exclude=*/llvm::opt::DriverFlag::HelpHidden, 109 /*ShowAllAliases=*/false); 110 return true; 111 } 112 113 // Honor -version. 114 if (flang->frontendOpts().showVersion) { 115 llvm::cl::PrintVersionMessage(); 116 return true; 117 } 118 119 // Load any requested plugins. 120 for (const std::string &Path : flang->frontendOpts().plugins) { 121 std::string Error; 122 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently( 123 Path.c_str(), &Error)) { 124 unsigned diagID = flang->diagnostics().getCustomDiagID( 125 clang::DiagnosticsEngine::Error, "unable to load plugin '%0': '%1'"); 126 flang->diagnostics().Report(diagID) << Path << Error; 127 } 128 } 129 130 // If there were errors in processing arguments, don't do anything else. 131 if (flang->diagnostics().hasErrorOccurred()) { 132 return false; 133 } 134 135 // Create and execute the frontend action. 136 std::unique_ptr<FrontendAction> act(CreateFrontendAction(*flang)); 137 if (!act) 138 return false; 139 140 bool success = flang->ExecuteAction(*act); 141 return success; 142 } 143 144 } // namespace Fortran::frontend 145