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 EmitLLVM: 39 return std::make_unique<EmitLLVMAction>(); 40 case EmitObj: 41 return std::make_unique<EmitObjAction>(); 42 case DebugUnparse: 43 return std::make_unique<DebugUnparseAction>(); 44 case DebugUnparseNoSema: 45 return std::make_unique<DebugUnparseNoSemaAction>(); 46 case DebugUnparseWithSymbols: 47 return std::make_unique<DebugUnparseWithSymbolsAction>(); 48 case DebugDumpSymbols: 49 return std::make_unique<DebugDumpSymbolsAction>(); 50 case DebugDumpParseTree: 51 return std::make_unique<DebugDumpParseTreeAction>(); 52 case DebugDumpParseTreeNoSema: 53 return std::make_unique<DebugDumpParseTreeNoSemaAction>(); 54 case DebugDumpAll: 55 return std::make_unique<DebugDumpAllAction>(); 56 case DebugDumpProvenance: 57 return std::make_unique<DebugDumpProvenanceAction>(); 58 case DebugDumpParsingLog: 59 return std::make_unique<DebugDumpParsingLogAction>(); 60 case DebugMeasureParseTree: 61 return std::make_unique<DebugMeasureParseTreeAction>(); 62 case DebugPreFIRTree: 63 return std::make_unique<DebugPreFIRTreeAction>(); 64 case GetDefinition: 65 return std::make_unique<GetDefinitionAction>(); 66 case GetSymbolsSources: 67 return std::make_unique<GetSymbolsSourcesAction>(); 68 case InitOnly: 69 return std::make_unique<InitOnlyAction>(); 70 case PluginAction: { 71 for (const FrontendPluginRegistry::entry &plugin : 72 FrontendPluginRegistry::entries()) { 73 if (plugin.getName() == ci.frontendOpts().ActionName) { 74 std::unique_ptr<PluginParseTreeAction> p(plugin.instantiate()); 75 return std::move(p); 76 } 77 } 78 unsigned diagID = ci.diagnostics().getCustomDiagID( 79 clang::DiagnosticsEngine::Error, "unable to find plugin '%0'"); 80 ci.diagnostics().Report(diagID) << ci.frontendOpts().ActionName; 81 return nullptr; 82 } 83 default: 84 break; 85 // TODO: 86 // case ParserSyntaxOnly: 87 // case EmitLLVM: 88 // case EmitLLVMOnly: 89 // case EmitCodeGenOnly: 90 // (...) 91 } 92 return 0; 93 } 94 95 std::unique_ptr<FrontendAction> CreateFrontendAction(CompilerInstance &ci) { 96 // Create the underlying action. 97 std::unique_ptr<FrontendAction> act = CreateFrontendBaseAction(ci); 98 if (!act) 99 return nullptr; 100 101 return act; 102 } 103 104 bool ExecuteCompilerInvocation(CompilerInstance *flang) { 105 // Honor -help. 106 if (flang->frontendOpts().showHelp) { 107 clang::driver::getDriverOptTable().printHelp(llvm::outs(), 108 "flang-new -fc1 [options] file...", "LLVM 'Flang' Compiler", 109 /*Include=*/clang::driver::options::FC1Option, 110 /*Exclude=*/llvm::opt::DriverFlag::HelpHidden, 111 /*ShowAllAliases=*/false); 112 return true; 113 } 114 115 // Honor -version. 116 if (flang->frontendOpts().showVersion) { 117 llvm::cl::PrintVersionMessage(); 118 return true; 119 } 120 121 // Load any requested plugins. 122 for (const std::string &Path : flang->frontendOpts().plugins) { 123 std::string Error; 124 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently( 125 Path.c_str(), &Error)) { 126 unsigned diagID = flang->diagnostics().getCustomDiagID( 127 clang::DiagnosticsEngine::Error, "unable to load plugin '%0': '%1'"); 128 flang->diagnostics().Report(diagID) << Path << Error; 129 } 130 } 131 132 // If there were errors in processing arguments, don't do anything else. 133 if (flang->diagnostics().hasErrorOccurred()) { 134 return false; 135 } 136 137 // Create and execute the frontend action. 138 std::unique_ptr<FrontendAction> act(CreateFrontendAction(*flang)); 139 if (!act) 140 return false; 141 142 bool success = flang->ExecuteAction(*act); 143 return success; 144 } 145 146 } // namespace Fortran::frontend 147