1257b2971SCaroline Concatto //===- CompilerInvocation.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 //===----------------------------------------------------------------------===// 81e462fafSAndrzej Warzynski // 91e462fafSAndrzej Warzynski // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 101e462fafSAndrzej Warzynski // 111e462fafSAndrzej Warzynski //===----------------------------------------------------------------------===// 12257b2971SCaroline Concatto 13257b2971SCaroline Concatto #include "flang/Frontend/CompilerInvocation.h" 146d48a1a5SFaris Rehman #include "flang/Common/Fortran-features.h" 154a5ac14eSDominik Adamski #include "flang/Common/OpenMP-features.h" 16541f5c4aSHussain Kadhem #include "flang/Common/Version.h" 17869385b1SAndrzej Warzynski #include "flang/Frontend/CodeGenOptions.h" 187809fa20SFaris Rehman #include "flang/Frontend/PreprocessorOptions.h" 192e9439e4SAndrzej Warzynski #include "flang/Frontend/TargetOptions.h" 206d48a1a5SFaris Rehman #include "flang/Semantics/semantics.h" 21e59e8488SjeanPerier #include "flang/Tools/TargetSetup.h" 22197d9a55SFaris Rehman #include "flang/Version.inc" 23257b2971SCaroline Concatto #include "clang/Basic/AllDiagnostics.h" 24257b2971SCaroline Concatto #include "clang/Basic/DiagnosticDriver.h" 25257b2971SCaroline Concatto #include "clang/Basic/DiagnosticOptions.h" 26257b2971SCaroline Concatto #include "clang/Driver/DriverDiagnostic.h" 27869385b1SAndrzej Warzynski #include "clang/Driver/OptionUtils.h" 28257b2971SCaroline Concatto #include "clang/Driver/Options.h" 29257b2971SCaroline Concatto #include "llvm/ADT/StringRef.h" 30257b2971SCaroline Concatto #include "llvm/ADT/StringSwitch.h" 31e2b7424dSSacha Ballantyne #include "llvm/Frontend/Debug/Options.h" 32257b2971SCaroline Concatto #include "llvm/Option/Arg.h" 33257b2971SCaroline Concatto #include "llvm/Option/ArgList.h" 34257b2971SCaroline Concatto #include "llvm/Option/OptTable.h" 359e6b46a9SDavid Truby #include "llvm/Support/CodeGen.h" 36cd4abc52SArnamoy Bhattacharyya #include "llvm/Support/FileSystem.h" 37cd4abc52SArnamoy Bhattacharyya #include "llvm/Support/FileUtilities.h" 385597ec2dSserge-sans-paille #include "llvm/Support/Path.h" 398d51d37eSAndrzej Warzynski #include "llvm/Support/Process.h" 40257b2971SCaroline Concatto #include "llvm/Support/raw_ostream.h" 41d768bf99SArchibald Elliott #include "llvm/TargetParser/Host.h" 4262c7f035SArchibald Elliott #include "llvm/TargetParser/Triple.h" 4384a0a3d3SPaul Osmialowski #include <algorithm> 44541f5c4aSHussain Kadhem #include <cstdlib> 456d48a1a5SFaris Rehman #include <memory> 464d4d4785SKazu Hirata #include <optional> 47257b2971SCaroline Concatto 48257b2971SCaroline Concatto using namespace Fortran::frontend; 49257b2971SCaroline Concatto 50257b2971SCaroline Concatto //===----------------------------------------------------------------------===// 51257b2971SCaroline Concatto // Initialization. 52257b2971SCaroline Concatto //===----------------------------------------------------------------------===// 53257b2971SCaroline Concatto CompilerInvocationBase::CompilerInvocationBase() 541e462fafSAndrzej Warzynski : diagnosticOpts(new clang::DiagnosticOptions()), 551e462fafSAndrzej Warzynski preprocessorOpts(new PreprocessorOptions()) {} 56257b2971SCaroline Concatto 57257b2971SCaroline Concatto CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &x) 581e462fafSAndrzej Warzynski : diagnosticOpts(new clang::DiagnosticOptions(x.getDiagnosticOpts())), 591e462fafSAndrzej Warzynski preprocessorOpts(new PreprocessorOptions(x.getPreprocessorOpts())) {} 60257b2971SCaroline Concatto 61257b2971SCaroline Concatto CompilerInvocationBase::~CompilerInvocationBase() = default; 62257b2971SCaroline Concatto 63257b2971SCaroline Concatto //===----------------------------------------------------------------------===// 64257b2971SCaroline Concatto // Deserialization (from args) 65257b2971SCaroline Concatto //===----------------------------------------------------------------------===// 6643084160SPeixin Qiao static bool parseShowColorsArgs(const llvm::opt::ArgList &args, 6743084160SPeixin Qiao bool defaultColor = true) { 6843084160SPeixin Qiao // Color diagnostics default to auto ("on" if terminal supports) in the 6906eb10daSBrad Richardson // compiler driver `flang` but default to off in the frontend driver 7006eb10daSBrad Richardson // `flang -fc1`, needing an explicit OPT_fdiagnostics_color. 718d51d37eSAndrzej Warzynski // Support both clang's -f[no-]color-diagnostics and gcc's 728d51d37eSAndrzej Warzynski // -f[no-]diagnostics-colors[=never|always|auto]. 738d51d37eSAndrzej Warzynski enum { 748d51d37eSAndrzej Warzynski Colors_On, 758d51d37eSAndrzej Warzynski Colors_Off, 768d51d37eSAndrzej Warzynski Colors_Auto 771e462fafSAndrzej Warzynski } showColors = defaultColor ? Colors_Auto : Colors_Off; 788d51d37eSAndrzej Warzynski 798d51d37eSAndrzej Warzynski for (auto *a : args) { 801e462fafSAndrzej Warzynski const llvm::opt::Option &opt = a->getOption(); 811e462fafSAndrzej Warzynski if (opt.matches(clang::driver::options::OPT_fcolor_diagnostics)) { 821e462fafSAndrzej Warzynski showColors = Colors_On; 831e462fafSAndrzej Warzynski } else if (opt.matches(clang::driver::options::OPT_fno_color_diagnostics)) { 841e462fafSAndrzej Warzynski showColors = Colors_Off; 851e462fafSAndrzej Warzynski } else if (opt.matches(clang::driver::options::OPT_fdiagnostics_color_EQ)) { 868d51d37eSAndrzej Warzynski llvm::StringRef value(a->getValue()); 878d51d37eSAndrzej Warzynski if (value == "always") 881e462fafSAndrzej Warzynski showColors = Colors_On; 898d51d37eSAndrzej Warzynski else if (value == "never") 901e462fafSAndrzej Warzynski showColors = Colors_Off; 918d51d37eSAndrzej Warzynski else if (value == "auto") 921e462fafSAndrzej Warzynski showColors = Colors_Auto; 938d51d37eSAndrzej Warzynski } 948d51d37eSAndrzej Warzynski } 958d51d37eSAndrzej Warzynski 961e462fafSAndrzej Warzynski return showColors == Colors_On || 971e462fafSAndrzej Warzynski (showColors == Colors_Auto && 981e462fafSAndrzej Warzynski llvm::sys::Process::StandardErrHasColors()); 998d51d37eSAndrzej Warzynski } 1008d51d37eSAndrzej Warzynski 101bbdf5c37SAndrzej Warzynski /// Extracts the optimisation level from \a args. 102bbdf5c37SAndrzej Warzynski static unsigned getOptimizationLevel(llvm::opt::ArgList &args, 103bbdf5c37SAndrzej Warzynski clang::DiagnosticsEngine &diags) { 1040a1aa6cdSArthur Eubanks unsigned defaultOpt = 0; 105bbdf5c37SAndrzej Warzynski 106bbdf5c37SAndrzej Warzynski if (llvm::opt::Arg *a = 107bbdf5c37SAndrzej Warzynski args.getLastArg(clang::driver::options::OPT_O_Group)) { 108bbdf5c37SAndrzej Warzynski if (a->getOption().matches(clang::driver::options::OPT_O0)) 1090a1aa6cdSArthur Eubanks return 0; 110bbdf5c37SAndrzej Warzynski 111bbdf5c37SAndrzej Warzynski assert(a->getOption().matches(clang::driver::options::OPT_O)); 112bbdf5c37SAndrzej Warzynski 113bbdf5c37SAndrzej Warzynski return getLastArgIntValue(args, clang::driver::options::OPT_O, defaultOpt, 114bbdf5c37SAndrzej Warzynski diags); 115bbdf5c37SAndrzej Warzynski } 116bbdf5c37SAndrzej Warzynski 117bbdf5c37SAndrzej Warzynski return defaultOpt; 118bbdf5c37SAndrzej Warzynski } 119bbdf5c37SAndrzej Warzynski 1201e462fafSAndrzej Warzynski bool Fortran::frontend::parseDiagnosticArgs(clang::DiagnosticOptions &opts, 12143084160SPeixin Qiao llvm::opt::ArgList &args) { 12243084160SPeixin Qiao opts.ShowColors = parseShowColorsArgs(args); 1238d51d37eSAndrzej Warzynski 1248d51d37eSAndrzej Warzynski return true; 1258d51d37eSAndrzej Warzynski } 1268d51d37eSAndrzej Warzynski 127e2b7424dSSacha Ballantyne static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts, 128e2b7424dSSacha Ballantyne llvm::opt::ArgList &args, 129e2b7424dSSacha Ballantyne clang::DiagnosticsEngine &diags) { 130e2b7424dSSacha Ballantyne using DebugInfoKind = llvm::codegenoptions::DebugInfoKind; 131e2b7424dSSacha Ballantyne if (llvm::opt::Arg *arg = 132e2b7424dSSacha Ballantyne args.getLastArg(clang::driver::options::OPT_debug_info_kind_EQ)) { 133e2b7424dSSacha Ballantyne std::optional<DebugInfoKind> val = 134e2b7424dSSacha Ballantyne llvm::StringSwitch<std::optional<DebugInfoKind>>(arg->getValue()) 135e2b7424dSSacha Ballantyne .Case("line-tables-only", llvm::codegenoptions::DebugLineTablesOnly) 136e2b7424dSSacha Ballantyne .Case("line-directives-only", 137e2b7424dSSacha Ballantyne llvm::codegenoptions::DebugDirectivesOnly) 138e2b7424dSSacha Ballantyne .Case("constructor", llvm::codegenoptions::DebugInfoConstructor) 139e2b7424dSSacha Ballantyne .Case("limited", llvm::codegenoptions::LimitedDebugInfo) 140e2b7424dSSacha Ballantyne .Case("standalone", llvm::codegenoptions::FullDebugInfo) 141e2b7424dSSacha Ballantyne .Case("unused-types", llvm::codegenoptions::UnusedTypeInfo) 142e2b7424dSSacha Ballantyne .Default(std::nullopt); 143e2b7424dSSacha Ballantyne if (!val.has_value()) { 144e2b7424dSSacha Ballantyne diags.Report(clang::diag::err_drv_invalid_value) 145e2b7424dSSacha Ballantyne << arg->getAsString(args) << arg->getValue(); 146e2b7424dSSacha Ballantyne return false; 147e2b7424dSSacha Ballantyne } 148e2b7424dSSacha Ballantyne opts.setDebugInfo(val.value()); 149e2b7424dSSacha Ballantyne if (val != llvm::codegenoptions::DebugLineTablesOnly && 150087b33bbSabidh val != llvm::codegenoptions::FullDebugInfo && 151e2b7424dSSacha Ballantyne val != llvm::codegenoptions::NoDebugInfo) { 152e2b7424dSSacha Ballantyne const auto debugWarning = diags.getCustomDiagID( 153e2b7424dSSacha Ballantyne clang::DiagnosticsEngine::Warning, "Unsupported debug option: %0"); 154e2b7424dSSacha Ballantyne diags.Report(debugWarning) << arg->getValue(); 155e2b7424dSSacha Ballantyne } 156e2b7424dSSacha Ballantyne } 157e2b7424dSSacha Ballantyne return true; 158e2b7424dSSacha Ballantyne } 159e2b7424dSSacha Ballantyne 160a207e630STom Eccles static bool parseVectorLibArg(Fortran::frontend::CodeGenOptions &opts, 161a207e630STom Eccles llvm::opt::ArgList &args, 162a207e630STom Eccles clang::DiagnosticsEngine &diags) { 163a207e630STom Eccles llvm::opt::Arg *arg = args.getLastArg(clang::driver::options::OPT_fveclib); 164a207e630STom Eccles if (!arg) 165a207e630STom Eccles return true; 166a207e630STom Eccles 167a207e630STom Eccles using VectorLibrary = llvm::driver::VectorLibrary; 168a207e630STom Eccles std::optional<VectorLibrary> val = 169a207e630STom Eccles llvm::StringSwitch<std::optional<VectorLibrary>>(arg->getValue()) 170a207e630STom Eccles .Case("Accelerate", VectorLibrary::Accelerate) 171a207e630STom Eccles .Case("LIBMVEC", VectorLibrary::LIBMVEC) 172a207e630STom Eccles .Case("MASSV", VectorLibrary::MASSV) 173a207e630STom Eccles .Case("SVML", VectorLibrary::SVML) 174a207e630STom Eccles .Case("SLEEF", VectorLibrary::SLEEF) 175a207e630STom Eccles .Case("Darwin_libsystem_m", VectorLibrary::Darwin_libsystem_m) 176a207e630STom Eccles .Case("ArmPL", VectorLibrary::ArmPL) 177a207e630STom Eccles .Case("NoLibrary", VectorLibrary::NoLibrary) 178a207e630STom Eccles .Default(std::nullopt); 179a207e630STom Eccles if (!val.has_value()) { 180a207e630STom Eccles diags.Report(clang::diag::err_drv_invalid_value) 181a207e630STom Eccles << arg->getAsString(args) << arg->getValue(); 182a207e630STom Eccles return false; 183a207e630STom Eccles } 184a207e630STom Eccles opts.setVecLib(val.value()); 185a207e630STom Eccles return true; 186a207e630STom Eccles } 187a207e630STom Eccles 18891989c67SVictor Kingi // Generate an OptRemark object containing info on if the -Rgroup 18991989c67SVictor Kingi // specified is enabled or not. 19091989c67SVictor Kingi static CodeGenOptions::OptRemark 1918e315c6cSVictor Kingi parseOptimizationRemark(clang::DiagnosticsEngine &diags, 1928e315c6cSVictor Kingi llvm::opt::ArgList &args, llvm::opt::OptSpecifier optEq, 19391989c67SVictor Kingi llvm::StringRef remarkOptName) { 19491989c67SVictor Kingi assert((remarkOptName == "pass" || remarkOptName == "pass-missed" || 19591989c67SVictor Kingi remarkOptName == "pass-analysis") && 1968e315c6cSVictor Kingi "Unsupported remark option name provided."); 19791989c67SVictor Kingi CodeGenOptions::OptRemark result; 19891989c67SVictor Kingi 19991989c67SVictor Kingi for (llvm::opt::Arg *a : args) { 20091989c67SVictor Kingi if (a->getOption().matches(clang::driver::options::OPT_R_Joined)) { 20191989c67SVictor Kingi llvm::StringRef value = a->getValue(); 20291989c67SVictor Kingi 20391989c67SVictor Kingi if (value == remarkOptName) { 20491989c67SVictor Kingi result.Kind = CodeGenOptions::RemarkKind::RK_Enabled; 20591989c67SVictor Kingi // Enable everything 20691989c67SVictor Kingi result.Pattern = ".*"; 20791989c67SVictor Kingi result.Regex = std::make_shared<llvm::Regex>(result.Pattern); 20891989c67SVictor Kingi 20991989c67SVictor Kingi } else if (value.split('-') == 21091989c67SVictor Kingi std::make_pair(llvm::StringRef("no"), remarkOptName)) { 21191989c67SVictor Kingi result.Kind = CodeGenOptions::RemarkKind::RK_Disabled; 21291989c67SVictor Kingi // Disable everything 21391989c67SVictor Kingi result.Pattern = ""; 21491989c67SVictor Kingi result.Regex = nullptr; 21591989c67SVictor Kingi } 2168e315c6cSVictor Kingi } else if (a->getOption().matches(optEq)) { 2178e315c6cSVictor Kingi result.Kind = CodeGenOptions::RemarkKind::RK_WithPattern; 2188e315c6cSVictor Kingi result.Pattern = a->getValue(); 2198e315c6cSVictor Kingi result.Regex = std::make_shared<llvm::Regex>(result.Pattern); 2208e315c6cSVictor Kingi std::string regexError; 2218e315c6cSVictor Kingi 2228e315c6cSVictor Kingi if (!result.Regex->isValid(regexError)) { 2238e315c6cSVictor Kingi diags.Report(clang::diag::err_drv_optimization_remark_pattern) 2248e315c6cSVictor Kingi << regexError << a->getAsString(args); 2258e315c6cSVictor Kingi return CodeGenOptions::OptRemark(); 2268e315c6cSVictor Kingi } 22791989c67SVictor Kingi } 22891989c67SVictor Kingi } 22991989c67SVictor Kingi return result; 23091989c67SVictor Kingi } 23191989c67SVictor Kingi 232869385b1SAndrzej Warzynski static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, 233869385b1SAndrzej Warzynski llvm::opt::ArgList &args, 234869385b1SAndrzej Warzynski clang::DiagnosticsEngine &diags) { 235bbdf5c37SAndrzej Warzynski opts.OptimizationLevel = getOptimizationLevel(args, diags); 236869385b1SAndrzej Warzynski 237869385b1SAndrzej Warzynski if (args.hasFlag(clang::driver::options::OPT_fdebug_pass_manager, 238869385b1SAndrzej Warzynski clang::driver::options::OPT_fno_debug_pass_manager, false)) 239869385b1SAndrzej Warzynski opts.DebugPassManager = 1; 240ef5ede52SUsman Nadeem 241bf81ba37STom Eccles if (args.hasFlag(clang::driver::options::OPT_fstack_arrays, 242f04ccadfSVictor Kingi clang::driver::options::OPT_fno_stack_arrays, false)) 243bf81ba37STom Eccles opts.StackArrays = 1; 244f04ccadfSVictor Kingi 245efae695dSMats Petersson if (args.hasFlag(clang::driver::options::OPT_floop_versioning, 246f04ccadfSVictor Kingi clang::driver::options::OPT_fno_loop_versioning, false)) 247efae695dSMats Petersson opts.LoopVersioning = 1; 248bf81ba37STom Eccles 2490195ec45SDavid Truby opts.UnrollLoops = args.hasFlag(clang::driver::options::OPT_funroll_loops, 2500195ec45SDavid Truby clang::driver::options::OPT_fno_unroll_loops, 2510195ec45SDavid Truby (opts.OptimizationLevel > 1)); 2520195ec45SDavid Truby 253374e8288STom Eccles opts.AliasAnalysis = opts.OptimizationLevel > 0; 254ac0015feSTom Eccles 25504873773SRadu Salavat // -mframe-pointer=none/non-leaf/all option. 25604873773SRadu Salavat if (const llvm::opt::Arg *a = 25704873773SRadu Salavat args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { 25804873773SRadu Salavat std::optional<llvm::FramePointerKind> val = 25904873773SRadu Salavat llvm::StringSwitch<std::optional<llvm::FramePointerKind>>(a->getValue()) 26004873773SRadu Salavat .Case("none", llvm::FramePointerKind::None) 26104873773SRadu Salavat .Case("non-leaf", llvm::FramePointerKind::NonLeaf) 26204873773SRadu Salavat .Case("all", llvm::FramePointerKind::All) 26304873773SRadu Salavat .Default(std::nullopt); 26404873773SRadu Salavat 26504873773SRadu Salavat if (!val.has_value()) { 26604873773SRadu Salavat diags.Report(clang::diag::err_drv_invalid_value) 26704873773SRadu Salavat << a->getAsString(args) << a->getValue(); 26804873773SRadu Salavat } else 26904873773SRadu Salavat opts.setFramePointer(val.value()); 27004873773SRadu Salavat } 27104873773SRadu Salavat 272c3821b8dSTarun Prabhu for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) 273c3821b8dSTarun Prabhu opts.LLVMPassPlugins.push_back(a->getValue()); 274c3821b8dSTarun Prabhu 27540d8c066SJan Sjodin // -fembed-offload-object option 27640d8c066SJan Sjodin for (auto *a : 27740d8c066SJan Sjodin args.filtered(clang::driver::options::OPT_fembed_offload_object_EQ)) 27840d8c066SJan Sjodin opts.OffloadObjects.push_back(a->getValue()); 27940d8c066SJan Sjodin 2800fdfb65eSNadeem, Usman // -flto=full/thin option. 2810fdfb65eSNadeem, Usman if (const llvm::opt::Arg *a = 2820fdfb65eSNadeem, Usman args.getLastArg(clang::driver::options::OPT_flto_EQ)) { 2830fdfb65eSNadeem, Usman llvm::StringRef s = a->getValue(); 2840fdfb65eSNadeem, Usman assert((s == "full" || s == "thin") && "Unknown LTO mode."); 2850fdfb65eSNadeem, Usman if (s == "full") 2860fdfb65eSNadeem, Usman opts.PrepareForFullLTO = true; 2870fdfb65eSNadeem, Usman else 2880fdfb65eSNadeem, Usman opts.PrepareForThinLTO = true; 2890fdfb65eSNadeem, Usman } 2900fdfb65eSNadeem, Usman 29195943d2fSDominik Adamski if (const llvm::opt::Arg *a = args.getLastArg( 29295943d2fSDominik Adamski clang::driver::options::OPT_mcode_object_version_EQ)) { 29395943d2fSDominik Adamski llvm::StringRef s = a->getValue(); 294500846d2SPierre van Houtryve if (s == "6") 295500846d2SPierre van Houtryve opts.CodeObjectVersion = llvm::CodeObjectVersionKind::COV_6; 29695943d2fSDominik Adamski if (s == "5") 29795943d2fSDominik Adamski opts.CodeObjectVersion = llvm::CodeObjectVersionKind::COV_5; 29895943d2fSDominik Adamski if (s == "4") 29995943d2fSDominik Adamski opts.CodeObjectVersion = llvm::CodeObjectVersionKind::COV_4; 30095943d2fSDominik Adamski if (s == "none") 30195943d2fSDominik Adamski opts.CodeObjectVersion = llvm::CodeObjectVersionKind::COV_None; 30295943d2fSDominik Adamski } 30395943d2fSDominik Adamski 304f04ccadfSVictor Kingi // -f[no-]save-optimization-record[=<format>] 305f04ccadfSVictor Kingi if (const llvm::opt::Arg *a = 306f04ccadfSVictor Kingi args.getLastArg(clang::driver::options::OPT_opt_record_file)) 307f04ccadfSVictor Kingi opts.OptRecordFile = a->getValue(); 308f04ccadfSVictor Kingi 30991989c67SVictor Kingi // Optimization file format. Defaults to yaml 310f04ccadfSVictor Kingi if (const llvm::opt::Arg *a = 311f04ccadfSVictor Kingi args.getLastArg(clang::driver::options::OPT_opt_record_format)) 312f04ccadfSVictor Kingi opts.OptRecordFormat = a->getValue(); 313f04ccadfSVictor Kingi 31491989c67SVictor Kingi // Specifies, using a regex, which successful optimization passes(middle and 31591989c67SVictor Kingi // backend), to include in the final optimization record file generated. If 31691989c67SVictor Kingi // not provided -fsave-optimization-record will include all passes. 317f04ccadfSVictor Kingi if (const llvm::opt::Arg *a = 318f04ccadfSVictor Kingi args.getLastArg(clang::driver::options::OPT_opt_record_passes)) 319f04ccadfSVictor Kingi opts.OptRecordPasses = a->getValue(); 320f04ccadfSVictor Kingi 32191989c67SVictor Kingi // Create OptRemark that allows printing of all successful optimization 32291989c67SVictor Kingi // passes applied. 3238e315c6cSVictor Kingi opts.OptimizationRemark = 3248e315c6cSVictor Kingi parseOptimizationRemark(diags, args, clang::driver::options::OPT_Rpass_EQ, 3258e315c6cSVictor Kingi /*remarkOptName=*/"pass"); 32691989c67SVictor Kingi 32791989c67SVictor Kingi // Create OptRemark that allows all missed optimization passes to be printed. 3288e315c6cSVictor Kingi opts.OptimizationRemarkMissed = parseOptimizationRemark( 3298e315c6cSVictor Kingi diags, args, clang::driver::options::OPT_Rpass_missed_EQ, 3308e315c6cSVictor Kingi /*remarkOptName=*/"pass-missed"); 33191989c67SVictor Kingi 33291989c67SVictor Kingi // Create OptRemark that allows all optimization decisions made by LLVM 33391989c67SVictor Kingi // to be printed. 3348e315c6cSVictor Kingi opts.OptimizationRemarkAnalysis = parseOptimizationRemark( 3358e315c6cSVictor Kingi diags, args, clang::driver::options::OPT_Rpass_analysis_EQ, 3368e315c6cSVictor Kingi /*remarkOptName=*/"pass-analysis"); 33791989c67SVictor Kingi 33812da8ef0SVictor Kingi if (opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo) { 33912da8ef0SVictor Kingi // If the user requested a flag that requires source locations available in 34012da8ef0SVictor Kingi // the backend, make sure that the backend tracks source location 34112da8ef0SVictor Kingi // information. 34212da8ef0SVictor Kingi bool needLocTracking = !opts.OptRecordFile.empty() || 34312da8ef0SVictor Kingi !opts.OptRecordPasses.empty() || 34412da8ef0SVictor Kingi !opts.OptRecordFormat.empty() || 34512da8ef0SVictor Kingi opts.OptimizationRemark.hasValidPattern() || 34612da8ef0SVictor Kingi opts.OptimizationRemarkMissed.hasValidPattern() || 34712da8ef0SVictor Kingi opts.OptimizationRemarkAnalysis.hasValidPattern(); 34812da8ef0SVictor Kingi 34912da8ef0SVictor Kingi if (needLocTracking) 35012da8ef0SVictor Kingi opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly); 35112da8ef0SVictor Kingi } 35212da8ef0SVictor Kingi 35333be8341SSergio Afonso if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ)) 35433be8341SSergio Afonso opts.SaveTempsDir = a->getValue(); 35533be8341SSergio Afonso 356839344f0STarun Prabhu // -record-command-line option. 357839344f0STarun Prabhu if (const llvm::opt::Arg *a = 358839344f0STarun Prabhu args.getLastArg(clang::driver::options::OPT_record_command_line)) { 359839344f0STarun Prabhu opts.RecordCommandLine = a->getValue(); 360839344f0STarun Prabhu } 361839344f0STarun Prabhu 362b75e7c61SJan Leyonberg // -mlink-builtin-bitcode 363b75e7c61SJan Leyonberg for (auto *a : 364b75e7c61SJan Leyonberg args.filtered(clang::driver::options::OPT_mlink_builtin_bitcode)) 365b75e7c61SJan Leyonberg opts.BuiltinBCLibs.push_back(a->getValue()); 366b75e7c61SJan Leyonberg 367ef5ede52SUsman Nadeem // -mrelocation-model option. 3680fdfb65eSNadeem, Usman if (const llvm::opt::Arg *a = 369ef5ede52SUsman Nadeem args.getLastArg(clang::driver::options::OPT_mrelocation_model)) { 3700fdfb65eSNadeem, Usman llvm::StringRef modelName = a->getValue(); 3710fdfb65eSNadeem, Usman auto relocModel = 3720fdfb65eSNadeem, Usman llvm::StringSwitch<std::optional<llvm::Reloc::Model>>(modelName) 373ef5ede52SUsman Nadeem .Case("static", llvm::Reloc::Static) 374ef5ede52SUsman Nadeem .Case("pic", llvm::Reloc::PIC_) 375ef5ede52SUsman Nadeem .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC) 376ef5ede52SUsman Nadeem .Case("ropi", llvm::Reloc::ROPI) 377ef5ede52SUsman Nadeem .Case("rwpi", llvm::Reloc::RWPI) 378ef5ede52SUsman Nadeem .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI) 3799a417395SKazu Hirata .Default(std::nullopt); 3800fdfb65eSNadeem, Usman if (relocModel.has_value()) 3810fdfb65eSNadeem, Usman opts.setRelocationModel(*relocModel); 382ef5ede52SUsman Nadeem else 383ef5ede52SUsman Nadeem diags.Report(clang::diag::err_drv_invalid_value) 3840fdfb65eSNadeem, Usman << a->getAsString(args) << modelName; 385ef5ede52SUsman Nadeem } 386ef5ede52SUsman Nadeem 387ef5ede52SUsman Nadeem // -pic-level and -pic-is-pie option. 3880fdfb65eSNadeem, Usman if (int picLevel = getLastArgIntValue( 389ef5ede52SUsman Nadeem args, clang::driver::options::OPT_pic_level, 0, diags)) { 3900fdfb65eSNadeem, Usman if (picLevel > 2) 391ef5ede52SUsman Nadeem diags.Report(clang::diag::err_drv_invalid_value) 392ef5ede52SUsman Nadeem << args.getLastArg(clang::driver::options::OPT_pic_level) 393ef5ede52SUsman Nadeem ->getAsString(args) 3940fdfb65eSNadeem, Usman << picLevel; 395ef5ede52SUsman Nadeem 3960fdfb65eSNadeem, Usman opts.PICLevel = picLevel; 397ef5ede52SUsman Nadeem if (args.hasArg(clang::driver::options::OPT_pic_is_pie)) 398ef5ede52SUsman Nadeem opts.IsPIE = 1; 399ef5ede52SUsman Nadeem } 4001360bfb0SMark Danial 4019e6b46a9SDavid Truby // -mcmodel option. 4029e6b46a9SDavid Truby if (const llvm::opt::Arg *a = 4039e6b46a9SDavid Truby args.getLastArg(clang::driver::options::OPT_mcmodel_EQ)) { 4049e6b46a9SDavid Truby llvm::StringRef modelName = a->getValue(); 4059e6b46a9SDavid Truby std::optional<llvm::CodeModel::Model> codeModel = getCodeModel(modelName); 4069e6b46a9SDavid Truby 4079e6b46a9SDavid Truby if (codeModel.has_value()) 4089e6b46a9SDavid Truby opts.CodeModel = modelName; 4099e6b46a9SDavid Truby else 4109e6b46a9SDavid Truby diags.Report(clang::diag::err_drv_invalid_value) 4119e6b46a9SDavid Truby << a->getAsString(args) << modelName; 4129e6b46a9SDavid Truby } 4139e6b46a9SDavid Truby 4149e6b46a9SDavid Truby if (const llvm::opt::Arg *arg = args.getLastArg( 4159e6b46a9SDavid Truby clang::driver::options::OPT_mlarge_data_threshold_EQ)) { 4169e6b46a9SDavid Truby uint64_t LDT; 4179e6b46a9SDavid Truby if (llvm::StringRef(arg->getValue()).getAsInteger(/*Radix=*/10, LDT)) { 4189e6b46a9SDavid Truby diags.Report(clang::diag::err_drv_invalid_value) 4199e6b46a9SDavid Truby << arg->getSpelling() << arg->getValue(); 4209e6b46a9SDavid Truby } 4219e6b46a9SDavid Truby opts.LargeDataThreshold = LDT; 4229e6b46a9SDavid Truby } 4239e6b46a9SDavid Truby 4241360bfb0SMark Danial // This option is compatible with -f[no-]underscoring in gfortran. 4251360bfb0SMark Danial if (args.hasFlag(clang::driver::options::OPT_fno_underscoring, 4261360bfb0SMark Danial clang::driver::options::OPT_funderscoring, false)) { 4271360bfb0SMark Danial opts.Underscoring = 0; 4281360bfb0SMark Danial } 429869385b1SAndrzej Warzynski } 430869385b1SAndrzej Warzynski 4312e9439e4SAndrzej Warzynski /// Parses all target input arguments and populates the target 4322e9439e4SAndrzej Warzynski /// options accordingly. 4332e9439e4SAndrzej Warzynski /// 4342e9439e4SAndrzej Warzynski /// \param [in] opts The target options instance to update 4352e9439e4SAndrzej Warzynski /// \param [in] args The list of input arguments (from the compiler invocation) 4361e462fafSAndrzej Warzynski static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) { 43702fb5b77SAndrzej Warzynski if (const llvm::opt::Arg *a = 43802fb5b77SAndrzej Warzynski args.getLastArg(clang::driver::options::OPT_triple)) 43902fb5b77SAndrzej Warzynski opts.triple = a->getValue(); 4403951a734SUsman Nadeem 4413951a734SUsman Nadeem if (const llvm::opt::Arg *a = 4423951a734SUsman Nadeem args.getLastArg(clang::driver::options::OPT_target_cpu)) 4433951a734SUsman Nadeem opts.cpu = a->getValue(); 4443951a734SUsman Nadeem 445f1d3fe7aSAlexis Perry-Holby if (const llvm::opt::Arg *a = 446f1d3fe7aSAlexis Perry-Holby args.getLastArg(clang::driver::options::OPT_tune_cpu)) 447f1d3fe7aSAlexis Perry-Holby opts.cpuToTuneFor = a->getValue(); 448f1d3fe7aSAlexis Perry-Holby 4493951a734SUsman Nadeem for (const llvm::opt::Arg *currentArg : 4503951a734SUsman Nadeem args.filtered(clang::driver::options::OPT_target_feature)) 4513951a734SUsman Nadeem opts.featuresAsWritten.emplace_back(currentArg->getValue()); 4522e9439e4SAndrzej Warzynski 453697bc748SRenaud Kauffmann if (args.hasArg(clang::driver::options::OPT_fdisable_real_10)) 454697bc748SRenaud Kauffmann opts.disabledRealKinds.push_back(10); 455697bc748SRenaud Kauffmann 456697bc748SRenaud Kauffmann if (args.hasArg(clang::driver::options::OPT_fdisable_real_3)) 457697bc748SRenaud Kauffmann opts.disabledRealKinds.push_back(3); 458697bc748SRenaud Kauffmann 459697bc748SRenaud Kauffmann if (args.hasArg(clang::driver::options::OPT_fdisable_integer_2)) 460697bc748SRenaud Kauffmann opts.disabledIntegerKinds.push_back(2); 461697bc748SRenaud Kauffmann 462697bc748SRenaud Kauffmann if (args.hasArg(clang::driver::options::OPT_fdisable_integer_16)) 463697bc748SRenaud Kauffmann opts.disabledIntegerKinds.push_back(16); 4648e14c6c1SKelvin Li 4658e14c6c1SKelvin Li if (const llvm::opt::Arg *a = 4668e14c6c1SKelvin Li args.getLastArg(clang::driver::options::OPT_mabi_EQ)) { 4678e14c6c1SKelvin Li llvm::StringRef V = a->getValue(); 4688e14c6c1SKelvin Li if (V == "vec-extabi") { 4698e14c6c1SKelvin Li opts.EnableAIXExtendedAltivecABI = true; 4708e14c6c1SKelvin Li } else if (V == "vec-default") { 4718e14c6c1SKelvin Li opts.EnableAIXExtendedAltivecABI = false; 4728e14c6c1SKelvin Li } 4738e14c6c1SKelvin Li } 474697bc748SRenaud Kauffmann } 475523d7bc6SAndrzej Warzynski // Tweak the frontend configuration based on the frontend action 476523d7bc6SAndrzej Warzynski static void setUpFrontendBasedOnAction(FrontendOptions &opts) { 47723d4c4f3SAndrzej Warzynski if (opts.programAction == DebugDumpParsingLog) 47823d4c4f3SAndrzej Warzynski opts.instrumentedParse = true; 47985b86c6fSAndrzej Warzynski 48023d4c4f3SAndrzej Warzynski if (opts.programAction == DebugDumpProvenance || 48123d4c4f3SAndrzej Warzynski opts.programAction == Fortran::frontend::GetDefinition) 48223d4c4f3SAndrzej Warzynski opts.needProvenanceRangeToCharBlockMappings = true; 483523d7bc6SAndrzej Warzynski } 484523d7bc6SAndrzej Warzynski 4850ec3ac9bSJonathon Penix /// Parse the argument specified for the -fconvert=<value> option 4860ec3ac9bSJonathon Penix static std::optional<const char *> parseConvertArg(const char *s) { 4870ec3ac9bSJonathon Penix return llvm::StringSwitch<std::optional<const char *>>(s) 4880ec3ac9bSJonathon Penix .Case("unknown", "UNKNOWN") 4890ec3ac9bSJonathon Penix .Case("native", "NATIVE") 4900ec3ac9bSJonathon Penix .Case("little-endian", "LITTLE_ENDIAN") 4910ec3ac9bSJonathon Penix .Case("big-endian", "BIG_ENDIAN") 4920ec3ac9bSJonathon Penix .Case("swap", "SWAP") 4930ec3ac9bSJonathon Penix .Default(std::nullopt); 4940ec3ac9bSJonathon Penix } 4950ec3ac9bSJonathon Penix 4961e462fafSAndrzej Warzynski static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args, 4976d0fef48SAndrzej Warzynski clang::DiagnosticsEngine &diags) { 498dc256a44SAndrzej Warzynski unsigned numErrorsBefore = diags.getNumErrors(); 499760e6c4cSAndrzej Warzynski 500760e6c4cSAndrzej Warzynski // By default the frontend driver creates a ParseSyntaxOnly action. 50123d4c4f3SAndrzej Warzynski opts.programAction = ParseSyntaxOnly; 502760e6c4cSAndrzej Warzynski 503d18a9aeaSAndrzej Warzynski // Treat multiple action options as an invocation error. Note that `clang 504d18a9aeaSAndrzej Warzynski // -cc1` does accept multiple action options, but will only consider the 505d18a9aeaSAndrzej Warzynski // rightmost one. 506d18a9aeaSAndrzej Warzynski if (args.hasMultipleArgs(clang::driver::options::OPT_Action_Group)) { 507d18a9aeaSAndrzej Warzynski const unsigned diagID = diags.getCustomDiagID( 508d18a9aeaSAndrzej Warzynski clang::DiagnosticsEngine::Error, "Only one action option is allowed"); 509d18a9aeaSAndrzej Warzynski diags.Report(diagID); 510d18a9aeaSAndrzej Warzynski return false; 511d18a9aeaSAndrzej Warzynski } 512d18a9aeaSAndrzej Warzynski 513257b2971SCaroline Concatto // Identify the action (i.e. opts.ProgramAction) 514257b2971SCaroline Concatto if (const llvm::opt::Arg *a = 515257b2971SCaroline Concatto args.getLastArg(clang::driver::options::OPT_Action_Group)) { 516257b2971SCaroline Concatto switch (a->getOption().getID()) { 517257b2971SCaroline Concatto default: { 518257b2971SCaroline Concatto llvm_unreachable("Invalid option in group!"); 519257b2971SCaroline Concatto } 5204c5906cfSCaroline Concatto case clang::driver::options::OPT_test_io: 52123d4c4f3SAndrzej Warzynski opts.programAction = InputOutputTest; 5224c5906cfSCaroline Concatto break; 523d28de0d7SCaroline Concatto case clang::driver::options::OPT_E: 52423d4c4f3SAndrzej Warzynski opts.programAction = PrintPreprocessedInput; 525d28de0d7SCaroline Concatto break; 5267d246cb1SAndrzej Warzynski case clang::driver::options::OPT_fsyntax_only: 52723d4c4f3SAndrzej Warzynski opts.programAction = ParseSyntaxOnly; 5287d246cb1SAndrzej Warzynski break; 52939ecf9d8STom Eccles case clang::driver::options::OPT_emit_fir: 53039ecf9d8STom Eccles opts.programAction = EmitFIR; 53139ecf9d8STom Eccles break; 53239ecf9d8STom Eccles case clang::driver::options::OPT_emit_hlfir: 53339ecf9d8STom Eccles opts.programAction = EmitHLFIR; 53469c3309dSAndrzej Warzynski break; 535e993b20cSAndrzej Warzynski case clang::driver::options::OPT_emit_llvm: 536e993b20cSAndrzej Warzynski opts.programAction = EmitLLVM; 537e993b20cSAndrzej Warzynski break; 538dd56939aSAndrzej Warzynski case clang::driver::options::OPT_emit_llvm_bc: 539dd56939aSAndrzej Warzynski opts.programAction = EmitLLVMBitcode; 540dd56939aSAndrzej Warzynski break; 541e5cdb6c5SAndrzej Warzynski case clang::driver::options::OPT_emit_obj: 54223d4c4f3SAndrzej Warzynski opts.programAction = EmitObj; 543e5cdb6c5SAndrzej Warzynski break; 54438101b4eSAndrzej Warzynski case clang::driver::options::OPT_S: 54538101b4eSAndrzej Warzynski opts.programAction = EmitAssembly; 54638101b4eSAndrzej Warzynski break; 54796d229c9SAndrzej Warzynski case clang::driver::options::OPT_fdebug_unparse: 54823d4c4f3SAndrzej Warzynski opts.programAction = DebugUnparse; 54996d229c9SAndrzej Warzynski break; 550e81b3401SAndrzej Warzynski case clang::driver::options::OPT_fdebug_unparse_no_sema: 55123d4c4f3SAndrzej Warzynski opts.programAction = DebugUnparseNoSema; 552e81b3401SAndrzej Warzynski break; 55396d229c9SAndrzej Warzynski case clang::driver::options::OPT_fdebug_unparse_with_symbols: 55423d4c4f3SAndrzej Warzynski opts.programAction = DebugUnparseWithSymbols; 55596d229c9SAndrzej Warzynski break; 556e00a3ccfSPeter Klausler case clang::driver::options::OPT_fdebug_unparse_with_modules: 557e00a3ccfSPeter Klausler opts.programAction = DebugUnparseWithModules; 558e00a3ccfSPeter Klausler break; 5594bd08dabSFaris Rehman case clang::driver::options::OPT_fdebug_dump_symbols: 56023d4c4f3SAndrzej Warzynski opts.programAction = DebugDumpSymbols; 5614bd08dabSFaris Rehman break; 5624bd08dabSFaris Rehman case clang::driver::options::OPT_fdebug_dump_parse_tree: 56323d4c4f3SAndrzej Warzynski opts.programAction = DebugDumpParseTree; 5644bd08dabSFaris Rehman break; 5658321579bSAndrzej Warzynski case clang::driver::options::OPT_fdebug_dump_pft: 5668321579bSAndrzej Warzynski opts.programAction = DebugDumpPFT; 5678321579bSAndrzej Warzynski break; 568a6be6e31SAndrzej Warzynski case clang::driver::options::OPT_fdebug_dump_all: 56923d4c4f3SAndrzej Warzynski opts.programAction = DebugDumpAll; 570a6be6e31SAndrzej Warzynski break; 571e81b3401SAndrzej Warzynski case clang::driver::options::OPT_fdebug_dump_parse_tree_no_sema: 57223d4c4f3SAndrzej Warzynski opts.programAction = DebugDumpParseTreeNoSema; 573e81b3401SAndrzej Warzynski break; 5744bd08dabSFaris Rehman case clang::driver::options::OPT_fdebug_dump_provenance: 57523d4c4f3SAndrzej Warzynski opts.programAction = DebugDumpProvenance; 5764bd08dabSFaris Rehman break; 577523d7bc6SAndrzej Warzynski case clang::driver::options::OPT_fdebug_dump_parsing_log: 57823d4c4f3SAndrzej Warzynski opts.programAction = DebugDumpParsingLog; 579523d7bc6SAndrzej Warzynski break; 580529f7181SFaris Rehman case clang::driver::options::OPT_fdebug_measure_parse_tree: 58123d4c4f3SAndrzej Warzynski opts.programAction = DebugMeasureParseTree; 582529f7181SFaris Rehman break; 583529f7181SFaris Rehman case clang::driver::options::OPT_fdebug_pre_fir_tree: 58423d4c4f3SAndrzej Warzynski opts.programAction = DebugPreFIRTree; 585529f7181SFaris Rehman break; 586eefda605SAndrzej Warzynski case clang::driver::options::OPT_fget_symbols_sources: 58723d4c4f3SAndrzej Warzynski opts.programAction = GetSymbolsSources; 588eefda605SAndrzej Warzynski break; 589dc256a44SAndrzej Warzynski case clang::driver::options::OPT_fget_definition: 59023d4c4f3SAndrzej Warzynski opts.programAction = GetDefinition; 591dc256a44SAndrzej Warzynski break; 592e1da3297SStuart Ellis case clang::driver::options::OPT_init_only: 59323d4c4f3SAndrzej Warzynski opts.programAction = InitOnly; 594e1da3297SStuart Ellis break; 595d28de0d7SCaroline Concatto 596257b2971SCaroline Concatto // TODO: 597e1da3297SStuart Ellis // case clang::driver::options::OPT_emit_llvm: 598257b2971SCaroline Concatto // case clang::driver::options::OPT_emit_llvm_only: 599257b2971SCaroline Concatto // case clang::driver::options::OPT_emit_codegen_only: 600257b2971SCaroline Concatto // case clang::driver::options::OPT_emit_module: 601257b2971SCaroline Concatto // (...) 602257b2971SCaroline Concatto } 603dc256a44SAndrzej Warzynski 604dc256a44SAndrzej Warzynski // Parse the values provided with `-fget-definition` (there should be 3 605dc256a44SAndrzej Warzynski // integers) 606dc256a44SAndrzej Warzynski if (llvm::opt::OptSpecifier(a->getOption().getID()) == 607dc256a44SAndrzej Warzynski clang::driver::options::OPT_fget_definition) { 608dc256a44SAndrzej Warzynski unsigned optVals[3] = {0, 0, 0}; 609dc256a44SAndrzej Warzynski 610dc256a44SAndrzej Warzynski for (unsigned i = 0; i < 3; i++) { 611dc256a44SAndrzej Warzynski llvm::StringRef val = a->getValue(i); 612dc256a44SAndrzej Warzynski 613dc256a44SAndrzej Warzynski if (val.getAsInteger(10, optVals[i])) { 614dc256a44SAndrzej Warzynski // A non-integer was encountered - that's an error. 615dc256a44SAndrzej Warzynski diags.Report(clang::diag::err_drv_invalid_value) 616dc256a44SAndrzej Warzynski << a->getOption().getName() << val; 617dc256a44SAndrzej Warzynski break; 618dc256a44SAndrzej Warzynski } 619dc256a44SAndrzej Warzynski } 62023d4c4f3SAndrzej Warzynski opts.getDefVals.line = optVals[0]; 62123d4c4f3SAndrzej Warzynski opts.getDefVals.startColumn = optVals[1]; 62223d4c4f3SAndrzej Warzynski opts.getDefVals.endColumn = optVals[2]; 623dc256a44SAndrzej Warzynski } 624257b2971SCaroline Concatto } 625257b2971SCaroline Concatto 626f52fc591SStuart Ellis // Parsing -load <dsopath> option and storing shared object path 627f52fc591SStuart Ellis if (llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_load)) { 628f52fc591SStuart Ellis opts.plugins.push_back(a->getValue()); 629f52fc591SStuart Ellis } 630f52fc591SStuart Ellis 631f52fc591SStuart Ellis // Parsing -plugin <name> option and storing plugin name and setting action 632f52fc591SStuart Ellis if (const llvm::opt::Arg *a = 633f52fc591SStuart Ellis args.getLastArg(clang::driver::options::OPT_plugin)) { 634f52fc591SStuart Ellis opts.programAction = PluginAction; 6351e462fafSAndrzej Warzynski opts.actionName = a->getValue(); 636f52fc591SStuart Ellis } 637f52fc591SStuart Ellis 63823d4c4f3SAndrzej Warzynski opts.outputFile = args.getLastArgValue(clang::driver::options::OPT_o); 63923d4c4f3SAndrzej Warzynski opts.showHelp = args.hasArg(clang::driver::options::OPT_help); 64023d4c4f3SAndrzej Warzynski opts.showVersion = args.hasArg(clang::driver::options::OPT_version); 64123d7a6ceSTarun Prabhu opts.printSupportedCPUs = 64223d7a6ceSTarun Prabhu args.hasArg(clang::driver::options::OPT_print_supported_cpus); 643257b2971SCaroline Concatto 644257b2971SCaroline Concatto // Get the input kind (from the value passed via `-x`) 645257b2971SCaroline Concatto InputKind dashX(Language::Unknown); 646257b2971SCaroline Concatto if (const llvm::opt::Arg *a = 647257b2971SCaroline Concatto args.getLastArg(clang::driver::options::OPT_x)) { 6481e462fafSAndrzej Warzynski llvm::StringRef xValue = a->getValue(); 649257b2971SCaroline Concatto // Principal languages. 6501e462fafSAndrzej Warzynski dashX = llvm::StringSwitch<InputKind>(xValue) 6513e782ba2SAndrzej Warzynski // Flang does not differentiate between pre-processed and not 6523e782ba2SAndrzej Warzynski // pre-processed inputs. 6533e782ba2SAndrzej Warzynski .Case("f95", Language::Fortran) 6543e782ba2SAndrzej Warzynski .Case("f95-cpp-input", Language::Fortran) 6558a8ef1caSValentin Clement (バレンタイン クレメン) // CUDA Fortran 6568a8ef1caSValentin Clement (バレンタイン クレメン) .Case("cuda", Language::Fortran) 657257b2971SCaroline Concatto .Default(Language::Unknown); 658257b2971SCaroline Concatto 659cc3c6b61SAndrzej Warzynski // Flang's intermediate representations. 6601e462fafSAndrzej Warzynski if (dashX.isUnknown()) 6611e462fafSAndrzej Warzynski dashX = llvm::StringSwitch<InputKind>(xValue) 662257b2971SCaroline Concatto .Case("ir", Language::LLVM_IR) 663cc3c6b61SAndrzej Warzynski .Case("fir", Language::MLIR) 664cc3c6b61SAndrzej Warzynski .Case("mlir", Language::MLIR) 665257b2971SCaroline Concatto .Default(Language::Unknown); 666257b2971SCaroline Concatto 6671e462fafSAndrzej Warzynski if (dashX.isUnknown()) 668257b2971SCaroline Concatto diags.Report(clang::diag::err_drv_invalid_value) 669257b2971SCaroline Concatto << a->getAsString(args) << a->getValue(); 670257b2971SCaroline Concatto } 671257b2971SCaroline Concatto 6724c5906cfSCaroline Concatto // Collect the input files and save them in our instance of FrontendOptions. 6734c5906cfSCaroline Concatto std::vector<std::string> inputs = 6744c5906cfSCaroline Concatto args.getAllArgValues(clang::driver::options::OPT_INPUT); 67523d4c4f3SAndrzej Warzynski opts.inputs.clear(); 6764c5906cfSCaroline Concatto if (inputs.empty()) 6774c5906cfSCaroline Concatto // '-' is the default input if none is given. 6784c5906cfSCaroline Concatto inputs.push_back("-"); 6794c5906cfSCaroline Concatto for (unsigned i = 0, e = inputs.size(); i != e; ++i) { 6804c5906cfSCaroline Concatto InputKind ik = dashX; 6811e462fafSAndrzej Warzynski if (ik.isUnknown()) { 6821e462fafSAndrzej Warzynski ik = FrontendOptions::getInputKindForExtension( 6834c5906cfSCaroline Concatto llvm::StringRef(inputs[i]).rsplit('.').second); 6841e462fafSAndrzej Warzynski if (ik.isUnknown()) 6854c5906cfSCaroline Concatto ik = Language::Unknown; 6864c5906cfSCaroline Concatto if (i == 0) 6874c5906cfSCaroline Concatto dashX = ik; 6884c5906cfSCaroline Concatto } 6894c5906cfSCaroline Concatto 69023d4c4f3SAndrzej Warzynski opts.inputs.emplace_back(std::move(inputs[i]), ik); 6914c5906cfSCaroline Concatto } 6923a1513c1SFaris Rehman 69323d4c4f3SAndrzej Warzynski // Set fortranForm based on options -ffree-form and -ffixed-form. 69474d5c3c0SPeter Steinfeld if (const auto *arg = 69574d5c3c0SPeter Steinfeld args.getLastArg(clang::driver::options::OPT_ffixed_form, 6963a1513c1SFaris Rehman clang::driver::options::OPT_ffree_form)) { 69723d4c4f3SAndrzej Warzynski opts.fortranForm = 6983a1513c1SFaris Rehman arg->getOption().matches(clang::driver::options::OPT_ffixed_form) 6993a1513c1SFaris Rehman ? FortranForm::FixedForm 7003a1513c1SFaris Rehman : FortranForm::FreeForm; 7013a1513c1SFaris Rehman } 7023a1513c1SFaris Rehman 70323d4c4f3SAndrzej Warzynski // Set fixedFormColumns based on -ffixed-line-length=<value> 7043a1513c1SFaris Rehman if (const auto *arg = 7053a1513c1SFaris Rehman args.getLastArg(clang::driver::options::OPT_ffixed_line_length_EQ)) { 7063a1513c1SFaris Rehman llvm::StringRef argValue = llvm::StringRef(arg->getValue()); 7073a1513c1SFaris Rehman std::int64_t columns = -1; 7083a1513c1SFaris Rehman if (argValue == "none") { 7093a1513c1SFaris Rehman columns = 0; 7103a1513c1SFaris Rehman } else if (argValue.getAsInteger(/*Radix=*/10, columns)) { 7113a1513c1SFaris Rehman columns = -1; 7123a1513c1SFaris Rehman } 7133a1513c1SFaris Rehman if (columns < 0) { 714aefbfbcbSNick Desaulniers diags.Report(clang::diag::err_drv_negative_columns) 715aefbfbcbSNick Desaulniers << arg->getOption().getName() << arg->getValue(); 7163a1513c1SFaris Rehman } else if (columns == 0) { 71723d4c4f3SAndrzej Warzynski opts.fixedFormColumns = 1000000; 7183a1513c1SFaris Rehman } else if (columns < 7) { 719aefbfbcbSNick Desaulniers diags.Report(clang::diag::err_drv_small_columns) 720aefbfbcbSNick Desaulniers << arg->getOption().getName() << arg->getValue() << "7"; 7213a1513c1SFaris Rehman } else { 72223d4c4f3SAndrzej Warzynski opts.fixedFormColumns = columns; 7233a1513c1SFaris Rehman } 7243a1513c1SFaris Rehman } 7256d48a1a5SFaris Rehman 7260ec3ac9bSJonathon Penix // Set conversion based on -fconvert=<value> 7270ec3ac9bSJonathon Penix if (const auto *arg = 7280ec3ac9bSJonathon Penix args.getLastArg(clang::driver::options::OPT_fconvert_EQ)) { 7290ec3ac9bSJonathon Penix const char *argValue = arg->getValue(); 7300ec3ac9bSJonathon Penix if (auto convert = parseConvertArg(argValue)) 7310ec3ac9bSJonathon Penix opts.envDefaults.push_back({"FORT_CONVERT", *convert}); 7320ec3ac9bSJonathon Penix else 7330ec3ac9bSJonathon Penix diags.Report(clang::diag::err_drv_invalid_value) 7340ec3ac9bSJonathon Penix << arg->getAsString(args) << argValue; 7350ec3ac9bSJonathon Penix } 7360ec3ac9bSJonathon Penix 73755a96155SAndrzej Warzynski // -f{no-}implicit-none 73823d4c4f3SAndrzej Warzynski opts.features.Enable( 73910826ea7SFaris Rehman Fortran::common::LanguageFeature::ImplicitNoneTypeAlways, 74055a96155SAndrzej Warzynski args.hasFlag(clang::driver::options::OPT_fimplicit_none, 74155a96155SAndrzej Warzynski clang::driver::options::OPT_fno_implicit_none, false)); 74255a96155SAndrzej Warzynski 74355a96155SAndrzej Warzynski // -f{no-}backslash 74423d4c4f3SAndrzej Warzynski opts.features.Enable(Fortran::common::LanguageFeature::BackslashEscapes, 74555a96155SAndrzej Warzynski args.hasFlag(clang::driver::options::OPT_fbackslash, 74674d5c3c0SPeter Steinfeld clang::driver::options::OPT_fno_backslash, 74774d5c3c0SPeter Steinfeld false)); 74855a96155SAndrzej Warzynski 74955a96155SAndrzej Warzynski // -f{no-}logical-abbreviations 75074d5c3c0SPeter Steinfeld opts.features.Enable( 75174d5c3c0SPeter Steinfeld Fortran::common::LanguageFeature::LogicalAbbreviations, 75255a96155SAndrzej Warzynski args.hasFlag(clang::driver::options::OPT_flogical_abbreviations, 75374d5c3c0SPeter Steinfeld clang::driver::options::OPT_fno_logical_abbreviations, 75474d5c3c0SPeter Steinfeld false)); 75555a96155SAndrzej Warzynski 756fc97d2e6SPeter Klausler // -f{no-}unsigned 757fc97d2e6SPeter Klausler opts.features.Enable(Fortran::common::LanguageFeature::Unsigned, 758fc97d2e6SPeter Klausler args.hasFlag(clang::driver::options::OPT_funsigned, 759fc97d2e6SPeter Klausler clang::driver::options::OPT_fno_unsigned, 760fc97d2e6SPeter Klausler false)); 761fc97d2e6SPeter Klausler 76255a96155SAndrzej Warzynski // -f{no-}xor-operator 76374d5c3c0SPeter Steinfeld opts.features.Enable( 76474d5c3c0SPeter Steinfeld Fortran::common::LanguageFeature::XOROperator, 76555a96155SAndrzej Warzynski args.hasFlag(clang::driver::options::OPT_fxor_operator, 76655a96155SAndrzej Warzynski clang::driver::options::OPT_fno_xor_operator, false)); 76755a96155SAndrzej Warzynski 768996ef895SPeter Klausler // -fno-automatic 769996ef895SPeter Klausler if (args.hasArg(clang::driver::options::OPT_fno_automatic)) { 770996ef895SPeter Klausler opts.features.Enable(Fortran::common::LanguageFeature::DefaultSave); 771996ef895SPeter Klausler } 772996ef895SPeter Klausler 773*7211bf48SjeanPerier // -f{no}-save-main-program 774*7211bf48SjeanPerier opts.features.Enable( 775*7211bf48SjeanPerier Fortran::common::LanguageFeature::SaveMainProgram, 776*7211bf48SjeanPerier args.hasFlag(clang::driver::options::OPT_fsave_main_program, 777*7211bf48SjeanPerier clang::driver::options::OPT_fno_save_main_program, false)); 778645c1ee8SjeanPerier 77910826ea7SFaris Rehman if (args.hasArg( 78010826ea7SFaris Rehman clang::driver::options::OPT_falternative_parameter_statement)) { 78123d4c4f3SAndrzej Warzynski opts.features.Enable(Fortran::common::LanguageFeature::OldStyleParameter); 78210826ea7SFaris Rehman } 78310826ea7SFaris Rehman if (const llvm::opt::Arg *arg = 78410826ea7SFaris Rehman args.getLastArg(clang::driver::options::OPT_finput_charset_EQ)) { 78510826ea7SFaris Rehman llvm::StringRef argValue = arg->getValue(); 78610826ea7SFaris Rehman if (argValue == "utf-8") { 78723d4c4f3SAndrzej Warzynski opts.encoding = Fortran::parser::Encoding::UTF_8; 78810826ea7SFaris Rehman } else if (argValue == "latin-1") { 78923d4c4f3SAndrzej Warzynski opts.encoding = Fortran::parser::Encoding::LATIN_1; 79010826ea7SFaris Rehman } else { 79110826ea7SFaris Rehman diags.Report(clang::diag::err_drv_invalid_value) 79210826ea7SFaris Rehman << arg->getAsString(args) << argValue; 79310826ea7SFaris Rehman } 79410826ea7SFaris Rehman } 795523d7bc6SAndrzej Warzynski 796523d7bc6SAndrzej Warzynski setUpFrontendBasedOnAction(opts); 79723d4c4f3SAndrzej Warzynski opts.dashX = dashX; 798dc256a44SAndrzej Warzynski 799dc256a44SAndrzej Warzynski return diags.getNumErrors() == numErrorsBefore; 800257b2971SCaroline Concatto } 801257b2971SCaroline Concatto 802cd4abc52SArnamoy Bhattacharyya // Generate the path to look for intrinsic modules 8038dc474c6Smadanial0 static std::string getIntrinsicDir(const char *argv) { 804cd4abc52SArnamoy Bhattacharyya // TODO: Find a system independent API 805cd4abc52SArnamoy Bhattacharyya llvm::SmallString<128> driverPath; 8068dc474c6Smadanial0 driverPath.assign(llvm::sys::fs::getMainExecutable(argv, nullptr)); 807cd4abc52SArnamoy Bhattacharyya llvm::sys::path::remove_filename(driverPath); 808cd4abc52SArnamoy Bhattacharyya driverPath.append("/../include/flang/"); 809cd4abc52SArnamoy Bhattacharyya return std::string(driverPath); 810cd4abc52SArnamoy Bhattacharyya } 811cd4abc52SArnamoy Bhattacharyya 812dda366edSAndrzej Warzynski // Generate the path to look for OpenMP headers 8138dc474c6Smadanial0 static std::string getOpenMPHeadersDir(const char *argv) { 814dda366edSAndrzej Warzynski llvm::SmallString<128> includePath; 8158dc474c6Smadanial0 includePath.assign(llvm::sys::fs::getMainExecutable(argv, nullptr)); 816dda366edSAndrzej Warzynski llvm::sys::path::remove_filename(includePath); 817dda366edSAndrzej Warzynski includePath.append("/../include/flang/OpenMP/"); 818dda366edSAndrzej Warzynski return std::string(includePath); 819dda366edSAndrzej Warzynski } 820dda366edSAndrzej Warzynski 8217809fa20SFaris Rehman /// Parses all preprocessor input arguments and populates the preprocessor 8227809fa20SFaris Rehman /// options accordingly. 8237809fa20SFaris Rehman /// 8247809fa20SFaris Rehman /// \param [in] opts The preprocessor options instance 8257809fa20SFaris Rehman /// \param [out] args The list of input arguments 82674d5c3c0SPeter Steinfeld static void parsePreprocessorArgs(Fortran::frontend::PreprocessorOptions &opts, 82774d5c3c0SPeter Steinfeld llvm::opt::ArgList &args) { 8287809fa20SFaris Rehman // Add macros from the command line. 82974d5c3c0SPeter Steinfeld for (const auto *currentArg : args.filtered(clang::driver::options::OPT_D, 83074d5c3c0SPeter Steinfeld clang::driver::options::OPT_U)) { 8317809fa20SFaris Rehman if (currentArg->getOption().matches(clang::driver::options::OPT_D)) { 8327809fa20SFaris Rehman opts.addMacroDef(currentArg->getValue()); 8337809fa20SFaris Rehman } else { 8347809fa20SFaris Rehman opts.addMacroUndef(currentArg->getValue()); 8357809fa20SFaris Rehman } 8367809fa20SFaris Rehman } 83787dfd5e0SFaris Rehman 83887dfd5e0SFaris Rehman // Add the ordered list of -I's. 83987dfd5e0SFaris Rehman for (const auto *currentArg : args.filtered(clang::driver::options::OPT_I)) 84087dfd5e0SFaris Rehman opts.searchDirectoriesFromDashI.emplace_back(currentArg->getValue()); 841cd4abc52SArnamoy Bhattacharyya 842cd4abc52SArnamoy Bhattacharyya // Prepend the ordered list of -intrinsic-modules-path 843cd4abc52SArnamoy Bhattacharyya // to the default location to search. 844cd4abc52SArnamoy Bhattacharyya for (const auto *currentArg : 845cd4abc52SArnamoy Bhattacharyya args.filtered(clang::driver::options::OPT_fintrinsic_modules_path)) 846cd4abc52SArnamoy Bhattacharyya opts.searchDirectoriesFromIntrModPath.emplace_back(currentArg->getValue()); 847b83a4450SAndrzej Warzynski 848b83a4450SAndrzej Warzynski // -cpp/-nocpp 849b83a4450SAndrzej Warzynski if (const auto *currentArg = args.getLastArg( 850b83a4450SAndrzej Warzynski clang::driver::options::OPT_cpp, clang::driver::options::OPT_nocpp)) 85123d4c4f3SAndrzej Warzynski opts.macrosFlag = 852b83a4450SAndrzej Warzynski (currentArg->getOption().matches(clang::driver::options::OPT_cpp)) 853b83a4450SAndrzej Warzynski ? PPMacrosFlag::Include 854b83a4450SAndrzej Warzynski : PPMacrosFlag::Exclude; 8553338ef93Speter klausler 8563338ef93Speter klausler opts.noReformat = args.hasArg(clang::driver::options::OPT_fno_reformat); 8574dfed691SPeter Klausler opts.preprocessIncludeLines = 8584dfed691SPeter Klausler args.hasArg(clang::driver::options::OPT_fpreprocess_include_lines); 8593338ef93Speter klausler opts.noLineDirectives = args.hasArg(clang::driver::options::OPT_P); 8607d60232bSKrzysztof Parzyszek opts.showMacros = args.hasArg(clang::driver::options::OPT_dM); 8617809fa20SFaris Rehman } 8627809fa20SFaris Rehman 863985a42fdSArnamoy Bhattacharyya /// Parses all semantic related arguments and populates the variables 8646d0fef48SAndrzej Warzynski /// options accordingly. Returns false if new errors are generated. 8656d0fef48SAndrzej Warzynski static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args, 866985a42fdSArnamoy Bhattacharyya clang::DiagnosticsEngine &diags) { 8676d0fef48SAndrzej Warzynski unsigned numErrorsBefore = diags.getNumErrors(); 868985a42fdSArnamoy Bhattacharyya 8691fd4beecSArnamoy Bhattacharyya // -J/module-dir option 87084a0a3d3SPaul Osmialowski std::vector<std::string> moduleDirList = 871985a42fdSArnamoy Bhattacharyya args.getAllArgValues(clang::driver::options::OPT_module_dir); 87284a0a3d3SPaul Osmialowski // User can only specify one -J/-module-dir directory, but may repeat 87384a0a3d3SPaul Osmialowski // -J/-module-dir as long as the directory is the same each time. 874985a42fdSArnamoy Bhattacharyya // https://gcc.gnu.org/onlinedocs/gfortran/Directory-Options.html 87584a0a3d3SPaul Osmialowski std::sort(moduleDirList.begin(), moduleDirList.end()); 87684a0a3d3SPaul Osmialowski moduleDirList.erase(std::unique(moduleDirList.begin(), moduleDirList.end()), 87784a0a3d3SPaul Osmialowski moduleDirList.end()); 878985a42fdSArnamoy Bhattacharyya if (moduleDirList.size() > 1) { 879985a42fdSArnamoy Bhattacharyya const unsigned diagID = 880985a42fdSArnamoy Bhattacharyya diags.getCustomDiagID(clang::DiagnosticsEngine::Error, 88184a0a3d3SPaul Osmialowski "Only one '-module-dir/-J' directory allowed. " 88284a0a3d3SPaul Osmialowski "'-module-dir/-J' may be given multiple times " 88384a0a3d3SPaul Osmialowski "but the directory must be the same each time."); 884985a42fdSArnamoy Bhattacharyya diags.Report(diagID); 885985a42fdSArnamoy Bhattacharyya } 886985a42fdSArnamoy Bhattacharyya if (moduleDirList.size() == 1) 8871e462fafSAndrzej Warzynski res.setModuleDir(moduleDirList[0]); 8881fd4beecSArnamoy Bhattacharyya 8891fd4beecSArnamoy Bhattacharyya // -fdebug-module-writer option 8901fd4beecSArnamoy Bhattacharyya if (args.hasArg(clang::driver::options::OPT_fdebug_module_writer)) { 8911e462fafSAndrzej Warzynski res.setDebugModuleDir(true); 8921fd4beecSArnamoy Bhattacharyya } 8936d0fef48SAndrzej Warzynski 89465987954SPeter Klausler // -fhermetic-module-files option 89565987954SPeter Klausler if (args.hasArg(clang::driver::options::OPT_fhermetic_module_files)) { 89665987954SPeter Klausler res.setHermeticModuleFileOutput(true); 89765987954SPeter Klausler } 89865987954SPeter Klausler 89920bd2142SAndrzej Warzynski // -module-suffix 90020bd2142SAndrzej Warzynski if (const auto *moduleSuffix = 90120bd2142SAndrzej Warzynski args.getLastArg(clang::driver::options::OPT_module_suffix)) { 9021e462fafSAndrzej Warzynski res.setModuleFileSuffix(moduleSuffix->getValue()); 90320bd2142SAndrzej Warzynski } 90420bd2142SAndrzej Warzynski 90555a96155SAndrzej Warzynski // -f{no-}analyzed-objects-for-unparse 9061e462fafSAndrzej Warzynski res.setUseAnalyzedObjectsForUnparse(args.hasFlag( 9071e462fafSAndrzej Warzynski clang::driver::options::OPT_fanalyzed_objects_for_unparse, 90855a96155SAndrzej Warzynski clang::driver::options::OPT_fno_analyzed_objects_for_unparse, true)); 9092a7bb849SAndrzej Warzynski 9106d0fef48SAndrzej Warzynski return diags.getNumErrors() == numErrorsBefore; 911985a42fdSArnamoy Bhattacharyya } 912985a42fdSArnamoy Bhattacharyya 9137416e8a8SArnamoy Bhattacharyya /// Parses all diagnostics related arguments and populates the variables 9146d0fef48SAndrzej Warzynski /// options accordingly. Returns false if new errors are generated. 9156d0fef48SAndrzej Warzynski static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args, 9167416e8a8SArnamoy Bhattacharyya clang::DiagnosticsEngine &diags) { 9176d0fef48SAndrzej Warzynski unsigned numErrorsBefore = diags.getNumErrors(); 9186d0fef48SAndrzej Warzynski 9197416e8a8SArnamoy Bhattacharyya // -Werror option 9207416e8a8SArnamoy Bhattacharyya // TODO: Currently throws a Diagnostic for anything other than -W<error>, 9217416e8a8SArnamoy Bhattacharyya // this has to change when other -W<opt>'s are supported. 9227416e8a8SArnamoy Bhattacharyya if (args.hasArg(clang::driver::options::OPT_W_Joined)) { 923ce3a1c59SEthan Luis McDonough const auto &wArgs = 924ce3a1c59SEthan Luis McDonough args.getAllArgValues(clang::driver::options::OPT_W_Joined); 925ce3a1c59SEthan Luis McDonough for (const auto &wArg : wArgs) { 926ce3a1c59SEthan Luis McDonough if (wArg == "error") { 9271e462fafSAndrzej Warzynski res.setWarnAsErr(true); 9287416e8a8SArnamoy Bhattacharyya } else { 9297416e8a8SArnamoy Bhattacharyya const unsigned diagID = 9307416e8a8SArnamoy Bhattacharyya diags.getCustomDiagID(clang::DiagnosticsEngine::Error, 9317416e8a8SArnamoy Bhattacharyya "Only `-Werror` is supported currently."); 9327416e8a8SArnamoy Bhattacharyya diags.Report(diagID); 9337416e8a8SArnamoy Bhattacharyya } 9347416e8a8SArnamoy Bhattacharyya } 935ce3a1c59SEthan Luis McDonough } 9366d0fef48SAndrzej Warzynski 93706eb10daSBrad Richardson // Default to off for `flang -fc1`. 93843084160SPeixin Qiao res.getFrontendOpts().showColors = 93943084160SPeixin Qiao parseShowColorsArgs(args, /*defaultDiagColor=*/false); 94043084160SPeixin Qiao 9418e315c6cSVictor Kingi // Honor color diagnostics. 9428e315c6cSVictor Kingi res.getDiagnosticOpts().ShowColors = res.getFrontendOpts().showColors; 9438e315c6cSVictor Kingi 9446d0fef48SAndrzej Warzynski return diags.getNumErrors() == numErrorsBefore; 9457416e8a8SArnamoy Bhattacharyya } 9467416e8a8SArnamoy Bhattacharyya 947ab971c29SArnamoy Bhattacharyya /// Parses all Dialect related arguments and populates the variables 9486d0fef48SAndrzej Warzynski /// options accordingly. Returns false if new errors are generated. 9496d0fef48SAndrzej Warzynski static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args, 950ab971c29SArnamoy Bhattacharyya clang::DiagnosticsEngine &diags) { 9516d0fef48SAndrzej Warzynski unsigned numErrorsBefore = diags.getNumErrors(); 952ab971c29SArnamoy Bhattacharyya 953ab971c29SArnamoy Bhattacharyya // -fdefault* family 954ab971c29SArnamoy Bhattacharyya if (args.hasArg(clang::driver::options::OPT_fdefault_real_8)) { 9551e462fafSAndrzej Warzynski res.getDefaultKinds().set_defaultRealKind(8); 9561e462fafSAndrzej Warzynski res.getDefaultKinds().set_doublePrecisionKind(16); 957ab971c29SArnamoy Bhattacharyya } 958ab971c29SArnamoy Bhattacharyya if (args.hasArg(clang::driver::options::OPT_fdefault_integer_8)) { 9591e462fafSAndrzej Warzynski res.getDefaultKinds().set_defaultIntegerKind(8); 9601e462fafSAndrzej Warzynski res.getDefaultKinds().set_subscriptIntegerKind(8); 9611e462fafSAndrzej Warzynski res.getDefaultKinds().set_sizeIntegerKind(8); 962fc43c4f0SKiran Chandramohan res.getDefaultKinds().set_defaultLogicalKind(8); 963ab971c29SArnamoy Bhattacharyya } 964ab971c29SArnamoy Bhattacharyya if (args.hasArg(clang::driver::options::OPT_fdefault_double_8)) { 965ab971c29SArnamoy Bhattacharyya if (!args.hasArg(clang::driver::options::OPT_fdefault_real_8)) { 966ab971c29SArnamoy Bhattacharyya // -fdefault-double-8 has to be used with -fdefault-real-8 967ab971c29SArnamoy Bhattacharyya // to be compatible with gfortran 96874d5c3c0SPeter Steinfeld const unsigned diagID = diags.getCustomDiagID( 96974d5c3c0SPeter Steinfeld clang::DiagnosticsEngine::Error, 970ab971c29SArnamoy Bhattacharyya "Use of `-fdefault-double-8` requires `-fdefault-real-8`"); 971ab971c29SArnamoy Bhattacharyya diags.Report(diagID); 972ab971c29SArnamoy Bhattacharyya } 973ab971c29SArnamoy Bhattacharyya // https://gcc.gnu.org/onlinedocs/gfortran/Fortran-Dialect-Options.html 9741e462fafSAndrzej Warzynski res.getDefaultKinds().set_doublePrecisionKind(8); 975ab971c29SArnamoy Bhattacharyya } 976ab971c29SArnamoy Bhattacharyya if (args.hasArg(clang::driver::options::OPT_flarge_sizes)) 9771e462fafSAndrzej Warzynski res.getDefaultKinds().set_sizeIntegerKind(8); 978ab971c29SArnamoy Bhattacharyya 9798a8ef1caSValentin Clement (バレンタイン クレメン) // -x cuda 9808a8ef1caSValentin Clement (バレンタイン クレメン) auto language = args.getLastArgValue(clang::driver::options::OPT_x); 981f841ca0cSKazu Hirata if (language == "cuda") { 9828a8ef1caSValentin Clement (バレンタイン クレメン) res.getFrontendOpts().features.Enable( 9838a8ef1caSValentin Clement (バレンタイン クレメン) Fortran::common::LanguageFeature::CUDA); 9848a8ef1caSValentin Clement (バレンタイン クレメン) } 9858a8ef1caSValentin Clement (バレンタイン クレメン) 9869dadb1f6SSergio Afonso // -fopenacc 987ab971c29SArnamoy Bhattacharyya if (args.hasArg(clang::driver::options::OPT_fopenacc)) { 9881e462fafSAndrzej Warzynski res.getFrontendOpts().features.Enable( 989ab971c29SArnamoy Bhattacharyya Fortran::common::LanguageFeature::OpenACC); 990ab971c29SArnamoy Bhattacharyya } 9919dadb1f6SSergio Afonso 9929dadb1f6SSergio Afonso // -pedantic 9939dadb1f6SSergio Afonso if (args.hasArg(clang::driver::options::OPT_pedantic)) { 9949dadb1f6SSergio Afonso res.setEnableConformanceChecks(); 9959dadb1f6SSergio Afonso res.setEnableUsageChecks(); 9969dadb1f6SSergio Afonso } 9979dadb1f6SSergio Afonso 9989dadb1f6SSergio Afonso // -w 9999dadb1f6SSergio Afonso if (args.hasArg(clang::driver::options::OPT_w)) 10009dadb1f6SSergio Afonso res.setDisableWarnings(); 10019dadb1f6SSergio Afonso 10029dadb1f6SSergio Afonso // -std=f2018 10039dadb1f6SSergio Afonso // TODO: Set proper options when more fortran standards 10049dadb1f6SSergio Afonso // are supported. 10059dadb1f6SSergio Afonso if (args.hasArg(clang::driver::options::OPT_std_EQ)) { 10069dadb1f6SSergio Afonso auto standard = args.getLastArgValue(clang::driver::options::OPT_std_EQ); 10079dadb1f6SSergio Afonso // We only allow f2018 as the given standard 10089dadb1f6SSergio Afonso if (standard == "f2018") { 10099dadb1f6SSergio Afonso res.setEnableConformanceChecks(); 10109dadb1f6SSergio Afonso } else { 10119dadb1f6SSergio Afonso const unsigned diagID = 10129dadb1f6SSergio Afonso diags.getCustomDiagID(clang::DiagnosticsEngine::Error, 10139dadb1f6SSergio Afonso "Only -std=f2018 is allowed currently."); 10149dadb1f6SSergio Afonso diags.Report(diagID); 10159dadb1f6SSergio Afonso } 10169dadb1f6SSergio Afonso } 10179dadb1f6SSergio Afonso return diags.getNumErrors() == numErrorsBefore; 10189dadb1f6SSergio Afonso } 10199dadb1f6SSergio Afonso 10209dadb1f6SSergio Afonso /// Parses all OpenMP related arguments if the -fopenmp option is present, 10219dadb1f6SSergio Afonso /// populating the \c res object accordingly. Returns false if new errors are 10229dadb1f6SSergio Afonso /// generated. 10239dadb1f6SSergio Afonso static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args, 10249dadb1f6SSergio Afonso clang::DiagnosticsEngine &diags) { 10254f130fa9STom Eccles llvm::opt::Arg *arg = args.getLastArg(clang::driver::options::OPT_fopenmp, 10264f130fa9STom Eccles clang::driver::options::OPT_fno_openmp); 10274f130fa9STom Eccles if (!arg || arg->getOption().matches(clang::driver::options::OPT_fno_openmp)) 10289dadb1f6SSergio Afonso return true; 10299dadb1f6SSergio Afonso 10309dadb1f6SSergio Afonso unsigned numErrorsBefore = diags.getNumErrors(); 10319dadb1f6SSergio Afonso llvm::Triple t(res.getTargetOpts().triple); 10329dadb1f6SSergio Afonso 1033d93bdd8bSDominik Adamski // By default OpenMP is set to 1.1 version 1034d93bdd8bSDominik Adamski res.getLangOpts().OpenMPVersion = 11; 10351e462fafSAndrzej Warzynski res.getFrontendOpts().features.Enable( 1036ab971c29SArnamoy Bhattacharyya Fortran::common::LanguageFeature::OpenMP); 1037d93bdd8bSDominik Adamski if (int Version = getLastArgIntValue( 1038d93bdd8bSDominik Adamski args, clang::driver::options::OPT_fopenmp_version_EQ, 1039d93bdd8bSDominik Adamski res.getLangOpts().OpenMPVersion, diags)) { 1040d93bdd8bSDominik Adamski res.getLangOpts().OpenMPVersion = Version; 1041d93bdd8bSDominik Adamski } 1042b9549261SSergio Afonso if (args.hasArg(clang::driver::options::OPT_fopenmp_force_usm)) { 1043b9549261SSergio Afonso res.getLangOpts().OpenMPForceUSM = 1; 1044b9549261SSergio Afonso } 104563ca93c7SSergio Afonso if (args.hasArg(clang::driver::options::OPT_fopenmp_is_target_device)) { 104663ca93c7SSergio Afonso res.getLangOpts().OpenMPIsTargetDevice = 1; 104753152f12SAndrew Gozillon 10482e634367SAndrew Gozillon // Get OpenMP host file path if any and report if a non existent file is 10492e634367SAndrew Gozillon // found 10502e634367SAndrew Gozillon if (auto *arg = args.getLastArg( 10512e634367SAndrew Gozillon clang::driver::options::OPT_fopenmp_host_ir_file_path)) { 10522e634367SAndrew Gozillon res.getLangOpts().OMPHostIRFile = arg->getValue(); 10532e634367SAndrew Gozillon if (!llvm::sys::fs::exists(res.getLangOpts().OMPHostIRFile)) 10542e634367SAndrew Gozillon diags.Report(clang::diag::err_drv_omp_host_ir_file_not_found) 10552e634367SAndrew Gozillon << res.getLangOpts().OMPHostIRFile; 10562e634367SAndrew Gozillon } 10572e634367SAndrew Gozillon 105853152f12SAndrew Gozillon if (args.hasFlag( 105953152f12SAndrew Gozillon clang::driver::options::OPT_fopenmp_assume_teams_oversubscription, 106053152f12SAndrew Gozillon clang::driver::options:: 106153152f12SAndrew Gozillon OPT_fno_openmp_assume_teams_oversubscription, 106253152f12SAndrew Gozillon /*Default=*/false)) 106353152f12SAndrew Gozillon res.getLangOpts().OpenMPTeamSubscription = true; 106453152f12SAndrew Gozillon 10659dadb1f6SSergio Afonso if (args.hasArg(clang::driver::options::OPT_fopenmp_assume_no_thread_state)) 106653152f12SAndrew Gozillon res.getLangOpts().OpenMPNoThreadState = 1; 106753152f12SAndrew Gozillon 106853152f12SAndrew Gozillon if (args.hasArg( 106953152f12SAndrew Gozillon clang::driver::options::OPT_fopenmp_assume_no_nested_parallelism)) 107053152f12SAndrew Gozillon res.getLangOpts().OpenMPNoNestedParallelism = 1; 107153152f12SAndrew Gozillon 10729dadb1f6SSergio Afonso if (args.hasFlag( 10739dadb1f6SSergio Afonso clang::driver::options::OPT_fopenmp_assume_threads_oversubscription, 107453152f12SAndrew Gozillon clang::driver::options:: 107553152f12SAndrew Gozillon OPT_fno_openmp_assume_threads_oversubscription, 107653152f12SAndrew Gozillon /*Default=*/false)) 107753152f12SAndrew Gozillon res.getLangOpts().OpenMPThreadSubscription = true; 107853152f12SAndrew Gozillon 107953152f12SAndrew Gozillon if ((args.hasArg(clang::driver::options::OPT_fopenmp_target_debug) || 108053152f12SAndrew Gozillon args.hasArg(clang::driver::options::OPT_fopenmp_target_debug_EQ))) { 108153152f12SAndrew Gozillon res.getLangOpts().OpenMPTargetDebug = getLastArgIntValue( 108253152f12SAndrew Gozillon args, clang::driver::options::OPT_fopenmp_target_debug_EQ, 108353152f12SAndrew Gozillon res.getLangOpts().OpenMPTargetDebug, diags); 108453152f12SAndrew Gozillon 108553152f12SAndrew Gozillon if (!res.getLangOpts().OpenMPTargetDebug && 108653152f12SAndrew Gozillon args.hasArg(clang::driver::options::OPT_fopenmp_target_debug)) 108753152f12SAndrew Gozillon res.getLangOpts().OpenMPTargetDebug = 1; 108853152f12SAndrew Gozillon } 1089f443fbc4SDominik Adamski if (args.hasArg(clang::driver::options::OPT_nogpulib)) 1090f443fbc4SDominik Adamski res.getLangOpts().NoGPULib = 1; 1091e002a38bSAndrew Gozillon } 109240340cf9SSergio Afonso 109340340cf9SSergio Afonso switch (llvm::Triple(res.getTargetOpts().triple).getArch()) { 109440340cf9SSergio Afonso case llvm::Triple::nvptx: 109540340cf9SSergio Afonso case llvm::Triple::nvptx64: 109640340cf9SSergio Afonso case llvm::Triple::amdgcn: 109740340cf9SSergio Afonso if (!res.getLangOpts().OpenMPIsTargetDevice) { 109840340cf9SSergio Afonso const unsigned diagID = diags.getCustomDiagID( 109940340cf9SSergio Afonso clang::DiagnosticsEngine::Error, 110040340cf9SSergio Afonso "OpenMP AMDGPU/NVPTX is only prepared to deal with device code."); 110140340cf9SSergio Afonso diags.Report(diagID); 110240340cf9SSergio Afonso } 110340340cf9SSergio Afonso res.getLangOpts().OpenMPIsGPU = 1; 110440340cf9SSergio Afonso break; 110540340cf9SSergio Afonso default: 110640340cf9SSergio Afonso res.getLangOpts().OpenMPIsGPU = 0; 110740340cf9SSergio Afonso break; 110840340cf9SSergio Afonso } 11094c7ebf79SArnamoy Bhattacharyya 11109dadb1f6SSergio Afonso // Get the OpenMP target triples if any. 11119dadb1f6SSergio Afonso if (auto *arg = 11129dadb1f6SSergio Afonso args.getLastArg(clang::driver::options::OPT_fopenmp_targets_EQ)) { 11139dadb1f6SSergio Afonso enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit }; 11149dadb1f6SSergio Afonso auto getArchPtrSize = [](const llvm::Triple &triple) { 11159dadb1f6SSergio Afonso if (triple.isArch16Bit()) 11169dadb1f6SSergio Afonso return Arch16Bit; 11179dadb1f6SSergio Afonso if (triple.isArch32Bit()) 11189dadb1f6SSergio Afonso return Arch32Bit; 11199dadb1f6SSergio Afonso assert(triple.isArch64Bit() && "Expected 64-bit architecture"); 11209dadb1f6SSergio Afonso return Arch64Bit; 11219dadb1f6SSergio Afonso }; 1122602df270SKiran Chandramohan 11239dadb1f6SSergio Afonso for (unsigned i = 0; i < arg->getNumValues(); ++i) { 11249dadb1f6SSergio Afonso llvm::Triple tt(arg->getValue(i)); 1125602df270SKiran Chandramohan 11269dadb1f6SSergio Afonso if (tt.getArch() == llvm::Triple::UnknownArch || 11279dadb1f6SSergio Afonso !(tt.getArch() == llvm::Triple::aarch64 || tt.isPPC() || 11289dadb1f6SSergio Afonso tt.getArch() == llvm::Triple::systemz || 11299dadb1f6SSergio Afonso tt.getArch() == llvm::Triple::nvptx || 11309dadb1f6SSergio Afonso tt.getArch() == llvm::Triple::nvptx64 || 11319dadb1f6SSergio Afonso tt.getArch() == llvm::Triple::amdgcn || 11329dadb1f6SSergio Afonso tt.getArch() == llvm::Triple::x86 || 11339dadb1f6SSergio Afonso tt.getArch() == llvm::Triple::x86_64)) 11349dadb1f6SSergio Afonso diags.Report(clang::diag::err_drv_invalid_omp_target) 11359dadb1f6SSergio Afonso << arg->getValue(i); 11369dadb1f6SSergio Afonso else if (getArchPtrSize(t) != getArchPtrSize(tt)) 11379dadb1f6SSergio Afonso diags.Report(clang::diag::err_drv_incompatible_omp_arch) 11389dadb1f6SSergio Afonso << arg->getValue(i) << t.str(); 11399dadb1f6SSergio Afonso else 11409dadb1f6SSergio Afonso res.getLangOpts().OMPTargetTriples.push_back(tt); 11414c7ebf79SArnamoy Bhattacharyya } 11424c7ebf79SArnamoy Bhattacharyya } 11436d0fef48SAndrzej Warzynski return diags.getNumErrors() == numErrorsBefore; 1144ab971c29SArnamoy Bhattacharyya } 1145ab971c29SArnamoy Bhattacharyya 11469698e575SYusuke MINATO /// Parses signed integer overflow options and populates the 11479698e575SYusuke MINATO /// CompilerInvocation accordingly. 11489698e575SYusuke MINATO /// Returns false if new errors are generated. 11499698e575SYusuke MINATO /// 11509698e575SYusuke MINATO /// \param [out] invoc Stores the processed arguments 11519698e575SYusuke MINATO /// \param [in] args The compiler invocation arguments to parse 11529698e575SYusuke MINATO /// \param [out] diags DiagnosticsEngine to report erros with 11539698e575SYusuke MINATO static bool parseIntegerOverflowArgs(CompilerInvocation &invoc, 11549698e575SYusuke MINATO llvm::opt::ArgList &args, 11559698e575SYusuke MINATO clang::DiagnosticsEngine &diags) { 11569698e575SYusuke MINATO Fortran::common::LangOptions &opts = invoc.getLangOpts(); 11579698e575SYusuke MINATO 11589698e575SYusuke MINATO if (args.getLastArg(clang::driver::options::OPT_fwrapv)) 11599698e575SYusuke MINATO opts.setSignedOverflowBehavior(Fortran::common::LangOptions::SOB_Defined); 11609698e575SYusuke MINATO 11619698e575SYusuke MINATO return true; 11629698e575SYusuke MINATO } 11639698e575SYusuke MINATO 1164a784de78STom Eccles /// Parses all floating point related arguments and populates the 1165a784de78STom Eccles /// CompilerInvocation accordingly. 1166a784de78STom Eccles /// Returns false if new errors are generated. 1167a784de78STom Eccles /// 1168a784de78STom Eccles /// \param [out] invoc Stores the processed arguments 1169a784de78STom Eccles /// \param [in] args The compiler invocation arguments to parse 1170a784de78STom Eccles /// \param [out] diags DiagnosticsEngine to report erros with 1171a784de78STom Eccles static bool parseFloatingPointArgs(CompilerInvocation &invoc, 1172a784de78STom Eccles llvm::opt::ArgList &args, 1173a784de78STom Eccles clang::DiagnosticsEngine &diags) { 117458e8683aSKrzysztof Parzyszek Fortran::common::LangOptions &opts = invoc.getLangOpts(); 1175a784de78STom Eccles 1176a784de78STom Eccles if (const llvm::opt::Arg *a = 1177a784de78STom Eccles args.getLastArg(clang::driver::options::OPT_ffp_contract)) { 1178a784de78STom Eccles const llvm::StringRef val = a->getValue(); 117958e8683aSKrzysztof Parzyszek enum Fortran::common::LangOptions::FPModeKind fpContractMode; 1180a784de78STom Eccles 1181a784de78STom Eccles if (val == "off") 118258e8683aSKrzysztof Parzyszek fpContractMode = Fortran::common::LangOptions::FPM_Off; 1183a784de78STom Eccles else if (val == "fast") 118458e8683aSKrzysztof Parzyszek fpContractMode = Fortran::common::LangOptions::FPM_Fast; 1185a784de78STom Eccles else { 1186a784de78STom Eccles diags.Report(clang::diag::err_drv_unsupported_option_argument) 11878c2c6228SFangrui Song << a->getSpelling() << val; 1188a784de78STom Eccles return false; 1189a784de78STom Eccles } 1190a784de78STom Eccles 1191a784de78STom Eccles opts.setFPContractMode(fpContractMode); 1192a784de78STom Eccles } 1193a784de78STom Eccles 119442c79f70SZahira Ammarguellat if (args.getLastArg(clang::driver::options::OPT_menable_no_infs)) { 11950fb763e7STom Eccles opts.NoHonorInfs = true; 11960fb763e7STom Eccles } 11970fb763e7STom Eccles 11983a1b4092STom Eccles if (args.getLastArg(clang::driver::options::OPT_menable_no_nans)) { 1199b5e93e39STom Eccles opts.NoHonorNaNs = true; 1200b5e93e39STom Eccles } 1201b5e93e39STom Eccles 12023a1b4092STom Eccles if (args.getLastArg(clang::driver::options::OPT_fapprox_func)) { 120336b37a1eSTom Eccles opts.ApproxFunc = true; 120436b37a1eSTom Eccles } 120536b37a1eSTom Eccles 12063a1b4092STom Eccles if (args.getLastArg(clang::driver::options::OPT_fno_signed_zeros)) { 1207b5b8a8cfSTom Eccles opts.NoSignedZeros = true; 1208b5b8a8cfSTom Eccles } 1209b5b8a8cfSTom Eccles 12103a1b4092STom Eccles if (args.getLastArg(clang::driver::options::OPT_mreassociate)) { 1211c4dc3c02STom Eccles opts.AssociativeMath = true; 1212c4dc3c02STom Eccles } 1213c4dc3c02STom Eccles 12143a1b4092STom Eccles if (args.getLastArg(clang::driver::options::OPT_freciprocal_math)) { 1215d0d4b635STom Eccles opts.ReciprocalMath = true; 1216d0d4b635STom Eccles } 1217d0d4b635STom Eccles 1218e7b66602STom Eccles if (args.getLastArg(clang::driver::options::OPT_ffast_math)) { 1219e7b66602STom Eccles opts.NoHonorInfs = true; 1220e7b66602STom Eccles opts.NoHonorNaNs = true; 1221e7b66602STom Eccles opts.AssociativeMath = true; 1222e7b66602STom Eccles opts.ReciprocalMath = true; 1223e7b66602STom Eccles opts.ApproxFunc = true; 1224e7b66602STom Eccles opts.NoSignedZeros = true; 122558e8683aSKrzysztof Parzyszek opts.setFPContractMode(Fortran::common::LangOptions::FPM_Fast); 1226e7b66602STom Eccles } 1227e7b66602STom Eccles 1228a784de78STom Eccles return true; 1229a784de78STom Eccles } 1230a784de78STom Eccles 123111e68c7eSMats Petersson /// Parses vscale range options and populates the CompilerInvocation 123211e68c7eSMats Petersson /// accordingly. 123311e68c7eSMats Petersson /// Returns false if new errors are generated. 123411e68c7eSMats Petersson /// 123511e68c7eSMats Petersson /// \param [out] invoc Stores the processed arguments 123611e68c7eSMats Petersson /// \param [in] args The compiler invocation arguments to parse 123711e68c7eSMats Petersson /// \param [out] diags DiagnosticsEngine to report erros with 123811e68c7eSMats Petersson static bool parseVScaleArgs(CompilerInvocation &invoc, llvm::opt::ArgList &args, 123911e68c7eSMats Petersson clang::DiagnosticsEngine &diags) { 12408cac995eSAndrzej Warzyński const auto *vscaleMin = 12418cac995eSAndrzej Warzyński args.getLastArg(clang::driver::options::OPT_mvscale_min_EQ); 12428cac995eSAndrzej Warzyński const auto *vscaleMax = 12438cac995eSAndrzej Warzyński args.getLastArg(clang::driver::options::OPT_mvscale_max_EQ); 12448cac995eSAndrzej Warzyński 12458cac995eSAndrzej Warzyński if (!vscaleMin && !vscaleMax) 12468cac995eSAndrzej Warzyński return true; 12478cac995eSAndrzej Warzyński 12488cac995eSAndrzej Warzyński llvm::Triple triple = llvm::Triple(invoc.getTargetOpts().triple); 12498cac995eSAndrzej Warzyński if (!triple.isAArch64() && !triple.isRISCV()) { 12508cac995eSAndrzej Warzyński const unsigned diagID = 12518cac995eSAndrzej Warzyński diags.getCustomDiagID(clang::DiagnosticsEngine::Error, 12528cac995eSAndrzej Warzyński "`-mvscale-max` and `-mvscale-min` are not " 12538cac995eSAndrzej Warzyński "supported for this architecture: %0"); 12548cac995eSAndrzej Warzyński diags.Report(diagID) << triple.getArchName(); 12558cac995eSAndrzej Warzyński return false; 12568cac995eSAndrzej Warzyński } 12578cac995eSAndrzej Warzyński 125858e8683aSKrzysztof Parzyszek Fortran::common::LangOptions &opts = invoc.getLangOpts(); 12598cac995eSAndrzej Warzyński if (vscaleMin) { 12608cac995eSAndrzej Warzyński llvm::StringRef argValue = llvm::StringRef(vscaleMin->getValue()); 12618cac995eSAndrzej Warzyński unsigned vscaleMinVal; 12628cac995eSAndrzej Warzyński if (argValue.getAsInteger(/*Radix=*/10, vscaleMinVal)) { 126311e68c7eSMats Petersson diags.Report(clang::diag::err_drv_unsupported_option_argument) 12648cac995eSAndrzej Warzyński << vscaleMax->getSpelling() << argValue; 126511e68c7eSMats Petersson return false; 126611e68c7eSMats Petersson } 12678cac995eSAndrzej Warzyński opts.VScaleMin = vscaleMinVal; 126811e68c7eSMats Petersson } 12698cac995eSAndrzej Warzyński 12708cac995eSAndrzej Warzyński if (vscaleMax) { 12718cac995eSAndrzej Warzyński llvm::StringRef argValue = llvm::StringRef(vscaleMax->getValue()); 12728cac995eSAndrzej Warzyński unsigned vscaleMaxVal; 12738cac995eSAndrzej Warzyński if (argValue.getAsInteger(/*Radix=w*/ 10, vscaleMaxVal)) { 127411e68c7eSMats Petersson diags.Report(clang::diag::err_drv_unsupported_option_argument) 12758cac995eSAndrzej Warzyński << vscaleMax->getSpelling() << argValue; 127611e68c7eSMats Petersson return false; 127711e68c7eSMats Petersson } 12788cac995eSAndrzej Warzyński opts.VScaleMax = vscaleMaxVal; 127911e68c7eSMats Petersson } 128011e68c7eSMats Petersson return true; 128111e68c7eSMats Petersson } 128211e68c7eSMats Petersson 128377ecb9a4SDavid Truby static bool parseLinkerOptionsArgs(CompilerInvocation &invoc, 128477ecb9a4SDavid Truby llvm::opt::ArgList &args, 128577ecb9a4SDavid Truby clang::DiagnosticsEngine &diags) { 128677ecb9a4SDavid Truby llvm::Triple triple = llvm::Triple(invoc.getTargetOpts().triple); 128777ecb9a4SDavid Truby 128877ecb9a4SDavid Truby // TODO: support --dependent-lib on other platforms when MLIR supports 128977ecb9a4SDavid Truby // !llvm.dependent.lib 129077ecb9a4SDavid Truby if (args.hasArg(clang::driver::options::OPT_dependent_lib) && 129177ecb9a4SDavid Truby !triple.isOSWindows()) { 129277ecb9a4SDavid Truby const unsigned diagID = 129377ecb9a4SDavid Truby diags.getCustomDiagID(clang::DiagnosticsEngine::Error, 129477ecb9a4SDavid Truby "--dependent-lib is only supported on Windows"); 129577ecb9a4SDavid Truby diags.Report(diagID); 129677ecb9a4SDavid Truby return false; 129777ecb9a4SDavid Truby } 129877ecb9a4SDavid Truby 129977ecb9a4SDavid Truby invoc.getCodeGenOpts().DependentLibs = 130077ecb9a4SDavid Truby args.getAllArgValues(clang::driver::options::OPT_dependent_lib); 130177ecb9a4SDavid Truby return true; 130277ecb9a4SDavid Truby } 130377ecb9a4SDavid Truby 13049698e575SYusuke MINATO static bool parseLangOptionsArgs(CompilerInvocation &invoc, 13059698e575SYusuke MINATO llvm::opt::ArgList &args, 13069698e575SYusuke MINATO clang::DiagnosticsEngine &diags) { 13079698e575SYusuke MINATO bool success = true; 13089698e575SYusuke MINATO 13099698e575SYusuke MINATO success &= parseIntegerOverflowArgs(invoc, args, diags); 13109698e575SYusuke MINATO success &= parseFloatingPointArgs(invoc, args, diags); 13119698e575SYusuke MINATO success &= parseVScaleArgs(invoc, args, diags); 13129698e575SYusuke MINATO 13139698e575SYusuke MINATO return success; 13149698e575SYusuke MINATO } 13159698e575SYusuke MINATO 13161e462fafSAndrzej Warzynski bool CompilerInvocation::createFromArgs( 131748e96e97SAndrzej Warzyński CompilerInvocation &invoc, llvm::ArrayRef<const char *> commandLineArgs, 1318541f5c4aSHussain Kadhem clang::DiagnosticsEngine &diags, const char *argv0) { 1319257b2971SCaroline Concatto 1320257b2971SCaroline Concatto bool success = true; 1321257b2971SCaroline Concatto 132202fb5b77SAndrzej Warzynski // Set the default triple for this CompilerInvocation. This might be 132302fb5b77SAndrzej Warzynski // overridden by users with `-triple` (see the call to `ParseTargetArgs` 132402fb5b77SAndrzej Warzynski // below). 132502fb5b77SAndrzej Warzynski // NOTE: Like in Clang, it would be nice to use option marshalling 132602fb5b77SAndrzej Warzynski // for this so that the entire logic for setting-up the triple is in one 132702fb5b77SAndrzej Warzynski // place. 132848e96e97SAndrzej Warzyński invoc.getTargetOpts().triple = 132902fb5b77SAndrzej Warzynski llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); 133002fb5b77SAndrzej Warzynski 1331257b2971SCaroline Concatto // Parse the arguments 1332257b2971SCaroline Concatto const llvm::opt::OptTable &opts = clang::driver::getDriverOptTable(); 13339478f661SJustin Bogner llvm::opt::Visibility visibilityMask(clang::driver::options::FC1Option); 1334257b2971SCaroline Concatto unsigned missingArgIndex, missingArgCount; 1335257b2971SCaroline Concatto llvm::opt::InputArgList args = opts.ParseArgs( 13369478f661SJustin Bogner commandLineArgs, missingArgIndex, missingArgCount, visibilityMask); 1337257b2971SCaroline Concatto 13382b4c9bc4SAndrzej Warzynski // Check for missing argument error. 13392b4c9bc4SAndrzej Warzynski if (missingArgCount) { 13402b4c9bc4SAndrzej Warzynski diags.Report(clang::diag::err_drv_missing_argument) 13412b4c9bc4SAndrzej Warzynski << args.getArgString(missingArgIndex) << missingArgCount; 13422b4c9bc4SAndrzej Warzynski success = false; 13432b4c9bc4SAndrzej Warzynski } 13442b4c9bc4SAndrzej Warzynski 1345257b2971SCaroline Concatto // Issue errors on unknown arguments 1346257b2971SCaroline Concatto for (const auto *a : args.filtered(clang::driver::options::OPT_UNKNOWN)) { 1347257b2971SCaroline Concatto auto argString = a->getAsString(args); 1348257b2971SCaroline Concatto std::string nearest; 13499478f661SJustin Bogner if (opts.findNearest(argString, nearest, visibilityMask) > 1) 1350257b2971SCaroline Concatto diags.Report(clang::diag::err_drv_unknown_argument) << argString; 1351257b2971SCaroline Concatto else 1352257b2971SCaroline Concatto diags.Report(clang::diag::err_drv_unknown_argument_with_suggestion) 1353257b2971SCaroline Concatto << argString << nearest; 1354257b2971SCaroline Concatto success = false; 1355257b2971SCaroline Concatto } 1356257b2971SCaroline Concatto 1357acf6a322STom Eccles // -flang-experimental-hlfir 135839ecf9d8STom Eccles if (args.hasArg(clang::driver::options::OPT_flang_experimental_hlfir) || 135939ecf9d8STom Eccles args.hasArg(clang::driver::options::OPT_emit_hlfir)) { 136048e96e97SAndrzej Warzyński invoc.loweringOpts.setLowerToHighLevelFIR(true); 1361acf6a322STom Eccles } 1362acf6a322STom Eccles 13639f265c38SjeanPerier // -flang-deprecated-no-hlfir 13649f265c38SjeanPerier if (args.hasArg(clang::driver::options::OPT_flang_deprecated_no_hlfir) && 13659f265c38SjeanPerier !args.hasArg(clang::driver::options::OPT_emit_hlfir)) { 13669f265c38SjeanPerier if (args.hasArg(clang::driver::options::OPT_flang_experimental_hlfir)) { 13679f265c38SjeanPerier const unsigned diagID = diags.getCustomDiagID( 13689f265c38SjeanPerier clang::DiagnosticsEngine::Error, 13699f265c38SjeanPerier "Options '-flang-experimental-hlfir' and " 13709f265c38SjeanPerier "'-flang-deprecated-no-hlfir' cannot be both specified"); 13719f265c38SjeanPerier diags.Report(diagID); 13729f265c38SjeanPerier } 137348e96e97SAndrzej Warzyński invoc.loweringOpts.setLowerToHighLevelFIR(false); 13749f265c38SjeanPerier } 13759f265c38SjeanPerier 137600769d69SKelvin Li // -fno-ppc-native-vector-element-order 137700769d69SKelvin Li if (args.hasArg(clang::driver::options::OPT_fno_ppc_native_vec_elem_order)) { 137848e96e97SAndrzej Warzyński invoc.loweringOpts.setNoPPCNativeVecElemOrder(true); 137900769d69SKelvin Li } 138000769d69SKelvin Li 1381ce326259SKiran Chandramohan // -f[no-]init-global-zero 1382ce326259SKiran Chandramohan if (args.hasFlag(clang::driver::options::OPT_finit_global_zero, 1383ce326259SKiran Chandramohan clang::driver::options::OPT_fno_init_global_zero, 1384ce326259SKiran Chandramohan /*default=*/true)) 1385ce326259SKiran Chandramohan invoc.loweringOpts.setInitGlobalZero(true); 1386ce326259SKiran Chandramohan else 1387ce326259SKiran Chandramohan invoc.loweringOpts.setInitGlobalZero(false); 1388ce326259SKiran Chandramohan 138991989c67SVictor Kingi // Preserve all the remark options requested, i.e. -Rpass, -Rpass-missed or 139091989c67SVictor Kingi // -Rpass-analysis. This will be used later when processing and outputting the 139191989c67SVictor Kingi // remarks generated by LLVM in ExecuteCompilerInvocation.cpp. 13928e315c6cSVictor Kingi for (auto *a : args.filtered(clang::driver::options::OPT_R_Group)) { 13938e315c6cSVictor Kingi if (a->getOption().matches(clang::driver::options::OPT_R_value_Group)) 13948e315c6cSVictor Kingi // This is -Rfoo=, where foo is the name of the diagnostic 13958e315c6cSVictor Kingi // group. Add only the remark option name to the diagnostics. e.g. for 13968e315c6cSVictor Kingi // -Rpass= we will add the string "pass". 139748e96e97SAndrzej Warzyński invoc.getDiagnosticOpts().Remarks.push_back( 13988e315c6cSVictor Kingi std::string(a->getOption().getName().drop_front(1).rtrim("=-"))); 13998e315c6cSVictor Kingi else 14008e315c6cSVictor Kingi // If no regex was provided, add the provided value, e.g. for -Rpass add 14018e315c6cSVictor Kingi // the string "pass". 140248e96e97SAndrzej Warzyński invoc.getDiagnosticOpts().Remarks.push_back(a->getValue()); 14038e315c6cSVictor Kingi } 140491989c67SVictor Kingi 14059d338749SSlava Zakharin // -frealloc-lhs is the default. 14069d338749SSlava Zakharin if (!args.hasFlag(clang::driver::options::OPT_frealloc_lhs, 14079d338749SSlava Zakharin clang::driver::options::OPT_fno_realloc_lhs, true)) 14089d338749SSlava Zakharin invoc.loweringOpts.setReallocateLHS(false); 14099d338749SSlava Zakharin 141048e96e97SAndrzej Warzyński success &= parseFrontendArgs(invoc.getFrontendOpts(), args, diags); 141148e96e97SAndrzej Warzyński parseTargetArgs(invoc.getTargetOpts(), args); 141248e96e97SAndrzej Warzyński parsePreprocessorArgs(invoc.getPreprocessorOpts(), args); 141348e96e97SAndrzej Warzyński parseCodeGenArgs(invoc.getCodeGenOpts(), args, diags); 141448e96e97SAndrzej Warzyński success &= parseDebugArgs(invoc.getCodeGenOpts(), args, diags); 141548e96e97SAndrzej Warzyński success &= parseVectorLibArg(invoc.getCodeGenOpts(), args, diags); 141648e96e97SAndrzej Warzyński success &= parseSemaArgs(invoc, args, diags); 141748e96e97SAndrzej Warzyński success &= parseDialectArgs(invoc, args, diags); 14189dadb1f6SSergio Afonso success &= parseOpenMPArgs(invoc, args, diags); 141948e96e97SAndrzej Warzyński success &= parseDiagArgs(invoc, args, diags); 1420ebc2c71dSAndrzej Warzynski 1421ebc2c71dSAndrzej Warzynski // Collect LLVM (-mllvm) and MLIR (-mmlir) options. 1422ebc2c71dSAndrzej Warzynski // NOTE: Try to avoid adding any options directly to `llvmArgs` or 1423ebc2c71dSAndrzej Warzynski // `mlirArgs`. Instead, you can use 1424ebc2c71dSAndrzej Warzynski // * `-mllvm <your-llvm-option>`, or 1425ebc2c71dSAndrzej Warzynski // * `-mmlir <your-mlir-option>`. 142648e96e97SAndrzej Warzyński invoc.frontendOpts.llvmArgs = 1427a7c08bcfSAndrzej Warzynski args.getAllArgValues(clang::driver::options::OPT_mllvm); 142848e96e97SAndrzej Warzyński invoc.frontendOpts.mlirArgs = 14296c93e1d3SAndrzej Warzynski args.getAllArgValues(clang::driver::options::OPT_mmlir); 14306c93e1d3SAndrzej Warzynski 14319698e575SYusuke MINATO success &= parseLangOptionsArgs(invoc, args, diags); 143211e68c7eSMats Petersson 143348e96e97SAndrzej Warzyński success &= parseLinkerOptionsArgs(invoc, args, diags); 143477ecb9a4SDavid Truby 1435541f5c4aSHussain Kadhem // Set the string to be used as the return value of the COMPILER_OPTIONS 1436541f5c4aSHussain Kadhem // intrinsic of iso_fortran_env. This is either passed in from the parent 1437541f5c4aSHussain Kadhem // compiler driver invocation with an environment variable, or failing that 1438541f5c4aSHussain Kadhem // set to the command line arguments of the frontend driver invocation. 143948e96e97SAndrzej Warzyński invoc.allCompilerInvocOpts = std::string(); 144048e96e97SAndrzej Warzyński llvm::raw_string_ostream os(invoc.allCompilerInvocOpts); 1441541f5c4aSHussain Kadhem char *compilerOptsEnv = std::getenv("FLANG_COMPILER_OPTIONS_STRING"); 1442541f5c4aSHussain Kadhem if (compilerOptsEnv != nullptr) { 1443541f5c4aSHussain Kadhem os << compilerOptsEnv; 1444541f5c4aSHussain Kadhem } else { 1445541f5c4aSHussain Kadhem os << argv0 << ' '; 1446541f5c4aSHussain Kadhem for (auto it = commandLineArgs.begin(), e = commandLineArgs.end(); it != e; 1447541f5c4aSHussain Kadhem ++it) { 1448541f5c4aSHussain Kadhem os << ' ' << *it; 1449541f5c4aSHussain Kadhem } 1450541f5c4aSHussain Kadhem } 1451541f5c4aSHussain Kadhem 1452310c281bSmacurtis-amd // Process the timing-related options. 1453310c281bSmacurtis-amd if (args.hasArg(clang::driver::options::OPT_ftime_report)) 1454310c281bSmacurtis-amd invoc.enableTimers = true; 1455310c281bSmacurtis-amd 145648e96e97SAndrzej Warzyński invoc.setArgv0(argv0); 14578dc474c6Smadanial0 1458257b2971SCaroline Concatto return success; 1459257b2971SCaroline Concatto } 1460d28de0d7SCaroline Concatto 14611e462fafSAndrzej Warzynski void CompilerInvocation::collectMacroDefinitions() { 14621e462fafSAndrzej Warzynski auto &ppOpts = this->getPreprocessorOpts(); 1463b83a4450SAndrzej Warzynski 14647809fa20SFaris Rehman for (unsigned i = 0, n = ppOpts.macros.size(); i != n; ++i) { 14657809fa20SFaris Rehman llvm::StringRef macro = ppOpts.macros[i].first; 14667809fa20SFaris Rehman bool isUndef = ppOpts.macros[i].second; 14677809fa20SFaris Rehman 14687809fa20SFaris Rehman std::pair<llvm::StringRef, llvm::StringRef> macroPair = macro.split('='); 14697809fa20SFaris Rehman llvm::StringRef macroName = macroPair.first; 14707809fa20SFaris Rehman llvm::StringRef macroBody = macroPair.second; 14717809fa20SFaris Rehman 14727809fa20SFaris Rehman // For an #undef'd macro, we only care about the name. 14737809fa20SFaris Rehman if (isUndef) { 14741e462fafSAndrzej Warzynski parserOpts.predefinitions.emplace_back(macroName.str(), 14751e462fafSAndrzej Warzynski std::optional<std::string>{}); 14767809fa20SFaris Rehman continue; 14777809fa20SFaris Rehman } 14787809fa20SFaris Rehman 14797809fa20SFaris Rehman // For a #define'd macro, figure out the actual definition. 14807809fa20SFaris Rehman if (macroName.size() == macro.size()) 14817809fa20SFaris Rehman macroBody = "1"; 14827809fa20SFaris Rehman else { 14837809fa20SFaris Rehman // Note: GCC drops anything following an end-of-line character. 14841e462fafSAndrzej Warzynski llvm::StringRef::size_type end = macroBody.find_first_of("\n\r"); 14851e462fafSAndrzej Warzynski macroBody = macroBody.substr(0, end); 14867809fa20SFaris Rehman } 14871e462fafSAndrzej Warzynski parserOpts.predefinitions.emplace_back( 14887809fa20SFaris Rehman macroName, std::optional<std::string>(macroBody.str())); 14897809fa20SFaris Rehman } 14907809fa20SFaris Rehman } 14917809fa20SFaris Rehman 14921e462fafSAndrzej Warzynski void CompilerInvocation::setDefaultFortranOpts() { 14931e462fafSAndrzej Warzynski auto &fortranOptions = getFortranOpts(); 1494d28de0d7SCaroline Concatto 1495d28de0d7SCaroline Concatto std::vector<std::string> searchDirectories{"."s}; 1496d28de0d7SCaroline Concatto fortranOptions.searchDirectories = searchDirectories; 1497dda366edSAndrzej Warzynski 1498dda366edSAndrzej Warzynski // Add the location of omp_lib.h to the search directories. Currently this is 1499dda366edSAndrzej Warzynski // identical to the modules' directory. 15008dc474c6Smadanial0 fortranOptions.searchDirectories.emplace_back( 15018dc474c6Smadanial0 getOpenMPHeadersDir(getArgv0())); 1502dda366edSAndrzej Warzynski 1503d28de0d7SCaroline Concatto fortranOptions.isFixedForm = false; 15040feff71eSAndrzej Warzynski } 15050feff71eSAndrzej Warzynski 15060feff71eSAndrzej Warzynski // TODO: When expanding this method, consider creating a dedicated API for 15070feff71eSAndrzej Warzynski // this. Also at some point we will need to differentiate between different 15080feff71eSAndrzej Warzynski // targets and add dedicated predefines for each. 15091e462fafSAndrzej Warzynski void CompilerInvocation::setDefaultPredefinitions() { 15101e462fafSAndrzej Warzynski auto &fortranOptions = getFortranOpts(); 15111e462fafSAndrzej Warzynski const auto &frontendOptions = getFrontendOpts(); 1512197d9a55SFaris Rehman // Populate the macro list with version numbers and other predefinitions. 1513197d9a55SFaris Rehman fortranOptions.predefinitions.emplace_back("__flang__", "1"); 151474d5c3c0SPeter Steinfeld fortranOptions.predefinitions.emplace_back("__flang_major__", 151574d5c3c0SPeter Steinfeld FLANG_VERSION_MAJOR_STRING); 151674d5c3c0SPeter Steinfeld fortranOptions.predefinitions.emplace_back("__flang_minor__", 151774d5c3c0SPeter Steinfeld FLANG_VERSION_MINOR_STRING); 151874d5c3c0SPeter Steinfeld fortranOptions.predefinitions.emplace_back("__flang_patchlevel__", 151974d5c3c0SPeter Steinfeld FLANG_VERSION_PATCHLEVEL_STRING); 15206d48a1a5SFaris Rehman 15216d48a1a5SFaris Rehman // Add predefinitions based on extensions enabled 152223d4c4f3SAndrzej Warzynski if (frontendOptions.features.IsEnabled( 15236d48a1a5SFaris Rehman Fortran::common::LanguageFeature::OpenACC)) { 15240d6017cdSValentin Clement fortranOptions.predefinitions.emplace_back("_OPENACC", "202211"); 15256d48a1a5SFaris Rehman } 152623d4c4f3SAndrzej Warzynski if (frontendOptions.features.IsEnabled( 15276d48a1a5SFaris Rehman Fortran::common::LanguageFeature::OpenMP)) { 15284a5ac14eSDominik Adamski Fortran::common::setOpenMPMacro(getLangOpts().OpenMPVersion, 15294a5ac14eSDominik Adamski fortranOptions.predefinitions); 15306d48a1a5SFaris Rehman } 1531987258f5SDaniel Chen 15321cfae76eSPeter Steinfeld llvm::Triple targetTriple{llvm::Triple(this->targetOpts.triple)}; 15338136ac1cSDaniel Chen if (targetTriple.isPPC()) { 15348136ac1cSDaniel Chen // '__powerpc__' is a generic macro for any PowerPC cases. e.g. Max integer 15358136ac1cSDaniel Chen // size. 15368136ac1cSDaniel Chen fortranOptions.predefinitions.emplace_back("__powerpc__", "1"); 15378136ac1cSDaniel Chen } 15388136ac1cSDaniel Chen if (targetTriple.isOSLinux()) { 15398136ac1cSDaniel Chen fortranOptions.predefinitions.emplace_back("__linux__", "1"); 15408136ac1cSDaniel Chen } 15418136ac1cSDaniel Chen 1542987258f5SDaniel Chen switch (targetTriple.getArch()) { 1543987258f5SDaniel Chen default: 1544987258f5SDaniel Chen break; 1545987258f5SDaniel Chen case llvm::Triple::ArchType::x86_64: 15461cfae76eSPeter Steinfeld fortranOptions.predefinitions.emplace_back("__x86_64__", "1"); 15471cfae76eSPeter Steinfeld fortranOptions.predefinitions.emplace_back("__x86_64", "1"); 1548987258f5SDaniel Chen break; 15491cfae76eSPeter Steinfeld } 15506d48a1a5SFaris Rehman } 15516d48a1a5SFaris Rehman 15521e462fafSAndrzej Warzynski void CompilerInvocation::setFortranOpts() { 15531e462fafSAndrzej Warzynski auto &fortranOptions = getFortranOpts(); 15541e462fafSAndrzej Warzynski const auto &frontendOptions = getFrontendOpts(); 15551e462fafSAndrzej Warzynski const auto &preprocessorOptions = getPreprocessorOpts(); 15561e462fafSAndrzej Warzynski auto &moduleDirJ = getModuleDir(); 15577809fa20SFaris Rehman 155823d4c4f3SAndrzej Warzynski if (frontendOptions.fortranForm != FortranForm::Unknown) { 15593a1513c1SFaris Rehman fortranOptions.isFixedForm = 156023d4c4f3SAndrzej Warzynski frontendOptions.fortranForm == FortranForm::FixedForm; 15613a1513c1SFaris Rehman } 156223d4c4f3SAndrzej Warzynski fortranOptions.fixedFormColumns = frontendOptions.fixedFormColumns; 15633a1513c1SFaris Rehman 15644dfed691SPeter Klausler // -E 15654dfed691SPeter Klausler fortranOptions.prescanAndReformat = 15664dfed691SPeter Klausler frontendOptions.programAction == PrintPreprocessedInput; 15674dfed691SPeter Klausler 156823d4c4f3SAndrzej Warzynski fortranOptions.features = frontendOptions.features; 156923d4c4f3SAndrzej Warzynski fortranOptions.encoding = frontendOptions.encoding; 15706d48a1a5SFaris Rehman 1571cd4abc52SArnamoy Bhattacharyya // Adding search directories specified by -I 157287dfd5e0SFaris Rehman fortranOptions.searchDirectories.insert( 157387dfd5e0SFaris Rehman fortranOptions.searchDirectories.end(), 157487dfd5e0SFaris Rehman preprocessorOptions.searchDirectoriesFromDashI.begin(), 157587dfd5e0SFaris Rehman preprocessorOptions.searchDirectoriesFromDashI.end()); 1576985a42fdSArnamoy Bhattacharyya 1577cd4abc52SArnamoy Bhattacharyya // Add the ordered list of -intrinsic-modules-path 1578cd4abc52SArnamoy Bhattacharyya fortranOptions.searchDirectories.insert( 1579cd4abc52SArnamoy Bhattacharyya fortranOptions.searchDirectories.end(), 1580cd4abc52SArnamoy Bhattacharyya preprocessorOptions.searchDirectoriesFromIntrModPath.begin(), 1581cd4abc52SArnamoy Bhattacharyya preprocessorOptions.searchDirectoriesFromIntrModPath.end()); 1582cd4abc52SArnamoy Bhattacharyya 158352a1346bSPeter Klausler // Add the default intrinsic module directory 15848dc474c6Smadanial0 fortranOptions.intrinsicModuleDirectories.emplace_back( 15858dc474c6Smadanial0 getIntrinsicDir(getArgv0())); 1586cd4abc52SArnamoy Bhattacharyya 1587985a42fdSArnamoy Bhattacharyya // Add the directory supplied through -J/-module-dir to the list of search 1588985a42fdSArnamoy Bhattacharyya // directories 1589d0f1283eSKazu Hirata if (moduleDirJ != ".") 1590985a42fdSArnamoy Bhattacharyya fortranOptions.searchDirectories.emplace_back(moduleDirJ); 1591523d7bc6SAndrzej Warzynski 159223d4c4f3SAndrzej Warzynski if (frontendOptions.instrumentedParse) 1593523d7bc6SAndrzej Warzynski fortranOptions.instrumentedParse = true; 15944c7ebf79SArnamoy Bhattacharyya 15958df63a23SPeixin Qiao if (frontendOptions.showColors) 15968df63a23SPeixin Qiao fortranOptions.showColors = true; 15978df63a23SPeixin Qiao 159823d4c4f3SAndrzej Warzynski if (frontendOptions.needProvenanceRangeToCharBlockMappings) 159985b86c6fSAndrzej Warzynski fortranOptions.needProvenanceRangeToCharBlockMappings = true; 160085b86c6fSAndrzej Warzynski 1601191d4872SPeter Klausler if (getEnableConformanceChecks()) 16024c7ebf79SArnamoy Bhattacharyya fortranOptions.features.WarnOnAllNonstandard(); 1603191d4872SPeter Klausler 1604191d4872SPeter Klausler if (getEnableUsageChecks()) 1605191d4872SPeter Klausler fortranOptions.features.WarnOnAllUsage(); 1606602df270SKiran Chandramohan 1607602df270SKiran Chandramohan if (getDisableWarnings()) { 1608602df270SKiran Chandramohan fortranOptions.features.DisableAllNonstandardWarnings(); 1609602df270SKiran Chandramohan fortranOptions.features.DisableAllUsageWarnings(); 1610602df270SKiran Chandramohan } 1611985a42fdSArnamoy Bhattacharyya } 1612985a42fdSArnamoy Bhattacharyya 1613ae4d7ac9SAndrzej Warzyński std::unique_ptr<Fortran::semantics::SemanticsContext> 1614ae4d7ac9SAndrzej Warzyński CompilerInvocation::getSemanticsCtx( 1615e59e8488SjeanPerier Fortran::parser::AllCookedSources &allCookedSources, 1616e59e8488SjeanPerier const llvm::TargetMachine &targetMachine) { 16171cfae76eSPeter Steinfeld auto &fortranOptions = getFortranOpts(); 16186d48a1a5SFaris Rehman 1619ae4d7ac9SAndrzej Warzyński auto semanticsContext = std::make_unique<semantics::SemanticsContext>( 16203b20a833SKrzysztof Parzyszek getDefaultKinds(), fortranOptions.features, getLangOpts(), 16213b20a833SKrzysztof Parzyszek allCookedSources); 16226d48a1a5SFaris Rehman 16231e462fafSAndrzej Warzynski semanticsContext->set_moduleDirectory(getModuleDir()) 16244c7ebf79SArnamoy Bhattacharyya .set_searchDirectories(fortranOptions.searchDirectories) 162552a1346bSPeter Klausler .set_intrinsicModuleDirectories(fortranOptions.intrinsicModuleDirectories) 16261e462fafSAndrzej Warzynski .set_warningsAreErrors(getWarnAsErr()) 16276ffea74fSjeanPerier .set_moduleFileSuffix(getModuleFileSuffix()) 16286ffea74fSjeanPerier .set_underscoring(getCodeGenOpts().Underscoring); 1629c4f04a12SPeixin Qiao 1630e59e8488SjeanPerier std::string compilerVersion = Fortran::common::getFlangFullVersion(); 1631e59e8488SjeanPerier Fortran::tools::setUpTargetCharacteristics( 1632697bc748SRenaud Kauffmann semanticsContext->targetCharacteristics(), targetMachine, getTargetOpts(), 1633697bc748SRenaud Kauffmann compilerVersion, allCompilerInvocOpts); 1634ae4d7ac9SAndrzej Warzyński return semanticsContext; 16357809fa20SFaris Rehman } 1636f1eb945fSSlava Zakharin 1637f1eb945fSSlava Zakharin /// Set \p loweringOptions controlling lowering behavior based 1638f1eb945fSSlava Zakharin /// on the \p optimizationLevel. 1639f1eb945fSSlava Zakharin void CompilerInvocation::setLoweringOptions() { 16408f3f15c1SSlava Zakharin const CodeGenOptions &codegenOpts = getCodeGenOpts(); 1641f1eb945fSSlava Zakharin 1642f1eb945fSSlava Zakharin // Lower TRANSPOSE as a runtime call under -O0. 1643f1eb945fSSlava Zakharin loweringOpts.setOptimizeTranspose(codegenOpts.OptimizationLevel > 0); 16446ffea74fSjeanPerier loweringOpts.setUnderscoring(codegenOpts.Underscoring); 16458f3f15c1SSlava Zakharin 164658e8683aSKrzysztof Parzyszek const Fortran::common::LangOptions &langOptions = getLangOpts(); 16479698e575SYusuke MINATO loweringOpts.setIntegerWrapAround(langOptions.getSignedOverflowBehavior() == 16489698e575SYusuke MINATO Fortran::common::LangOptions::SOB_Defined); 16498f3f15c1SSlava Zakharin Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions(); 16508f3f15c1SSlava Zakharin // TODO: when LangOptions are finalized, we can represent 16518f3f15c1SSlava Zakharin // the math related options using Fortran::commmon::MathOptionsBase, 16528f3f15c1SSlava Zakharin // so that we can just copy it into LoweringOptions. 16538f3f15c1SSlava Zakharin mathOpts 16548f3f15c1SSlava Zakharin .setFPContractEnabled(langOptions.getFPContractMode() == 165558e8683aSKrzysztof Parzyszek Fortran::common::LangOptions::FPM_Fast) 16563538ca3fSSlava Zakharin .setNoHonorInfs(langOptions.NoHonorInfs) 16573538ca3fSSlava Zakharin .setNoHonorNaNs(langOptions.NoHonorNaNs) 16583538ca3fSSlava Zakharin .setApproxFunc(langOptions.ApproxFunc) 16593538ca3fSSlava Zakharin .setNoSignedZeros(langOptions.NoSignedZeros) 16603538ca3fSSlava Zakharin .setAssociativeMath(langOptions.AssociativeMath) 16613538ca3fSSlava Zakharin .setReciprocalMath(langOptions.ReciprocalMath); 1662f1eb945fSSlava Zakharin } 1663