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