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 @@ -650,7 +650,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/SecondaryInputs/basic-test-header.h b/flang/test/Flang-Driver/Inputs/SecondaryInputs/basic-test-header.h new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/SecondaryInputs/basic-test-header.h @@ -0,0 +1 @@ +#define X SecondDirectory \ No newline at end of file diff --git a/flang/test/Flang-Driver/Inputs/basic-test-header.h b/flang/test/Flang-Driver/Inputs/basic-test-header.h new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/basic-test-header.h @@ -0,0 +1 @@ +#define X FirstDirectory \ No newline at end of file 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,59 @@ +! Ensure argument -I works as expected. + +! 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/SecondaryInputs %s 2>&1 | FileCheck %s --check-prefix=PRIMARYINCLUDE +! RUN: %flang-new -E -I %S/Inputs/SecondaryInputs -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SECONDARYINCLUDE +! RUN: not %flang-new -E -I %S/InvalidFolder %s 2>&1 | FileCheck %s --check-prefix=UNINCLUDED + +!----------------------------------------- +! 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 -E -I %S/Inputs -I %S/Inputs/SecondaryInputs %s 2>&1 | FileCheck %s --check-prefix=PRIMARYINCLUDE +! RUN: %flang-new -E -I %S/Inputs/SecondaryInputs -I %S/Inputs %s 2>&1 | FileCheck %s --check-prefix=SECONDARYINCLUDE +! RUN: not %flang-new -fc1 -E -I %S/InvalidFolder %s 2>&1 | FileCheck %s --check-prefix=UNINCLUDED + +!-------------------------------------------- +! EXPECTED OUTPUT FOR MISSING INCLUDED FILE +!-------------------------------------------- +! UNINCLUDED:No such file or directory +! UNINCLUDED-NOT:program a + +!-------------------------------------- +! EXPECTED OUTPUT FOR A SINGLE INCLUDE +!-------------------------------------- +! SINGLEINCLUDE:program firstdirectory +! SINGLEINCLUDE-NOT:program x +! SINGLEINCLUDE-NOT:program b +! SINGLEINCLUDE-NEXT:end + +!----------------------------------------------------- +! EXPECTED OUTPUT FOR /Inputs/ FOLDER SPECIFIED FIRST +!----------------------------------------------------- +! PRIMARYINCLUDE:program firstdirectory +! PRIMARYINCLUDE-NOT:program seconddirectory +! PRIMARYINCLUDE-NOT:program b +! PRIMARYINCLUDE-NEXT:end + +!--------------------------------------------------------------------- +! EXPECTED OUTPUT FOR /Inputs/SecondaryInputs/ FOLDER SPECIFIED FIRST +!--------------------------------------------------------------------- +! SECONDARYINCLUDE:program seconddirectory +! SECONDARYINCLUDE-NOT:program firstdirectory +! SECONDARYINCLUDE-NOT:program b +! SECONDARYINCLUDE-NEXT:end + +#include +#ifdef X +program X +#else +program B +#endif +end \ No newline at end of file