summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Driver/Driver.h11
-rw-r--r--clang/include/clang/Driver/ToolChain.h2
-rw-r--r--clang/include/clang/Driver/Types.h3
-rw-r--r--clang/lib/Driver/CMakeLists.txt1
-rw-r--r--clang/lib/Driver/Driver.cpp14
-rw-r--r--clang/lib/Driver/ToolChain.cpp19
-rw-r--r--clang/lib/Driver/ToolChains/Flang.cpp79
-rw-r--r--clang/lib/Driver/ToolChains/Flang.h46
-rw-r--r--clang/lib/Driver/Types.cpp10
-rw-r--r--clang/test/Driver/flang/Inputs/one.f901
-rw-r--r--clang/test/Driver/flang/Inputs/other.c1
-rw-r--r--clang/test/Driver/flang/Inputs/two.f901
-rw-r--r--clang/test/Driver/flang/flang.F9051
-rw-r--r--clang/test/Driver/flang/flang.f9051
-rw-r--r--clang/test/Driver/flang/multiple-inputs-mixed.f907
-rw-r--r--clang/test/Driver/flang/multiple-inputs.f907
-rw-r--r--clang/test/Driver/fortran.f9537
-rw-r--r--clang/test/Driver/lit.local.cfg2
18 files changed, 322 insertions, 21 deletions
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 5e7283e31ee..64f1eb8cb5d 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -65,7 +65,8 @@ class Driver {
GCCMode,
GXXMode,
CPPMode,
- CLMode
+ CLMode,
+ FlangMode
} Mode;
enum SaveTempsMode {
@@ -180,6 +181,10 @@ public:
/// Whether the driver should follow cl.exe like behavior.
bool IsCLMode() const { return Mode == CLMode; }
+ /// Whether the driver should invoke flang for fortran inputs.
+ /// Other modes fall back to calling gcc which in turn calls gfortran.
+ bool IsFlangMode() const { return Mode == FlangMode; }
+
/// Only print tool bindings, don't build any jobs.
unsigned CCCPrintBindings : 1;
@@ -534,6 +539,10 @@ public:
/// handle this action.
bool ShouldUseClangCompiler(const JobAction &JA) const;
+ /// ShouldUseFlangCompiler - Should the flang compiler be used to
+ /// handle this action.
+ bool ShouldUseFlangCompiler(const JobAction &JA) const;
+
/// Returns true if we are performing any kind of LTO.
bool isUsingLTO() const { return LTOMode != LTOK_None; }
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index c40af1e6e01..26d8d43dd2f 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -134,6 +134,7 @@ private:
path_list ProgramPaths;
mutable std::unique_ptr<Tool> Clang;
+ mutable std::unique_ptr<Tool> Flang;
mutable std::unique_ptr<Tool> Assemble;
mutable std::unique_ptr<Tool> Link;
mutable std::unique_ptr<Tool> IfsMerge;
@@ -141,6 +142,7 @@ private:
mutable std::unique_ptr<Tool> OffloadWrapper;
Tool *getClang() const;
+ Tool *getFlang() const;
Tool *getAssemble() const;
Tool *getLink() const;
Tool *getIfsMerge() const;
diff --git a/clang/include/clang/Driver/Types.h b/clang/include/clang/Driver/Types.h
index a605450e6e3..c7c38fa5259 100644
--- a/clang/include/clang/Driver/Types.h
+++ b/clang/include/clang/Driver/Types.h
@@ -84,6 +84,9 @@ namespace types {
/// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
bool isObjC(ID Id);
+ /// isFortran - Is this a Fortran input.
+ bool isFortran(ID Id);
+
/// isSrcFile - Is this a source file, i.e. something that still has to be
/// preprocessed. The logic behind this is the same that decides if the first
/// compilation phase is a preprocessing one.
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 84fd58cf681..e175e88c4eb 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -43,6 +43,7 @@ add_clang_library(clangDriver
ToolChains/Cuda.cpp
ToolChains/Darwin.cpp
ToolChains/DragonFly.cpp
+ ToolChains/Flang.cpp
ToolChains/FreeBSD.cpp
ToolChains/Fuchsia.cpp
ToolChains/Gnu.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 4c59bf0a5e2..3fb38a79051 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -178,6 +178,7 @@ void Driver::setDriverModeFromOption(StringRef Opt) {
.Case("g++", GXXMode)
.Case("cpp", CPPMode)
.Case("cl", CLMode)
+ .Case("flang", FlangMode)
.Default(None))
Mode = *M;
else
@@ -4876,6 +4877,19 @@ bool Driver::ShouldUseClangCompiler(const JobAction &JA) const {
return true;
}
+bool Driver::ShouldUseFlangCompiler(const JobAction &JA) const {
+ // Say "no" if there is not exactly one input of a type flang understands.
+ if (JA.size() != 1 ||
+ !types::isFortran((*JA.input_begin())->getType()))
+ return false;
+
+ // And say "no" if this is not a kind of action flang understands.
+ if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
+ return false;
+
+ return true;
+}
+
/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the
/// grouped values as integers. Numbers which are not provided are set to 0.
///
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 357a5106ab3..a014c611ee2 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -11,6 +11,7 @@
#include "ToolChains/Arch/ARM.h"
#include "ToolChains/Clang.h"
#include "ToolChains/InterfaceStubs.h"
+#include "ToolChains/Flang.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Config/config.h"
@@ -151,6 +152,7 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
{"cpp", "--driver-mode=cpp"},
{"cl", "--driver-mode=cl"},
{"++", "--driver-mode=g++"},
+ {"flang", "--driver-mode=flang"},
};
for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i) {
@@ -254,6 +256,12 @@ Tool *ToolChain::getClang() const {
return Clang.get();
}
+Tool *ToolChain::getFlang() const {
+ if (!Flang)
+ Flang.reset(new tools::Flang(*this));
+ return Flang.get();
+}
+
Tool *ToolChain::buildAssembler() const {
return new tools::ClangAs(*this);
}
@@ -493,6 +501,7 @@ bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) {
}
Tool *ToolChain::SelectTool(const JobAction &JA) const {
+ if (D.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA)) return getFlang();
if (getDriver().ShouldUseClangCompiler(JA)) return getClang();
Action::ActionClass AC = JA.getKind();
if (AC == Action::AssembleJobClass && useIntegratedAs())
@@ -541,7 +550,15 @@ std::string ToolChain::GetLinkerPath() const {
}
types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {
- return types::lookupTypeForExtension(Ext);
+ types::ID id = types::lookupTypeForExtension(Ext);
+
+ // Flang always runs the preprocessor and has no notion of "preprocessed
+ // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
+ // them differently.
+ if (D.IsFlangMode() && id == types::TY_PP_Fortran)
+ id = types::TY_Fortran;
+
+ return id;
}
bool ToolChain::HasNativeLLVMSupport() const {
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
new file mode 100644
index 00000000000..9b9eb81fa11
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -0,0 +1,79 @@
+//===-- Flang.cpp - Flang+LLVM ToolChain Implementations --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "Flang.h"
+#include "CommonArgs.h"
+
+#include "clang/Driver/Options.h"
+
+#include <cassert>
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+void Flang::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const ArgList &Args, const char *LinkingOutput) const {
+ const auto &TC = getToolChain();
+ const llvm::Triple &Triple = TC.getEffectiveTriple();
+ const std::string &TripleStr = Triple.getTriple();
+
+ ArgStringList CmdArgs;
+
+ CmdArgs.push_back("-fc1");
+
+ CmdArgs.push_back("-triple");
+ CmdArgs.push_back(Args.MakeArgString(TripleStr));
+
+ if (isa<PreprocessJobAction>(JA)) {
+ CmdArgs.push_back("-E");
+ } else if (isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) {
+ if (JA.getType() == types::TY_Nothing) {
+ CmdArgs.push_back("-fsyntax-only");
+ } else if (JA.getType() == types::TY_AST) {
+ CmdArgs.push_back("-emit-ast");
+ } else if (JA.getType() == types::TY_LLVM_IR ||
+ JA.getType() == types::TY_LTO_IR) {
+ CmdArgs.push_back("-emit-llvm");
+ } else if (JA.getType() == types::TY_LLVM_BC ||
+ JA.getType() == types::TY_LTO_BC) {
+ CmdArgs.push_back("-emit-llvm-bc");
+ } else if (JA.getType() == types::TY_PP_Asm) {
+ CmdArgs.push_back("-S");
+ } else {
+ assert(false && "Unexpected output type!");
+ }
+ } else if (isa<AssembleJobAction>(JA)) {
+ CmdArgs.push_back("-emit-obj");
+ } else {
+ assert(false && "Unexpected action class for Flang tool.");
+ }
+
+ if (Output.isFilename()) {
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+ } else {
+ assert(Output.isNothing() && "Invalid output.");
+ }
+
+ const InputInfo &Input = Inputs[0];
+ assert(Input.isFilename() && "Invalid input.");
+ CmdArgs.push_back(Input.getFilename());
+
+ const auto& D = C.getDriver();
+ const char* Exec = Args.MakeArgString(D.GetProgramPath("flang", TC));
+ C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+Flang::Flang(const ToolChain &TC)
+ : Tool("flang", "flang frontend", TC, RF_Full) {}
+
+Flang::~Flang() {}
diff --git a/clang/lib/Driver/ToolChains/Flang.h b/clang/lib/Driver/ToolChains/Flang.h
new file mode 100644
index 00000000000..19e3a8c28f7
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Flang.h
@@ -0,0 +1,46 @@
+//===--- Flang.h - Flang Tool and ToolChain Implementations ====-*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FLANG_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FLANG_H
+
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/Action.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/ToolChain.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+namespace driver {
+
+namespace tools {
+
+/// Flang compiler tool.
+class LLVM_LIBRARY_VISIBILITY Flang : public Tool {
+public:
+ Flang(const ToolChain &TC);
+ ~Flang() override;
+
+ bool hasGoodDiagnostics() const override { return true; }
+ bool hasIntegratedAssembler() const override { return true; }
+ bool hasIntegratedCPP() const override { return true; }
+ bool canEmitIR() const override { return true; }
+
+ void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const override;
+};
+
+} // end namespace tools
+
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FLANG_H
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index a30710645af..0e14e3d63fa 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -212,6 +212,16 @@ bool types::isHIP(ID Id) {
}
}
+bool types::isFortran(ID Id) {
+ switch (Id) {
+ default:
+ return false;
+
+ case TY_Fortran: case TY_PP_Fortran:
+ return true;
+ }
+}
+
bool types::isSrcFile(ID Id) {
return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID;
}
diff --git a/clang/test/Driver/flang/Inputs/one.f90 b/clang/test/Driver/flang/Inputs/one.f90
new file mode 100644
index 00000000000..3c234da8c26
--- /dev/null
+++ b/clang/test/Driver/flang/Inputs/one.f90
@@ -0,0 +1 @@
+! This file only exists to facilitate a driver -### test.
diff --git a/clang/test/Driver/flang/Inputs/other.c b/clang/test/Driver/flang/Inputs/other.c
new file mode 100644
index 00000000000..719903ec38b
--- /dev/null
+++ b/clang/test/Driver/flang/Inputs/other.c
@@ -0,0 +1 @@
+/* This file only exists to facilitate a driver -### test. */
diff --git a/clang/test/Driver/flang/Inputs/two.f90 b/clang/test/Driver/flang/Inputs/two.f90
new file mode 100644
index 00000000000..3c234da8c26
--- /dev/null
+++ b/clang/test/Driver/flang/Inputs/two.f90
@@ -0,0 +1 @@
+! This file only exists to facilitate a driver -### test.
diff --git a/clang/test/Driver/flang/flang.F90 b/clang/test/Driver/flang/flang.F90
new file mode 100644
index 00000000000..37553c7c276
--- /dev/null
+++ b/clang/test/Driver/flang/flang.F90
@@ -0,0 +1,51 @@
+! Check that flang -fc1 is invoked when in --driver-mode=flang.
+
+! This is a copy of flang.f90 because the driver has logic in it which
+! differentiates between F90 and f90 files. Flang will not treat these files
+! differently.
+
+! Test various output types:
+! * -E
+! * -fsyntax-only
+! * -emit-llvm -S
+! * -emit-llvm
+! * -S
+! * (no type specified, resulting in an object file)
+
+! All invocations should begin with flang -fc1, consume up to here.
+! ALL-LABEL: "{{[^"]*}}flang" "-fc1"
+
+! Check that f90 files are not treated as "previously preprocessed"
+! ... in --driver-mode=flang.
+! RUN: %clang --driver-mode=flang -### -E %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-E %s
+! CHECK-E-NOT: previously preprocessed input
+! CHECK-E-DAG: "-E"
+! CHECK-E-DAG: "-o" "-"
+
+! RUN: %clang --driver-mode=flang -### -emit-ast %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-EMIT-AST %s
+! CHECK-EMIT-AST-DAG: "-triple"
+! CHECK-EMIT-AST-DAG: "-emit-ast"
+! CHECK-EMIT-AST-DAG: "-o" "{{[^"]*}}.ast"
+
+! RUN: %clang --driver-mode=flang -### -fsyntax-only %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-SYNTAX-ONLY %s
+! CHECK-SYNTAX-ONLY-NOT: "-o"
+! CHECK-SYNTAX-ONLY-DAG: "-fsyntax-only"
+
+! RUN: %clang --driver-mode=flang -### -emit-llvm -S %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-EMIT-LLVM-IR %s
+! CHECK-EMIT-LLVM-IR-DAG: "-emit-llvm"
+! CHECK-EMIT-LLVM-IR-DAG: "-o" "{{[^"]*}}.ll"
+
+! RUN: %clang --driver-mode=flang -### -emit-llvm %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-EMIT-LLVM-BC %s
+! CHECK-EMIT-LLVM-BC-DAG: "-emit-llvm-bc"
+! CHECK-EMIT-LLVM-BC-DAG: "-o" "{{[^"]*}}.bc"
+
+! RUN: %clang --driver-mode=flang -### -S %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-S %s
+! CHECK-S-DAG: "-S"
+! CHECK-S-DAG: "-o" "{{[^"]*}}.s"
+
+! RUN: %clang --driver-mode=flang -### %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-EMIT-OBJ %s
+! CHECK-EMIT-OBJ-DAG: "-emit-obj"
+! CHECK-EMIT-OBJ-DAG: "-o" "{{[^"]*}}.o"
+
+! Should end in the input file.
+! ALL: "{{.*}}flang.F90"{{$}}
diff --git a/clang/test/Driver/flang/flang.f90 b/clang/test/Driver/flang/flang.f90
new file mode 100644
index 00000000000..56c1ace6f86
--- /dev/null
+++ b/clang/test/Driver/flang/flang.f90
@@ -0,0 +1,51 @@
+! Check that flang -fc1 is invoked when in --driver-mode=flang.
+
+! This is a copy of flang.F90 because the driver has logic in it which
+! differentiates between F90 and f90 files. Flang will not treat these files
+! differently.
+
+! Test various output types:
+! * -E
+! * -fsyntax-only
+! * -emit-llvm -S
+! * -emit-llvm
+! * -S
+! * (no type specified, resulting in an object file)
+
+! All invocations should begin with flang -fc1, consume up to here.
+! ALL-LABEL: "{{[^"]*}}flang" "-fc1"
+
+! Check that f90 files are not treated as "previously preprocessed"
+! ... in --driver-mode=flang.
+! RUN: %clang --driver-mode=flang -### -E %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-E %s
+! CHECK-E-NOT: previously preprocessed input
+! CHECK-E-DAG: "-E"
+! CHECK-E-DAG: "-o" "-"
+
+! RUN: %clang --driver-mode=flang -### -emit-ast %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-EMIT-AST %s
+! CHECK-EMIT-AST-DAG: "-triple"
+! CHECK-EMIT-AST-DAG: "-emit-ast"
+! CHECK-EMIT-AST-DAG: "-o" "{{[^"]*}}.ast"
+
+! RUN: %clang --driver-mode=flang -### -fsyntax-only %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-SYNTAX-ONLY %s
+! CHECK-SYNTAX-ONLY-NOT: "-o"
+! CHECK-SYNTAX-ONLY-DAG: "-fsyntax-only"
+
+! RUN: %clang --driver-mode=flang -### -emit-llvm -S %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-EMIT-LLVM-IR %s
+! CHECK-EMIT-LLVM-IR-DAG: "-emit-llvm"
+! CHECK-EMIT-LLVM-IR-DAG: "-o" "{{[^"]*}}.ll"
+
+! RUN: %clang --driver-mode=flang -### -emit-llvm %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-EMIT-LLVM-BC %s
+! CHECK-EMIT-LLVM-BC-DAG: "-emit-llvm-bc"
+! CHECK-EMIT-LLVM-BC-DAG: "-o" "{{[^"]*}}.bc"
+
+! RUN: %clang --driver-mode=flang -### -S %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-S %s
+! CHECK-S-DAG: "-S"
+! CHECK-S-DAG: "-o" "{{[^"]*}}.s"
+
+! RUN: %clang --driver-mode=flang -### %s 2>&1 | FileCheck --check-prefixes=ALL,CHECK-EMIT-OBJ %s
+! CHECK-EMIT-OBJ-DAG: "-emit-obj"
+! CHECK-EMIT-OBJ-DAG: "-o" "{{[^"]*}}.o"
+
+! Should end in the input file.
+! ALL: "{{.*}}flang.f90"{{$}}
diff --git a/clang/test/Driver/flang/multiple-inputs-mixed.f90 b/clang/test/Driver/flang/multiple-inputs-mixed.f90
new file mode 100644
index 00000000000..98d8cab00bd
--- /dev/null
+++ b/clang/test/Driver/flang/multiple-inputs-mixed.f90
@@ -0,0 +1,7 @@
+! Check that flang can handle mixed C and fortran inputs.
+
+! RUN: %clang --driver-mode=flang -### -fsyntax-only %S/Inputs/one.f90 %S/Inputs/other.c 2>&1 | FileCheck --check-prefixes=CHECK-SYNTAX-ONLY %s
+! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang{{[^"/]*}}" "-fc1"
+! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90"
+! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}clang{{[^"/]*}}" "-cc1"
+! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/other.c"
diff --git a/clang/test/Driver/flang/multiple-inputs.f90 b/clang/test/Driver/flang/multiple-inputs.f90
new file mode 100644
index 00000000000..34592a3dc3a
--- /dev/null
+++ b/clang/test/Driver/flang/multiple-inputs.f90
@@ -0,0 +1,7 @@
+! Check that flang driver can handle multiple inputs at once.
+
+! RUN: %clang --driver-mode=flang -### -fsyntax-only %S/Inputs/one.f90 %S/Inputs/two.f90 2>&1 | FileCheck --check-prefixes=CHECK-SYNTAX-ONLY %s
+! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang" "-fc1"
+! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90"
+! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang" "-fc1"
+! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/two.f90"
diff --git a/clang/test/Driver/fortran.f95 b/clang/test/Driver/fortran.f95
index 47c6e7b50c9..03ff99f9fbf 100644
--- a/clang/test/Driver/fortran.f95
+++ b/clang/test/Driver/fortran.f95
@@ -1,21 +1,22 @@
-// Check that the clang driver can invoke gcc to compile Fortran.
+! Check that the clang driver can invoke gcc to compile Fortran when in
+! --driver-mode=clang. This is legacy behaviour - see also --driver-mode=flang.
-// RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -c %s -### 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-OBJECT %s
-// CHECK-OBJECT: gcc
-// CHECK-OBJECT: "-c"
-// CHECK-OBJECT: "-x" "f95"
-// CHECK-OBJECT-NOT: cc1as
+! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -c %s -### 2>&1 \
+! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s
+! CHECK-OBJECT: gcc
+! CHECK-OBJECT: "-c"
+! CHECK-OBJECT: "-x" "f95"
+! CHECK-OBJECT-NOT: cc1as
-// RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-ASM %s
-// CHECK-ASM: gcc
-// CHECK-ASM: "-S"
-// CHECK-ASM: "-x" "f95"
-// CHECK-ASM-NOT: cc1
+! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \
+! RUN: | FileCheck --check-prefix=CHECK-ASM %s
+! CHECK-ASM: gcc
+! CHECK-ASM: "-S"
+! CHECK-ASM: "-x" "f95"
+! CHECK-ASM-NOT: cc1
-// RUN: %clang -Wall -target x86_64-unknown-linux-gnu -integrated-as %s -o %t -### 2>&1 | FileCheck --check-prefix=CHECK-WARN %s
-// CHECK-WARN: gcc
-// CHECK-WARN-NOT: "-Wall"
-// CHECK-WARN: ld
-// CHECK-WARN-NOT: "-Wall"
+! RUN: %clang -Wall -target x86_64-unknown-linux-gnu -integrated-as %s -o %t -### 2>&1 | FileCheck --check-prefix=CHECK-WARN %s
+! CHECK-WARN: gcc
+! CHECK-WARN-NOT: "-Wall"
+! CHECK-WARN: ld
+! CHECK-WARN-NOT: "-Wall"
diff --git a/clang/test/Driver/lit.local.cfg b/clang/test/Driver/lit.local.cfg
index 4a4ef2af23b..ad3f0e92cac 100644
--- a/clang/test/Driver/lit.local.cfg
+++ b/clang/test/Driver/lit.local.cfg
@@ -1,4 +1,4 @@
-config.suffixes = ['.c', '.cpp', '.h', '.m', '.mm', '.S', '.s', '.f90', '.f95',
+config.suffixes = ['.c', '.cpp', '.h', '.m', '.mm', '.S', '.s', '.f90', '.F90', '.f95',
'.cu', '.rs', '.cl', '.hip']
config.substitutions = list(config.substitutions)
config.substitutions.insert(0,
OpenPOWER on IntegriCloud