diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp --- a/flang/lib/Frontend/FrontendAction.cpp +++ b/flang/lib/Frontend/FrontendAction.cpp @@ -51,6 +51,14 @@ Fortran::parser::Options parserOptions = this->instance().invocation().fortranOpts(); + // Set the fixed form flag based on the file extension + auto pathDotIndex{currentInputPath.rfind(".")}; + if (pathDotIndex != std::string::npos) { + std::string pathSuffix{currentInputPath.substr(pathDotIndex + 1)}; + parserOptions.isFixedForm = pathSuffix == "f" || pathSuffix == "F" || + pathSuffix == "ff" || pathSuffix == "for" || pathSuffix == "FOR" || + pathSuffix == "fpp" || pathSuffix == "FPP"; + } // Prescan. In case of failure, report and return. ci.parsing().Prescan(currentInputPath, parserOptions); diff --git a/flang/lib/Frontend/FrontendOptions.cpp b/flang/lib/Frontend/FrontendOptions.cpp --- a/flang/lib/Frontend/FrontendOptions.cpp +++ b/flang/lib/Frontend/FrontendOptions.cpp @@ -13,9 +13,14 @@ InputKind FrontendOptions::GetInputKindForExtension(llvm::StringRef extension) { return llvm::StringSwitch(extension) - // TODO: Should match the list in flang/test/lit.cfg.py + // Note: Keep this list in-sync with flang/test/lit.cfg.py + // TODO: Add Cuda Fortan files (i.e. `*.cuf` and `*.CUF`). // FIXME: Currently this API allows at most 9 items per case. - .Cases("f", "F", "f77", "f90", "F90", "f95", "F95", "ff95", "f18", "F18", + // Fixed form files + .Cases("f", "F", "ff", "for", "FOR", "fpp", "FPP", Language::Fortran) + // Free form files + .Cases("f77", "f90", "F90", "ff90", "f95", "F95", "ff95", "f18", "F18", Language::Fortran) + .Cases("f03", "F03", "f08", "F08", Language::Fortran) .Default(Language::Unknown); } diff --git a/flang/test/Flang-Driver/Inputs/fixed-form-test.f b/flang/test/Flang-Driver/Inputs/fixed-form-test.f new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/fixed-form-test.f @@ -0,0 +1,2 @@ + program A + end \ No newline at end of file diff --git a/flang/test/Flang-Driver/Inputs/free-form-test.f90 b/flang/test/Flang-Driver/Inputs/free-form-test.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/Inputs/free-form-test.f90 @@ -0,0 +1,2 @@ +program A +end \ No newline at end of file diff --git a/flang/test/Flang-Driver/fixed-free-detection.f90 b/flang/test/Flang-Driver/fixed-free-detection.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/fixed-free-detection.f90 @@ -0,0 +1,38 @@ +! Ensure the driver behaves differently on a fixed form file, to a free form file, based on the file extension. + +! REQUIRES: new-flang-driver + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: %flang-new -E %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM +! RUN: %flang-new -E %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM +! RUN: %flang-new -E %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: %flang-new -fc1 -E %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM +! RUN: %flang-new -fc1 -E %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM +! RUN: %flang-new -fc1 -E %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS + +!------------------------------------- +! EXPECTED OUTPUT FOR A FREE FORM FILE +!------------------------------------- +! FREEFORM:program a +! FREEFORM-NOT:programa + +!--------------------------------------- +! EXPECTED OUTPUT FOR A FIXED FORM FILE +!--------------------------------------- +! FIXEDFORM:programa +! FIXEDFORM-NOT:program a + +!------------------------------------------------ +! EXPECTED OUTPUT FOR 2 FILES OF DIFFERENT FORMS +!------------------------------------------------ +! MULTIPLEFORMS:program a +! MULTIPLEFORMS-NOT:programa +! MULTIPLEFORMS-NEXT:end +! MULTIPLEFORMS-NEXT:programa +! MULTIPLEFORMS-NOT:program a \ No newline at end of file diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py --- a/flang/test/lit.cfg.py +++ b/flang/test/lit.cfg.py @@ -26,8 +26,8 @@ # suffixes: A list of file extensions to treat as test files. config.suffixes = ['.c', '.cpp', '.f', '.F', '.ff', '.FOR', '.for', '.f77', '.f90', '.F90', - '.ff90', '.f95', '.F95', '.ff95', '.fpp', '.FPP', '.cuf', - '.CUF', '.f18', '.F18', '.fir'] + '.ff90', '.f95', '.F95', '.ff95', '.fpp', '.FPP', '.cuf' + '.CUF', '.f18', '.F18', '.fir', '.f03', '.F03', '.f08', '.F08'] config.substitutions.append(('%PATH%', config.environment['PATH'])) diff --git a/flang/unittests/Frontend/FrontendActionTest.cpp b/flang/unittests/Frontend/FrontendActionTest.cpp --- a/flang/unittests/Frontend/FrontendActionTest.cpp +++ b/flang/unittests/Frontend/FrontendActionTest.cpp @@ -40,7 +40,7 @@ // Generate a unique test file name. const testing::TestInfo *const test_info = testing::UnitTest::GetInstance()->current_test_info(); - inputFileName_ = std::string(test_info->name()) + "_test-file.f"; + inputFileName_ = std::string(test_info->name()) + "_test-file.f90"; // Create the input file stream. Note that this stream is populated // separately in every test (i.e. the input is test specific).