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