Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -4261,7 +4261,6 @@ defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group; defm init_local_zero : BooleanFFlag<"init-local-zero">, Group; defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group; -defm intrinsic_modules_path : BooleanFFlag<"intrinsic-modules-path">, Group; defm max_identifier_length : BooleanFFlag<"max-identifier-length">, Group; defm module_private : BooleanFFlag<"module-private">, Group; defm pack_derived : BooleanFFlag<"pack-derived">, Group; @@ -4342,6 +4341,10 @@ def fno_implicit_none : Flag<["-"], "fno-implicit-none">, Group; def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group, HelpText<"Enable the old style PARAMETER statement">; +def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group, MetaVarName<"">, + HelpText<"Specify where to find the compiled intrinsic modules">, + DocBrief<[{This option specifies the location of pre-compiled intrinsic modules, + if they are not in the default location expected by the compiler.}]>; } //===----------------------------------------------------------------------===// Index: clang/lib/Driver/ToolChains/Flang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Flang.cpp +++ clang/lib/Driver/ToolChains/Flang.cpp @@ -42,7 +42,8 @@ void Flang::AddOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { Args.AddAllArgs(CmdArgs, - {options::OPT_module_dir, options::OPT_fdebug_module_writer}); + {options::OPT_module_dir, options::OPT_fdebug_module_writer, + options::OPT_fintrinsic_modules_path}); } void Flang::ConstructJob(Compilation &C, const JobAction &JA, Index: flang/include/flang/Frontend/PreprocessorOptions.h =================================================================== --- flang/include/flang/Frontend/PreprocessorOptions.h +++ flang/include/flang/Frontend/PreprocessorOptions.h @@ -29,6 +29,8 @@ // consider collecting them in a separate aggregate. For now we keep it here // as there is no point creating a class for just one field. std::vector searchDirectoriesFromDashI; + // Search directories specified by the user with -fintrinsic-modules-path + std::vector searchDirectoriesFromIntrModPath; public: PreprocessorOptions() {} @@ -44,4 +46,4 @@ } // namespace Fortran::frontend -#endif // LLVM_FLANG_PREPROCESSOROPTIONS_H \ No newline at end of file +#endif // LLVM_FLANG_PREPROCESSOROPTIONS_H Index: flang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- flang/lib/Frontend/CompilerInvocation.cpp +++ flang/lib/Frontend/CompilerInvocation.cpp @@ -23,6 +23,10 @@ #include "llvm/Option/OptTable.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" + +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" + #include using namespace Fortran::frontend; @@ -282,6 +286,13 @@ return dashX; } +// Generate the path to look for intrinsic modules +static std::string getIntrinsicDir() { + std::string driverPath = llvm::sys::fs::getMainExecutable(nullptr, nullptr); + driverPath = driverPath.substr(0, driverPath.find_last_of("/\\")); + return driverPath.append("/../tools/flang/include/flang/"); +} + /// Parses all preprocessor input arguments and populates the preprocessor /// options accordingly. /// @@ -302,6 +313,14 @@ // Add the ordered list of -I's. for (const auto *currentArg : args.filtered(clang::driver::options::OPT_I)) opts.searchDirectoriesFromDashI.emplace_back(currentArg->getValue()); + + // Prepend the ordered list of -intrinsic-modules-path + // to the default location to search (currently hardcoded). + // TODO: identify a value for this default search directory + for (const auto *currentArg : + args.filtered(clang::driver::options::OPT_fintrinsic_modules_path)) + opts.searchDirectoriesFromIntrModPath.emplace_back(currentArg->getValue()); + opts.searchDirectoriesFromIntrModPath.emplace_back(getIntrinsicDir()); } /// Parses all semantic related arguments and populates the variables @@ -496,11 +515,18 @@ collectMacroDefinitions(preprocessorOptions, fortranOptions); + // Adding search directories specified by -I fortranOptions.searchDirectories.insert( fortranOptions.searchDirectories.end(), preprocessorOptions.searchDirectoriesFromDashI.begin(), preprocessorOptions.searchDirectoriesFromDashI.end()); + // Add the ordered list of -intrinsic-modules-path + fortranOptions.searchDirectories.insert( + fortranOptions.searchDirectories.end(), + preprocessorOptions.searchDirectoriesFromIntrModPath.begin(), + preprocessorOptions.searchDirectoriesFromIntrModPath.end()); + // Add the directory supplied through -J/-module-dir to the list of search // directories if (moduleDirJ.compare(".") != 0) Index: flang/test/Driver/Inputs/ieee_arithmetic.mod =================================================================== --- /dev/null +++ flang/test/Driver/Inputs/ieee_arithmetic.mod @@ -0,0 +1,6 @@ +! DUMMY module +module ieee_arithmetic +type::ieee_round_type +integer(1),private::mode=0_1 +end type +end Index: flang/test/Driver/Inputs/iso_fortran_env.mod =================================================================== --- /dev/null +++ flang/test/Driver/Inputs/iso_fortran_env.mod @@ -0,0 +1,6 @@ +! DUMMY module +module iso_fortran_env +use __fortran_builtins,only:event_type=>__builtin_event_type +use __fortran_builtins,only:lock_type=>__builtin_lock_type +use __fortran_builtins,only:team_type=>__builtin_team_type +end Index: flang/test/Driver/driver-help-hidden.f90 =================================================================== --- flang/test/Driver/driver-help-hidden.f90 +++ flang/test/Driver/driver-help-hidden.f90 @@ -35,6 +35,8 @@ ! CHECK-NEXT: -ffree-form Process source files in free form ! CHECK-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements ! CHECK-NEXT: -finput-charset= Specify the default character set for source files +! CHECK-NEXT: -fintrinsic-modules-path +! CHECK-NEXT: Specify where to find the compiled intrinsic modules ! CHECK-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations ! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics Index: flang/test/Driver/driver-help.f90 =================================================================== --- flang/test/Driver/driver-help.f90 +++ flang/test/Driver/driver-help.f90 @@ -35,6 +35,8 @@ ! HELP-NEXT: -ffree-form Process source files in free form ! HELP-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements ! HELP-NEXT: -finput-charset= Specify the default character set for source files +! HELP-NEXT: -fintrinsic-modules-path +! HELP-NEXT: Specify where to find the compiled intrinsic modules ! HELP-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! HELP-NEXT: -flogical-abbreviations Enable logical abbreviations ! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics @@ -82,6 +84,8 @@ ! HELP-FC1-NEXT: -ffree-form Process source files in free form ! HELP-FC1-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements ! HELP-FC1-NEXT: -finput-charset= Specify the default character set for source files +! HELP-FC1-NEXT: -fintrinsic-modules-path +! HELP-FC1-NEXT: Specify where to find the compiled intrinsic modules ! HELP-FC1-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! HELP-FC1-NEXT: -flogical-abbreviations Enable logical abbreviations ! HELP-FC1-NEXT: -fopenacc Enable OpenACC Index: flang/test/Driver/intrinsic_module_path.f90 =================================================================== --- /dev/null +++ flang/test/Driver/intrinsic_module_path.f90 @@ -0,0 +1,35 @@ +! Ensure argument -fintrinsic-modules-path works as expected. +! WITHOUT the option, the default location for the module is checked and no error generated. +! With the option GIVEN, the module with the same name is PREPENDED, and considered over the +! default one, causing a CHECKSUM error. + + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: %flang-new -fsyntax-only %s 2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT +! RUN: not %flang-new -fsyntax-only -fintrinsic-modules-path %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=GIVEN + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: %flang-new -fc1 %s 2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT +! RUN: not %flang-new -fc1 -fintrinsic-modules-path %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=GIVEN + +!----------------------------------------- +! EXPECTED OUTPUT WITHOUT +!----------------------------------------- +! WITHOUT-NOT: 'ieee_arithmetic.mod' was not found +! WITHOUT-NOT: 'iso_fortran_env.mod' was not found + +!----------------------------------------- +! EXPECTED OUTPUT WITH +!----------------------------------------- +! GIVEN: error: Cannot read module file for module 'ieee_arithmetic': File has invalid checksum +! GIVEN: error: Cannot read module file for module 'iso_fortran_env': File has invalid checksum + + +program test_intrinsic_module_path + use ieee_arithmetic, only: ieee_round_type + use iso_fortran_env, only: team_type, event_type, lock_type +end program