[test-suite] Support Fortran tests in CMake infrastructure.

In preparation for Flang compiler, add support for Fortran in CMake. Include a simple Fortran90 hello world test. Tested with GFortran.

Reviewed By: Meinersbur

Differential Revision: https://reviews.llvm.org/D93778
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7bdee3c..1ab7ecf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,8 +2,14 @@
 
 include(CheckSymbolExists)
 
+option(TEST_SUITE_FORTRAN "Enable Fortran test suite" OFF)
+
 project(test-suite C CXX)
 
+if(TEST_SUITE_FORTRAN)
+  enable_language(Fortran)
+endif()
+
 function(append value)
   foreach(variable ${ARGN})
     set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
@@ -21,6 +27,9 @@
 # On the other hand we often want to switch compiler or cflags
 mark_as_advanced(CLEAR CMAKE_C_COMPILER CMAKE_CXX_COMPILER CMAKE_LINKER
   CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS)
+if(TEST_SUITE_FORTRAN)
+    mark_as_advanced(CLEAR CMAKE_Fortran_COMPILER)
+endif()
 
 # The files in cmake/caches often want to pass along additional flags to select
 # the target architecture. Note that you should still use
@@ -29,6 +38,9 @@
    "Extra flags to select target architecture.")
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_SUITE_ARCH_FLAGS}")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TEST_SUITE_ARCH_FLAGS}")
+if(TEST_SUITE_FORTRAN)
+  set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${TEST_SUITE_ARCH_FLAGS}")
+endif()
 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_SUITE_ARCH_FLAGS}")
 
 set(LLVM_CODESIGNING_IDENTITY "" CACHE STRING
@@ -153,12 +165,16 @@
 # LNT to gather data, for examples -ftime-report, or -mllvm -stats. This way
 # the user specified CMAKE_C_FLAGS etc. need not be changed.
 set(TEST_SUITE_DIAGNOSE_FLAGS CACHE STRING
-   "Extra flags appended to CMAKE_C_FLAGS + CMAKE_CXX_FLAGS")
+   "Extra flags appended to CMAKE_C_FLAGS + CMAKE_CXX_FLAGS + CMAKE_Fortran_FLAGS")
 set(TEST_SUITE_DIAGNOSE_LINKER_FLAGS CACHE STRING
     "Extra flags appended to CMAKE_EXE_LINKER_FLAGS")
 mark_as_advanced(TEST_SUITE_DIAGNOSE_FLAGS TEST_SUITE_DIAGNOSE_LINKER_FLAGS)
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_SUITE_DIAGNOSE_FLAGS}")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TEST_SUITE_DIAGNOSE_FLAGS}")
+if(TEST_SUITE_FORTRAN)
+  set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${TEST_SUITE_DIAGNOSE_FLAGS}")
+endif()
+
 set(CMAKE_EXE_LINKER_FLAGS
     "${CMAKE_EXE_LINKER_FLAGS} ${TEST_SUITE_DIAGNOSE_LINKER_FLAGS}")
 
@@ -172,12 +188,25 @@
 # specifies CMAKE_C_FLAGS and similar.
 set(TEST_SUITE_EXTRA_C_FLAGS CACHE STRING "Extra flags for CMAKE_C_FLAGS")
 set(TEST_SUITE_EXTRA_CXX_FLAGS CACHE STRING "Extra flags for CMAKE_CXX_FLAGS")
+if(TEST_SUITE_FORTRAN)
+  set(TEST_SUITE_EXTRA_Fortran_FLAGS CACHE STRING "Extra flags for CMAKE_Fortran_FLAGS")
+endif()
+
 set(TEST_SUITE_EXTRA_EXE_LINKER_FLAGS CACHE STRING
     "Extra flags for CMAKE_EXE_LINKER_FLAGS")
 mark_as_advanced(TEST_SUITE_EXTRA_C_FLAGS, TEST_SUITE_EXTRA_CXX_FLAGS,
                  TEST_SUITE_EXTRA_EXE_LINKER_FLAGS)
+
+if(TEST_SUITE_FORTRAN)
+  mark_as_advanced(TEST_SUITE_EXTRA_Fortran_FLAGS TEST_SUITE_EXTRA_EXE_LINKER_FLAGS)
+endif()
+
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_SUITE_EXTRA_C_FLAGS}")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TEST_SUITE_EXTRA_CXX_FLAGS}")
+if(TEST_SUITE_FORTRAN)
+  set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${TEST_SUITE_EXTRA_Fortran_FLAGS}")
+endif()
+
 set(CMAKE_EXE_LINKER_FLAGS
     "${CMAKE_EXE_LINKER_FLAGS} ${TEST_SUITE_EXTRA_EXE_LINKER_FLAGS}")
 
diff --git a/SingleSource/UnitTests/CMakeLists.txt b/SingleSource/UnitTests/CMakeLists.txt
index 86310a3..b3b1647 100644
--- a/SingleSource/UnitTests/CMakeLists.txt
+++ b/SingleSource/UnitTests/CMakeLists.txt
@@ -12,6 +12,11 @@
   add_subdirectory(ObjC++)
 endif()
 
+# Fortran
+if(TEST_SUITE_FORTRAN)
+  add_subdirectory(Fortran)
+endif()
+
 file(GLOB Source RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c *.cpp)
 if(TARGET_OS STREQUAL "AIX" AND ARCH STREQUAL "PowerPC" AND NOT PPC_IS_PPC64_ENABLED) 
   list(REMOVE_ITEM Source AtomicOps.c)
diff --git a/SingleSource/UnitTests/Fortran/CMakeLists.txt b/SingleSource/UnitTests/Fortran/CMakeLists.txt
new file mode 100644
index 0000000..630458a
--- /dev/null
+++ b/SingleSource/UnitTests/Fortran/CMakeLists.txt
@@ -0,0 +1 @@
+llvm_singlesource()
diff --git a/SingleSource/UnitTests/Fortran/hello.f90 b/SingleSource/UnitTests/Fortran/hello.f90
new file mode 100644
index 0000000..e75962d
--- /dev/null
+++ b/SingleSource/UnitTests/Fortran/hello.f90
@@ -0,0 +1,3 @@
+program hello
+  print *, 'Hello world'
+end program hello
diff --git a/SingleSource/UnitTests/Fortran/hello.reference_output b/SingleSource/UnitTests/Fortran/hello.reference_output
new file mode 100644
index 0000000..760c80e
--- /dev/null
+++ b/SingleSource/UnitTests/Fortran/hello.reference_output
@@ -0,0 +1,2 @@
+ Hello world
+exit 0
diff --git a/cmake/modules/SingleMultiSource.cmake b/cmake/modules/SingleMultiSource.cmake
index 7473a92..0dd7898 100644
--- a/cmake/modules/SingleMultiSource.cmake
+++ b/cmake/modules/SingleMultiSource.cmake
@@ -33,7 +33,7 @@
   if(DEFINED Source)
     set(sources ${Source})
   else()
-    file(GLOB sources *.c *.cpp *.cc)
+    file(GLOB sources *.c *.cpp *.cc *.f *.F *.f90 *.F90)
   endif()
   foreach(source ${sources})
     basename(name ${source})
@@ -51,7 +51,7 @@
 function(llvm_multisource target)
   set(sources ${ARGN})
   if(NOT sources)
-    file(GLOB sources *.c *.cpp *.cc)
+    file(GLOB sources *.c *.cpp *.cc *.f *.F *.f90 *.F90)
   endif()
 
   llvm_test_executable_no_test(${target} ${sources})