diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4256,7 +4256,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; @@ -4338,6 +4337,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.}]>; } def J : JoinedOrSeparate<["-"], "J">, diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/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, diff --git a/flang/include/flang/Frontend/PreprocessorOptions.h b/flang/include/flang/Frontend/PreprocessorOptions.h --- a/flang/include/flang/Frontend/PreprocessorOptions.h +++ b/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 diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -21,6 +21,8 @@ #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" #include @@ -285,6 +287,16 @@ return dashX; } +// Generate the path to look for intrinsic modules +static std::string getIntrinsicDir() { + // TODO: Find a system independent API + llvm::SmallString<128> driverPath; + driverPath.assign(llvm::sys::fs::getMainExecutable(nullptr, nullptr)); + llvm::sys::path::remove_filename(driverPath); + driverPath.append("/../include/flang/"); + return std::string(driverPath); +} + /// Parses all preprocessor input arguments and populates the preprocessor /// options accordingly. /// @@ -305,6 +317,12 @@ // 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. + for (const auto *currentArg : + args.filtered(clang::driver::options::OPT_fintrinsic_modules_path)) + opts.searchDirectoriesFromIntrModPath.emplace_back(currentArg->getValue()); } /// Parses all semantic related arguments and populates the variables @@ -499,11 +517,21 @@ 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 default intrinsic module directory at the end + fortranOptions.searchDirectories.emplace_back(getIntrinsicDir()); + // Add the directory supplied through -J/-module-dir to the list of search // directories if (moduleDirJ.compare(".") != 0) diff --git a/flang/test/Driver/Inputs/ieee_arithmetic.mod b/flang/test/Driver/Inputs/ieee_arithmetic.mod new file mode 100644 --- /dev/null +++ b/flang/test/Driver/Inputs/ieee_arithmetic.mod @@ -0,0 +1,7 @@ +! DUMMY module +! Added for testing purposes. The contents of this file are currently not relevant. +module ieee_arithmetic +type::ieee_round_type +integer(1),private::mode=0_1 +end type +end diff --git a/flang/test/Driver/Inputs/iso_fortran_env.mod b/flang/test/Driver/Inputs/iso_fortran_env.mod new file mode 100644 --- /dev/null +++ b/flang/test/Driver/Inputs/iso_fortran_env.mod @@ -0,0 +1,7 @@ +! DUMMY module +! Added for testing purposes. The contents of this file are currently not relevant. +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 diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/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 diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 --- a/flang/test/Driver/driver-help.f90 +++ b/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 @@ -83,6 +85,8 @@ ! HELP-FC1-NEXT: -fget-symbols-sources Dump symbols and their source code locations ! 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 diff --git a/flang/test/Driver/intrinsic_module_path.f90 b/flang/test/Driver/intrinsic_module_path.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Driver/intrinsic_module_path.f90 @@ -0,0 +1,37 @@ +! 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. + +! REQUIRES: new-flang-driver + + +!-------------------------- +! 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