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 @@ -678,7 +678,7 @@ HelpText<"Restrict all prior -I flags to double-quoted inclusion and " "remove current directory from include path">; def I : JoinedOrSeparate<["-"], "I">, Group, - Flags<[CC1Option,CC1AsOption]>, MetaVarName<"">, + Flags<[CC1Option,CC1AsOption,FlangOption,FC1Option]>, MetaVarName<"">, HelpText<"Add directory to the end of the list of include search paths">, DocBrief<[{Add directory to include search path. For C++ inputs, if there are multiple -I options, these directories are searched 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 @@ -21,7 +21,7 @@ void Flang::AddPreprocessingOptions(const ArgList &Args, ArgStringList &CmdArgs) const { - Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U}); + Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I}); } 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 @@ -24,6 +24,11 @@ class PreprocessorOptions { public: std::vector> macros; + // Search directories specified by the user with -I + // TODO: When adding support for more options related to search paths, + // 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; public: PreprocessorOptions() {} 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 @@ -176,6 +176,10 @@ opts.addMacroUndef(currentArg->getValue()); } } + + // Add the ordered list of -I's. + for (const auto *currentArg : args.filtered(clang::driver::options::OPT_I)) + opts.searchDirectoriesFromDashI.emplace_back(currentArg->getValue()); } bool CompilerInvocation::CreateFromArgs(CompilerInvocation &res, @@ -261,4 +265,9 @@ const auto &preprocessorOptions = preprocessorOpts(); collectMacroDefinitions(preprocessorOptions, fortranOptions); + + fortranOptions.searchDirectories.insert( + fortranOptions.searchDirectories.end(), + preprocessorOptions.searchDirectoriesFromDashI.begin(), + preprocessorOptions.searchDirectoriesFromDashI.end()); } diff --git a/flang/test/Flang-Driver/Inputs/basic-header-one.h b/flang/test/Flang-Driver/Inputs/basic-header-one.h new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/basic-header-one.h @@ -0,0 +1 @@ +#define X MainDirectoryOne diff --git a/flang/test/Flang-Driver/Inputs/basic-header-two.h b/flang/test/Flang-Driver/Inputs/basic-header-two.h new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/basic-header-two.h @@ -0,0 +1 @@ +#define Y MainDirectoryTwo diff --git a/flang/test/Flang-Driver/Inputs/basictestmoduleone.mod b/flang/test/Flang-Driver/Inputs/basictestmoduleone.mod new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/basictestmoduleone.mod @@ -0,0 +1 @@ +NOT A REAL MODULE FILE - USE THIS ONLY FOR TESTING THE DRIVER diff --git a/flang/test/Flang-Driver/Inputs/header-dir/basic-header-one.h b/flang/test/Flang-Driver/Inputs/header-dir/basic-header-one.h new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/header-dir/basic-header-one.h @@ -0,0 +1 @@ +#define X SubDirectoryOne diff --git a/flang/test/Flang-Driver/Inputs/header-dir/basic-header-two.h b/flang/test/Flang-Driver/Inputs/header-dir/basic-header-two.h new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/header-dir/basic-header-two.h @@ -0,0 +1 @@ +#define Y SubDirectoryTwo diff --git a/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduletwo.mod b/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduletwo.mod new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/module-dir/basictestmoduletwo.mod @@ -0,0 +1 @@ +NOT A REAL MODULE FILE - USE THIS ONLY FOR TESTING THE DRIVER diff --git a/flang/test/Flang-Driver/driver-help-hidden.f90 b/flang/test/Flang-Driver/driver-help-hidden.f90 --- a/flang/test/Flang-Driver/driver-help-hidden.f90 +++ b/flang/test/Flang-Driver/driver-help-hidden.f90 @@ -25,6 +25,7 @@ ! CHECK-NEXT: -fcolor-diagnostics Enable colors in diagnostics ! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics ! CHECK-NEXT: -help Display available options +! CHECK-NEXT: -I Add directory to the end of the list of include search paths ! CHECK-NEXT: -o Write output to ! CHECK-NEXT: -test-io Run the InputOuputTest action. Use for development and testing only. ! CHECK-NEXT: -U Undefine macro diff --git a/flang/test/Flang-Driver/driver-help.f90 b/flang/test/Flang-Driver/driver-help.f90 --- a/flang/test/Flang-Driver/driver-help.f90 +++ b/flang/test/Flang-Driver/driver-help.f90 @@ -25,6 +25,7 @@ ! HELP-NEXT: -fcolor-diagnostics Enable colors in diagnostics ! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics ! HELP-NEXT: -help Display available options +! HELP-NEXT: -I Add directory to the end of the list of include search paths ! HELP-NEXT: -o Write output to ! HELP-NEXT: -U Undefine macro ! HELP-NEXT: --version Print version information @@ -39,6 +40,7 @@ ! HELP-FC1-NEXT: -emit-obj Emit native object files ! HELP-FC1-NEXT: -E Only run the preprocessor ! HELP-FC1-NEXT: -help Display available options +! HELP-FC1-NEXT: -I Add directory to the end of the list of include search paths ! HELP-FC1-NEXT: -o Write output to ! HELP-FC1-NEXT: -U Undefine macro ! HELP-FC1-NEXT: --version Print version information diff --git a/flang/test/Flang-Driver/include-header.f90 b/flang/test/Flang-Driver/include-header.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/include-header.f90 @@ -0,0 +1,77 @@ +! Ensure argument -I works as expected with an included header. + +! REQUIRES: new-flang-driver + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: not %flang-new -E %s 2>&1 | FileCheck %s --check-prefix=UNINCLUDED +! RUN: %flang-new -E -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE +! RUN: %flang-new -E -I %S/Inputs -I %S/Inputs/header-dir %s 2>&1 | FileCheck %s --check-prefix=MAINDIRECTORY +! RUN: %flang-new -E -I %S/Inputs/header-dir -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SUBDIRECTORY + +!---------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!---------------------------------------- +! RUN: not %flang-new -fc1 -E %s 2>&1 | FileCheck %s --check-prefix=UNINCLUDED +! RUN: %flang-new -fc1 -E -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE +! RUN: %flang-new -fc1 -E -I %S/Inputs -I %S/Inputs/header-dir %s 2>&1 | FileCheck %s --check-prefix=MAINDIRECTORY +! RUN: %flang-new -fc1 -E -I %S/Inputs/header-dir -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SUBDIRECTORY + +!-------------------------------------------- +! EXPECTED OUTPUT FOR MISSING INCLUDED FILE +!-------------------------------------------- +! UNINCLUDED:No such file or directory +! UNINCLUDED-NOT:program b +! UNINCLUDED-NOT:program c + +!--------------------------------------------- +! EXPECTED OUTPUT FOR A SINGLE INCLUDED FOLDER +!-------------------------------------------- +! SINGLEINCLUDE:program maindirectoryone +! SINGLEINCLUDE-NOT:program x +! SINGLEINCLUDE-NOT:program b +! SINGLEINCLUDE-NEXT:end +! SINGLEINCLUDE-NEXT:program maindirectorytwo +! SINGLEINCLUDE-NOT:program y +! SINGLEINCLUDE-NOT:program c + +!------------------------------------------------------- +! EXPECTED OUTPUT FOR Inputs/ DIRECTORY SPECIFIED FIRST +!------------------------------------------------------- +! MAINDIRECTORY:program maindirectoryone +! MAINDIRECTORY-NOT:program subdirectoryone +! MAINDIRECTORY-NOT:program b +! MAINDIRECTORY-NEXT:end +! MAINDIRECTORY-NEXT:program maindirectorytwo +! MAINDIRECTORY-NOT:program subdirectorytwo +! MAINDIRECTORY-NOT:program c + +!------------------------------------------------------------------ +! EXPECTED OUTPUT FOR Inputs/header-dir/ DIRECTORY SPECIFIED FIRST +!------------------------------------------------------------------ +! SUBDIRECTORY:program subdirectoryone +! SUBDIRECTORY-NOT:program maindirectoryone +! SUBDIRECTORY-NOT:program b +! SUBDIRECTORY-NEXT:end +! SUBDIRECTORY-NEXT:program subdirectorytwo +! SUBDIRECTORY-NOT:program maindirectorytwo +! SUBDIRECTORY-NOT:program c + +! include-test-one.f90 +#include +#ifdef X +program X +#else +program B +#endif +end + +! include-test-two.f90 +INCLUDE "basic-header-two.h" +#ifdef Y +program Y +#else +program C +#endif +end diff --git a/flang/test/Flang-Driver/include-module.f90 b/flang/test/Flang-Driver/include-module.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/include-module.f90 @@ -0,0 +1,32 @@ +! Ensure argument -I works as expected with module files. +! The module files for this test are not real module files. + +! REQUIRES: new-flang-driver + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: not %flang-new -fsyntax-only -I %S/Inputs -I %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED +! RUN: not %flang-new -fsyntax-only -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs -I %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED +! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE + +!----------------------------------------- +! EXPECTED OUTPUT FOR MISSING MODULE FILE +!----------------------------------------- +! SINGLEINCLUDE:No such file or directory +! SINGLEINCLUDE-NOT:Error reading module file for module 'basictestmoduletwo' + +!--------------------------------------- +! EXPECTED OUTPUT FOR ALL MODULES FOUND +!--------------------------------------- +! INCLUDED-NOT:No such file or directory + +program test_dash_I_with_mod_files + USE basictestmoduleone + USE basictestmoduletwo +end