CarolineConcatto updated this revision to Diff 287270.
CarolineConcatto added a comment.

Address review comments

Replace namespace flang for Fortran::frontend 
and fix style


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86089/new/

https://reviews.llvm.org/D86089

Files:
  clang/include/clang/Driver/Driver.h
  clang/include/clang/Driver/Options.h
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChains/Flang.cpp
  clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
  clang/lib/Tooling/Tooling.cpp
  clang/test/Driver/flang/flang.f90
  clang/test/Driver/flang/flang_ucase.F90
  clang/test/Driver/flang/multiple-inputs-mixed.f90
  clang/test/Driver/flang/multiple-inputs.f90
  clang/unittests/Driver/SanitizerArgsTest.cpp
  clang/unittests/Driver/ToolChainTest.cpp
  flang/CMakeLists.txt
  flang/include/flang/Frontend/CompilerInstance.h
  flang/include/flang/Frontend/CompilerInvocation.h
  flang/include/flang/Frontend/FrontendOptions.h
  flang/include/flang/FrontendTool/Utils.h
  flang/lib/CMakeLists.txt
  flang/lib/Frontend/CMakeLists.txt
  flang/lib/Frontend/CompilerInstance.cpp
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendOptions.cpp
  flang/lib/FrontendTool/CMakeLists.txt
  flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
  flang/test/CMakeLists.txt
  flang/test/Flang-Driver/driver-error-cc1.c
  flang/test/Flang-Driver/driver-error-cc1.cpp
  flang/test/Flang-Driver/driver-error-diagnostic.f90
  flang/test/Flang-Driver/driver-help.f90
  flang/test/Flang-Driver/driver-version.f90
  flang/test/lit.cfg.py
  flang/test/lit.site.cfg.py.in
  flang/tools/CMakeLists.txt
  flang/tools/flang-driver/CMakeLists.txt
  flang/tools/flang-driver/driver.cpp
  flang/tools/flang-driver/fc1_main.cpp
  flang/unittests/CMakeLists.txt
  flang/unittests/Frontend/CMakeLists.txt
  flang/unittests/Frontend/CompilerInstanceTest.cpp
  llvm/lib/Option/OptTable.cpp

Index: llvm/lib/Option/OptTable.cpp
===================================================================
--- llvm/lib/Option/OptTable.cpp
+++ llvm/lib/Option/OptTable.cpp
@@ -612,7 +612,19 @@
     unsigned Flags = getInfo(Id).Flags;
     if (FlagsToInclude && !(Flags & FlagsToInclude))
       continue;
-    if (Flags & FlagsToExclude)
+    // If `Flags` is in both the Exclude set and in the Include set - display
+    // it.
+    if ((Flags & FlagsToExclude) && !(Flags & FlagsToInclude))
+      continue;
+
+    // If `Flags` is empty (i.e. it's an option without any flags) then this is
+    // a Clang-only option. If:
+    // * we _are not_ in Flang Mode (FlagsToExclude contains FlangMode), then
+    //   display it.
+    // * we _are_ in Flang mode (FlagsToExclude does not contain FlangMode),
+    //  don't display it.
+    if (!Flags &&
+        (FlagsToExclude & /*clang::driver::options::FlangMode*/ (1 << 14)))
       continue;
 
     // If an alias doesn't have a help text, show a help text for the aliased
Index: flang/unittests/Frontend/CompilerInstanceTest.cpp
===================================================================
--- /dev/null
+++ flang/unittests/Frontend/CompilerInstanceTest.cpp
@@ -0,0 +1,52 @@
+//===- unittests/Frontend/CompilerInstanceTest.cpp - CI tests -------------===//
+//
+// 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/Frontend/CompilerInstance.h"
+#include "gtest/gtest.h"
+#include "flang/Frontend/CompilerInvocation.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Driver/Options.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <filesystem>
+using namespace llvm;
+using namespace Fortran::frontend;
+
+namespace {
+
+TEST(CompilerInstance, AllowDiagnosticLogWithUnownedDiagnosticConsumer) {
+  // 1. Set-up a basic DiagnosticConsumer
+  std::string diagnosticOutput;
+  llvm::raw_string_ostream diagnosticsOS(diagnosticOutput);
+  auto diagPrinter = std::make_unique<clang::TextDiagnosticPrinter>(
+      diagnosticsOS, new clang::DiagnosticOptions());
+
+  // 2. Create a CompilerInstance (to manage a DiagnosticEngine)
+  CompilerInstance compInst;
+
+  // 3. Set-up DiagnosticOptions
+  auto diagOpts = new clang::DiagnosticOptions();
+  // Tell the diagnostics engine to emit the diagnostic log to STDERR. This
+  // ensures that a chained diagnostic consumer is created so that the test can
+  // exercise the unowned diagnostic consumer in a chained consumer.
+  diagOpts->DiagnosticLogFile = "-";
+
+  // 4. Create a DiagnosticEngine with an unowned consumer
+  IntrusiveRefCntPtr<clang::DiagnosticsEngine> diags =
+      compInst.CreateDiagnostics(diagOpts, diagPrinter.get(),
+          /*ShouldOwnClient=*/false);
+
+  // 5. Report a diagnostic
+  diags->Report(clang::diag::err_expected) << "no crash";
+
+  // 6. Verify that the reported diagnostic wasn't lost and did end up in the
+  // output stream
+  ASSERT_EQ(diagnosticsOS.str(), "error: expected no crash\n");
+}
+} // namespace
Index: flang/unittests/Frontend/CMakeLists.txt
===================================================================
--- /dev/null
+++ flang/unittests/Frontend/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_flang_unittest(FlangFrontendTests
+  CompilerInstanceTest.cpp
+)
+
+target_link_libraries(FlangFrontendTests
+  PRIVATE
+  LLVMSupport
+  clangBasic
+  flangFrontend
+  flangFrontendTool)
Index: flang/unittests/CMakeLists.txt
===================================================================
--- flang/unittests/CMakeLists.txt
+++ flang/unittests/CMakeLists.txt
@@ -22,3 +22,7 @@
 add_subdirectory(Evaluate)
 add_subdirectory(Runtime)
 add_subdirectory(Lower)
+
+if (FLANG_BUILD_NEW_DRIVER)
+  add_subdirectory(Frontend)
+endif()
Index: flang/tools/flang-driver/fc1_main.cpp
===================================================================
--- /dev/null
+++ flang/tools/flang-driver/fc1_main.cpp
@@ -0,0 +1,56 @@
+//===-- fc1_main.cpp - Flang FC1 Compiler Frontend ------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the entry point to the flang -fc1 functionality, which implements the
+// core compiler functionality along with a number of additional tools for
+// demonstration and testing purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Frontend/CompilerInstance.h"
+#include "flang/Frontend/CompilerInvocation.h"
+#include "flang/FrontendTool/Utils.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <cstdio>
+
+using namespace Fortran::frontend;
+
+int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
+
+  // Create DiagnosticsEngine
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagID(
+      new clang::DiagnosticIDs());
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagOpts =
+      new clang::DiagnosticOptions();
+  clang::TextDiagnosticBuffer *diagsBuffer = new clang::TextDiagnosticBuffer;
+  clang::DiagnosticsEngine diags(diagID, &*diagOpts, diagsBuffer);
+
+  // Create compiler instance  compiler invocation to have a frontend
+  std::unique_ptr<CompilerInstance> flang(new CompilerInstance());
+
+  // Diagnostics engine for the frontend.
+  flang->CreateDiagnostics();
+  if (!flang->HasDiagnostics())
+    return 1;
+
+  bool success =
+      CompilerInvocation::CreateFromArgs(flang->GetInvocation(), argv, diags);
+
+  // Execute the frontend actions.
+  /*{*/ success = ExecuteCompilerInvocation(flang.get()); /*}*/
+
+  return !success;
+}
Index: flang/tools/flang-driver/driver.cpp
===================================================================
--- /dev/null
+++ flang/tools/flang-driver/driver.cpp
@@ -0,0 +1,103 @@
+//===-- main.cpp - Flang Driver -----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the entry point to the flang driver; it is a thin wrapper
+// for functionality in the Driver flang library.
+//
+//===----------------------------------------------------------------------===//
+// ClangFrontend was added to help Diagnostic error
+// Further work may be required
+#include "clang/Driver/Driver.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/VirtualFileSystem.h"
+
+// main frontend method. Lives inside fc1_main.cpp
+extern int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0);
+
+std::string GetExecutablePath(const char *argv0) {
+  // This just needs to be some symbol in the binary
+  void *p = (void *)(intptr_t)GetExecutablePath;
+  return llvm::sys::fs::getMainExecutable(argv0, p);
+}
+
+// This lets us create the DiagnosticsEngine with a properly-filled-out
+// DiagnosticOptions instance
+static clang::DiagnosticOptions *CreateAndPopulateDiagOpts(
+    llvm::ArrayRef<const char *> argv) {
+  auto *diagOpts = new clang::DiagnosticOptions;
+  return diagOpts;
+}
+
+static int ExecuteFC1Tool(llvm::SmallVectorImpl<const char *> &argV) {
+  llvm::StringRef tool = argV[1];
+  if (tool == "-fc1")
+    return fc1_main(makeArrayRef(argV).slice(2), argV[0]);
+
+  // Reject unknown tools.
+  // ATM it only supports fc1. Any fc1[*] is rejected.
+  llvm::errs() << "error: unknown integrated tool '" << tool << "'. "
+               << "Valid tools include '-fc1'.\n";
+  return 1;
+}
+
+int main(int argc_, const char **argv_) {
+
+  // Initialize variables to call the driver
+  llvm::InitLLVM x(argc_, argv_);
+  llvm::SmallVector<const char *, 256> argv(argv_, argv_ + argc_);
+
+  clang::driver::ParsedClangName targetandMode("flang", "--driver-mode=flang");
+  std::string driverPath = GetExecutablePath(argv[0]);
+
+  // Check if flang-new is in frontend mode
+  auto firstArg = std::find_if(
+      argv.begin() + 1, argv.end(), [](const char *a) { return a != nullptr; });
+  if (firstArg != argv.end()) {
+    // Something went wrong, unsupported code path.
+    // Exit early (return 1).
+    if (llvm::StringRef(argv[1]).startswith("-cc1")) {
+      llvm::errs() << "error: unknown integrated tool '" << argv[1] << "'. "
+                   << "Valid tools include '-fc1'.\n";
+      return 1;
+    }
+    // Call flang-new frontend
+    if (llvm::StringRef(argv[1]).startswith("-fc1")) {
+      return ExecuteFC1Tool(argv);
+    }
+  }
+
+  // Do driver tasks. Not in the frontend mode.
+
+  // Create DiagnosticsEngine
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagOpts =
+      CreateAndPopulateDiagOpts(argv);
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagID(
+      new clang::DiagnosticIDs());
+  clang::TextDiagnosticPrinter *diagClient =
+      new clang::TextDiagnosticPrinter(llvm::errs(), &*diagOpts);
+  clang::DiagnosticsEngine diags(diagID, &*diagOpts, diagClient);
+
+  // Prepare driver  and  run
+  clang::driver::Driver theDriver(driverPath,
+      llvm::sys::getDefaultTargetTriple(), diags, "LLVM 'Flang' Compiler:");
+  theDriver.setTargetAndMode(targetandMode);
+  std::unique_ptr<clang::driver::Compilation> c(
+      theDriver.BuildCompilation(argv));
+  llvm::SmallVector<std::pair<int, const clang::driver::Command *>, 4>
+      failingCommands;
+  return theDriver.ExecuteCompilation(*c, failingCommands);
+}
Index: flang/tools/flang-driver/CMakeLists.txt
===================================================================
--- /dev/null
+++ flang/tools/flang-driver/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Infrastructure to build flang driver entry point. Flang driver depends on
+# LLVM libraries.
+
+# Set your project compile flags.
+link_directories(${LLVM_LIBRARY_DIR})
+
+add_executable(flang-new
+  driver.cpp
+  fc1_main.cpp
+)
+
+# Link against LLVM and Clang libraries
+target_link_libraries(flang-new
+  PRIVATE
+  ${LLVM_COMMON_LIBS}
+  flangFrontend
+  flangFrontendTool
+  clangDriver
+  clangBasic
+  clangFrontend
+  LLVMSupport
+  LLVMTarget
+  LLVMOption
+)
+
+install(TARGETS flang-new DESTINATION bin)
Index: flang/tools/CMakeLists.txt
===================================================================
--- flang/tools/CMakeLists.txt
+++ flang/tools/CMakeLists.txt
@@ -7,6 +7,9 @@
 #===------------------------------------------------------------------------===#
 
 add_subdirectory(f18)
+if(FLANG_BUILD_NEW_DRIVER)
+  add_subdirectory(flang-driver)
+endif()
 if(LINK_WITH_FIR)
   add_subdirectory(tco)
 endif()
Index: flang/test/lit.site.cfg.py.in
===================================================================
--- flang/test/lit.site.cfg.py.in
+++ flang/test/lit.site.cfg.py.in
@@ -10,6 +10,9 @@
 config.flang_llvm_tools_dir = "@CMAKE_BINARY_DIR@/bin"
 config.python_executable = "@PYTHON_EXECUTABLE@"
 
+# control the regression test for flang-new driver
+config.include_flang_new_driver_test="@FLANG_BUILD_NEW_DRIVER@"
+
 # Support substitution of the tools_dir with user parameters. This is
 # used when we can't determine the tool dir at configuration time.
 try:
Index: flang/test/lit.cfg.py
===================================================================
--- flang/test/lit.cfg.py
+++ flang/test/lit.cfg.py
@@ -25,7 +25,7 @@
 config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
 
 # suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.f', '.F', '.ff','.FOR', '.for', '.f77', '.f90', '.F90',
+config.suffixes = ['.c', '.cpp', '.f', '.F', '.ff','.FOR', '.for', '.f77', '.f90', '.F90',
                    '.ff90', '.f95', '.F95', '.ff95', '.fpp', '.FPP', '.cuf',
                    '.CUF', '.f18', '.F18', '.fir' ]
 
@@ -36,7 +36,10 @@
 # excludes: A list of directories to exclude from the testsuite. The 'Inputs'
 # subdirectories contain auxiliary inputs for various tests in their parent
 # directories.
+# exclude the tests for flang_new driver while there are two drivers
 config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']
+if config.include_flang_new_driver_test == "OFF":
+  config.excludes.append('Flang-Driver')
 
 # test_source_root: The root path where tests are located.
 config.test_source_root = os.path.dirname(__file__)
@@ -61,8 +64,12 @@
     extra_args=["-intrinsic-module-directory "+config.flang_intrinsic_modules_dir],
     unresolved='fatal')
 ]
+if config.include_flang_new_driver_test == "ON":
+  tools.append(ToolSubst('%flang-new', command=FindTool('flang-new'), unresolved='fatal')) 
+  
 llvm_config.add_tool_substitutions(tools, [config.flang_llvm_tools_dir])
 
+
 # Enable libpgmath testing
 result = lit_config.params.get("LIBPGMATH")
 if result:
Index: flang/test/Flang-Driver/driver-version.f90
===================================================================
--- /dev/null
+++ flang/test/Flang-Driver/driver-version.f90
@@ -0,0 +1,10 @@
+! Test driver 'flang-new' print version
+
+! RUN: %flang-new --version 2>&1 | FileCheck %s
+
+! CHECK:flang-new version 
+! CHECK-NEXT:Target:
+! CHECK-NEXT:Thread model:
+! CHECK-NEXT:InstalledDir:
+
+
Index: flang/test/Flang-Driver/driver-help.f90
===================================================================
--- /dev/null
+++ flang/test/Flang-Driver/driver-help.f90
@@ -0,0 +1,12 @@
+! Test flang driver 'flang-new' and flang frontend driver 'flang-new -fc1' help screen
+
+! RUN: %flang-new -help 2>&1 | FileCheck %s
+! RUN: %flang-new -fc1 -help 2>&1 | FileCheck %s
+
+! CHECK:OVERVIEW: LLVM 'Flang' Compiler:
+! CHECK-EMPTY:
+! CHECK-NEXT:USAGE: flang-new
+! CHECK-EMPTY:
+! CHECK-NEXT:OPTIONS:
+! CHECK-NEXT: -help     Display available options
+! CHECK-NEXT: --version Print version information
\ No newline at end of file
Index: flang/test/Flang-Driver/driver-error-diagnostic.f90
===================================================================
--- /dev/null
+++ flang/test/Flang-Driver/driver-error-diagnostic.f90
@@ -0,0 +1,7 @@
+! Test driver 'flang-new' error diagnostic messages
+
+! RUN: not %flang-new --versiona 2>&1 | FileCheck %s
+! RUN: not %flang-new --helps 2>&1 | FileCheck %s
+
+! CHECK:error: unsupported option 
+! CHECK-NEXT:error: no input files
Index: flang/test/Flang-Driver/driver-error-cc1.cpp
===================================================================
--- /dev/null
+++ flang/test/Flang-Driver/driver-error-cc1.cpp
@@ -0,0 +1,6 @@
+! Test invalid frontend argument for the driver
+! Use cpp file to call flang-new -cc1
+
+! RUN: %flang-new %s 2>&1 | FileCheck %s
+
+! CHECK:error: unknown integrated tool '-cc1'. Valid tools include '-fc1'.
Index: flang/test/Flang-Driver/driver-error-cc1.c
===================================================================
--- /dev/null
+++ flang/test/Flang-Driver/driver-error-cc1.c
@@ -0,0 +1,6 @@
+! Test invalid frontend argument for the driver
+! Use c file to call flang-new -cc1
+
+! RUN: %flang-new %s 2>&1 | FileCheck %s
+
+! CHECK:error: unknown integrated tool '-cc1'. Valid tools include '-fc1'.
Index: flang/test/CMakeLists.txt
===================================================================
--- flang/test/CMakeLists.txt
+++ flang/test/CMakeLists.txt
@@ -37,6 +37,10 @@
   list(APPEND FLANG_TEST_DEPENDS tco)
 endif()
 
+if (FLANG_BUILD_NEW_DRIVER)
+  list(APPEND FLANG_TEST_DEPENDS flang-new)
+endif()
+
 if (FLANG_INCLUDE_TESTS)
   if (FLANG_GTEST_AVAIL)
     list(APPEND FLANG_TEST_DEPENDS FlangUnitTests)
Index: flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- /dev/null
+++ flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -0,0 +1,42 @@
+//===--- ExecuteCompilerInvocation.cpp ------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file holds ExecuteCompilerInvocation(). It is split into its own file to
+// minimize the impact of pulling in essentially everything else in Clang.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Frontend/CompilerInstance.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace Fortran::frontend;
+namespace Fortran::frontend {
+bool ExecuteCompilerInvocation(CompilerInstance *flang) {
+  // Honor -help.
+  if (flang->GetFrontendOpts().showHelp_) {
+    clang::driver::getDriverOptTable().PrintHelp(llvm::outs(),
+        "flang-new -fc1 [options] file...", "LLVM 'Flang' Compiler:",
+        /*Include=*/clang::driver::options::FlangOption,
+        /*Exclude=*/0, /*ShowAllAliases=*/false);
+    return true;
+  }
+  // Honor -version.
+  //
+  // FIXME: Use a better -version message?
+  if (flang->GetFrontendOpts().showVersion_) {
+    llvm::cl::PrintVersionMessage();
+    return true;
+  }
+
+  return true;
+}
+
+} // namespace Fortran::frontend
Index: flang/lib/FrontendTool/CMakeLists.txt
===================================================================
--- /dev/null
+++ flang/lib/FrontendTool/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_library(flangFrontendTool
+ ExecuteCompilerInvocation.cpp
+ )
+
+target_link_libraries(flangFrontendTool
+  LLVMOption
+  LLVMSupport
+  clangBasic
+  clangDriver
+)
+
+install (TARGETS flangFrontendTool
+  ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
+  RUNTIME DESTINATION bin
+)
Index: flang/lib/Frontend/FrontendOptions.cpp
===================================================================
--- /dev/null
+++ flang/lib/Frontend/FrontendOptions.cpp
@@ -0,0 +1,9 @@
+//===- FrontendOptions.cpp ------------------------------------------------===//
+//
+// 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/Frontend/FrontendOptions.h"
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- /dev/null
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -0,0 +1,94 @@
+//===- CompilerInvocation.cpp ---------------------------------------------===//
+//
+// 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/Frontend/CompilerInvocation.h"
+#include "clang/Basic/AllDiagnostics.h"
+#include "clang/Basic/DiagnosticDriver.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace Fortran::frontend;
+
+//===----------------------------------------------------------------------===//
+// Initialization.
+//===----------------------------------------------------------------------===//
+CompilerInvocationBase::CompilerInvocationBase()
+    : diagnosticOpts_(new clang::DiagnosticOptions()) {}
+
+CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &x)
+    : diagnosticOpts_(new clang::DiagnosticOptions(x.GetDiagnosticOpts())) {}
+
+CompilerInvocationBase::~CompilerInvocationBase() = default;
+
+static InputKind ParseFrontendArgs(FrontendOptions &opts,
+    llvm::opt::ArgList &args, clang::DiagnosticsEngine &diags) {
+  if (const llvm::opt::Arg *a =
+          args.getLastArg(clang::driver::options::OPT_Action_Group)) {
+    switch (a->getOption().getID()) {
+    default: {
+      // Happens when no option is passed to the driver
+      llvm::errs() << "Unknown Option";
+      diags.Report(clang::diag::err_drv_invalid_value) << "Unknown"
+                                                       << "Options";
+      InputKind dashX(Language::Unknown);
+      return dashX;
+    }
+    }
+  }
+
+  opts.showHelp_ = args.hasArg(clang::driver::options::OPT_help);
+  opts.showVersion_ = args.hasArg(clang::driver::options::OPT_version);
+
+  InputKind dashX(Language::Unknown);
+  if (const llvm::opt::Arg *a =
+          args.getLastArg(clang::driver::options::OPT_x)) {
+    llvm::StringRef XValue = a->getValue();
+    // Principal languages.
+    dashX = llvm::StringSwitch<InputKind>(XValue)
+                .Case("f90", Language::Fortran)
+                .Default(Language::Unknown);
+
+    // Some special cases cannot be combined with suffixes.
+    if (dashX.IsUnknown())
+      dashX = llvm::StringSwitch<InputKind>(XValue)
+                  .Case("ir", Language::LLVM_IR)
+                  .Default(Language::Unknown);
+    if (dashX.IsUnknown())
+      diags.Report(clang::diag::err_drv_invalid_value)
+          << a->getAsString(args) << a->getValue();
+  }
+
+  return dashX;
+}
+
+bool CompilerInvocation::CreateFromArgs(CompilerInvocation &res,
+    llvm::ArrayRef<const char *> commandLineArgs,
+    clang::DiagnosticsEngine &diags) {
+
+  bool success = true;
+
+  // Parse the arguments.
+  const llvm::opt::OptTable &opts = clang::driver::getDriverOptTable();
+  const unsigned includedFlagsBitmask =
+      clang::driver::options::CC1Option | clang::driver::options::FlangOption;
+  unsigned missingArgIndex, missingArgCount;
+  llvm::opt::InputArgList args = opts.ParseArgs(
+      commandLineArgs, missingArgIndex, missingArgCount, includedFlagsBitmask);
+
+  InputKind dashX = ParseFrontendArgs(res.GetFrontendOpts(), args, diags);
+  (void)dashX;
+
+  return success;
+}
Index: flang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- /dev/null
+++ flang/lib/Frontend/CompilerInstance.cpp
@@ -0,0 +1,42 @@
+//===--- CompilerInstance.cpp ---------------------------------------------===//
+//
+// 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/Frontend/CompilerInstance.h"
+#include "flang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace Fortran::frontend;
+
+CompilerInstance::CompilerInstance() : invocation_(new CompilerInvocation()) {}
+
+CompilerInstance::~CompilerInstance() = default;
+
+void CompilerInstance::CreateDiagnostics(
+    clang::DiagnosticConsumer *client, bool shouldOwnClient) {
+  diagnostics_ =
+      CreateDiagnostics(&GetDiagnosticOpts(), client, shouldOwnClient);
+}
+
+clang::IntrusiveRefCntPtr<clang::DiagnosticsEngine>
+CompilerInstance::CreateDiagnostics(clang::DiagnosticOptions *opts,
+    clang::DiagnosticConsumer *client, bool shouldOwnClient) {
+  clang::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagID(
+      new clang::DiagnosticIDs());
+  clang::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diags(
+      new clang::DiagnosticsEngine(diagID, opts));
+
+  // Create the diagnostic client for reporting errors or for
+  // implementing -verify.
+  if (client) {
+    diags->setClient(client, shouldOwnClient);
+  } else {
+    diags->setClient(new clang::TextDiagnosticPrinter(llvm::errs(), opts));
+  }
+  return diags;
+}
Index: flang/lib/Frontend/CMakeLists.txt
===================================================================
--- /dev/null
+++ flang/lib/Frontend/CMakeLists.txt
@@ -0,0 +1,22 @@
+
+add_library(flangFrontend
+  CompilerInstance.cpp
+  CompilerInvocation.cpp
+  FrontendOptions.cpp
+)
+
+# ClangFrontend was added to help Diagnostic error
+# Further work may be required
+target_link_libraries(flangFrontend
+  LLVMOption
+  LLVMSupport
+  clangBasic
+  clangDriver
+  clangFrontend
+)
+
+install (TARGETS flangFrontend
+  ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
+  RUNTIME DESTINATION bin
+)
Index: flang/lib/CMakeLists.txt
===================================================================
--- flang/lib/CMakeLists.txt
+++ flang/lib/CMakeLists.txt
@@ -5,6 +5,11 @@
 add_subdirectory(Parser)
 add_subdirectory(Semantics)
 
+if(FLANG_BUILD_NEW_DRIVER)
+  add_subdirectory(Frontend)
+  add_subdirectory(FrontendTool)
+endif()
+
 if(LINK_WITH_FIR)
   add_subdirectory(Optimizer)
 endif()
Index: flang/include/flang/FrontendTool/Utils.h
===================================================================
--- /dev/null
+++ flang/include/flang/FrontendTool/Utils.h
@@ -0,0 +1,29 @@
+//===--- Utils.h - Misc utilities for the flang front-end --------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+//  This header contains miscellaneous utilities for various front-end actions
+//  which were split from Frontend to minimise Frontend's dependencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTENDTOOL_UTILS_H
+#define LLVM_FLANG_FRONTENDTOOL_UTILS_H
+
+namespace Fortran::frontend {
+
+class CompilerInstance;
+
+/// ExecuteCompilerInvocation - Execute the given actions described by the
+/// compiler invocation object in the given compiler instance.
+///
+/// \return - True on success.
+bool ExecuteCompilerInvocation(CompilerInstance *flang);
+
+} // end namespace Fortran::frontend
+
+#endif // LLVM_FLANG_FRONTENDTOOL_UTILS_H
Index: flang/include/flang/Frontend/FrontendOptions.h
===================================================================
--- /dev/null
+++ flang/include/flang/Frontend/FrontendOptions.h
@@ -0,0 +1,74 @@
+//===- FrontendOptions.h ----------------------------------------*- 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_FLANG_FRONTEND_FRONTENDOPTIONS_H
+#define LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
+
+#include <cstdint>
+#include <string>
+namespace Fortran::frontend {
+
+enum class Language : uint8_t {
+  Unknown,
+
+  /// LLVM IR: we accept this so that we can run the optimizer on it,
+  /// and compile it to assembly or object code.
+  LLVM_IR,
+
+  ///@{ Languages that the frontend can parse and compile.
+  Fortran,
+  ///@}
+};
+
+/// The kind of a file that we've been handed as an input.
+class InputKind {
+private:
+  Language lang_;
+  unsigned fmt_ : 3;
+  unsigned preprocessed_ : 1;
+
+public:
+  /// The input file format.
+  enum Format { Source, ModuleMap, Precompiled };
+
+  constexpr InputKind(
+      Language l = Language::Unknown, Format f = Source, bool pp = false)
+      : lang_(l), fmt_(f), preprocessed_(pp) {}
+
+  Language GetLanguage() const { return static_cast<Language>(lang_); }
+  Format GetFormat() const { return static_cast<Format>(fmt_); }
+  bool IsPreprocessed() const { return preprocessed_; }
+
+  /// Is the input kind fully-unknown?
+  bool IsUnknown() const {
+    return lang_ == Language::Unknown && fmt_ == Source;
+  }
+
+  InputKind GetPreprocessed() const {
+    return InputKind(GetLanguage(), GetFormat(), true);
+  }
+
+  InputKind WithFormat(Format f) const {
+    return InputKind(GetLanguage(), f, IsPreprocessed());
+  }
+};
+
+/// FrontendOptions - Options for controlling the behavior of the frontend.
+class FrontendOptions {
+public:
+  /// Show the -help text.
+  unsigned showHelp_ : 1;
+
+  /// Show the -version text.
+  unsigned showVersion_ : 1;
+
+public:
+  FrontendOptions() : showHelp_(false), showVersion_(false) {}
+};
+} // namespace Fortran::frontend
+
+#endif // LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
Index: flang/include/flang/Frontend/CompilerInvocation.h
===================================================================
--- /dev/null
+++ flang/include/flang/Frontend/CompilerInvocation.h
@@ -0,0 +1,53 @@
+//===- CompilerInvocation.h - Compiler Invocation Helper Data ---*- 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_FLANG_FRONTEND_COMPILERINVOCATION_H
+#define LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H
+
+#include "flang/Frontend/FrontendOptions.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+
+namespace Fortran::frontend {
+class CompilerInvocationBase {
+public:
+  /// Options controlling the diagnostic engine.$
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagnosticOpts_;
+
+  CompilerInvocationBase();
+  CompilerInvocationBase(const CompilerInvocationBase &x);
+  ~CompilerInvocationBase();
+
+  clang::DiagnosticOptions &GetDiagnosticOpts() {
+    return *diagnosticOpts_.get();
+  }
+  const clang::DiagnosticOptions &GetDiagnosticOpts() const {
+    return *diagnosticOpts_.get();
+  }
+};
+
+class CompilerInvocation : public CompilerInvocationBase {
+  /// Options controlling the frontend itself.
+  FrontendOptions frontendOpts_;
+
+public:
+  CompilerInvocation() = default;
+
+  FrontendOptions &GetFrontendOpts() { return frontendOpts_; }
+  const FrontendOptions &GetFrontendOpts() const { return frontendOpts_; }
+
+  /// Create a compiler invocation from a list of input options.
+  /// \returns true on success.
+  /// \returns false if an error was encountered while parsing the arguments
+  /// \param [out] res - The resulting invocation.
+  static bool CreateFromArgs(CompilerInvocation &res,
+      llvm::ArrayRef<const char *> commandLineArgs,
+      clang::DiagnosticsEngine &diags);
+};
+
+} // end namespace Fortran::frontend
+#endif // LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H
Index: flang/include/flang/Frontend/CompilerInstance.h
===================================================================
--- /dev/null
+++ flang/include/flang/Frontend/CompilerInstance.h
@@ -0,0 +1,98 @@
+//===-- CompilerInstance.h - Clang Compiler Instance ------------*- 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_FLANG_FRONTEND_COMPILERINSTANCE_H
+#define LLVM_FLANG_FRONTEND_COMPILERINSTANCE_H
+
+#include "flang/Frontend/CompilerInvocation.h"
+
+#include <cassert>
+#include <memory>
+
+namespace Fortran::frontend {
+
+class CompilerInstance {
+
+  /// The options used in this compiler instance.
+  std::shared_ptr<CompilerInvocation> invocation_;
+
+  // The diagnostics engine instance.
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_;
+
+public:
+  explicit CompilerInstance();
+
+  ~CompilerInstance();
+  CompilerInvocation &GetInvocation() {
+    assert(invocation_ && "Compiler instance has no invocation!");
+    return *invocation_;
+  };
+  /// }
+  /// @name Forwarding Methods
+  /// {
+
+  clang::DiagnosticOptions &GetDiagnosticOpts() {
+    return invocation_->GetDiagnosticOpts();
+  }
+  const clang::DiagnosticOptions &GetDiagnosticOpts() const {
+    return invocation_->GetDiagnosticOpts();
+  }
+
+  FrontendOptions &GetFrontendOpts() { return invocation_->GetFrontendOpts(); }
+  const FrontendOptions &GetFrontendOpts() const {
+    return invocation_->GetFrontendOpts();
+  }
+
+  /// }
+  /// @name Diagnostics Engine
+  /// {
+
+  bool HasDiagnostics() const { return diagnostics_ != nullptr; }
+
+  /// Get the current diagnostics engine.
+  clang::DiagnosticsEngine &GetDiagnostics() const {
+    assert(diagnostics_ && "Compiler instance has no diagnostics!");
+    return *diagnostics_;
+  }
+
+  /// SetDiagnostics - Replace the current diagnostics engine.
+  void SetDiagnostics(clang::DiagnosticsEngine *value);
+
+  clang::DiagnosticConsumer &GetDiagnosticClient() const {
+    assert(diagnostics_ && diagnostics_->getClient() &&
+        "Compiler instance has no diagnostic client!");
+    return *diagnostics_->getClient();
+  }
+
+  /// }
+  /// @name Construction Utility Methods
+  /// {
+
+  /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
+  ///
+  /// If no diagnostic client is provided, this creates a
+  /// DiagnosticConsumer that is owned by the returned diagnostic
+  /// object, if using directly the caller is responsible for
+  /// releasing the returned DiagnosticsEngine's client eventually.
+  ///
+  /// \param opts - The diagnostic options; note that the created text
+  /// diagnostic object contains a reference to these options.
+  ///
+  /// \param client If non-NULL, a diagnostic client that will be
+  /// attached to (and, then, owned by) the returned DiagnosticsEngine
+  /// object.
+  ///
+  /// \return The new object on success, or null on failure.
+  static clang::IntrusiveRefCntPtr<clang::DiagnosticsEngine> CreateDiagnostics(
+      clang::DiagnosticOptions *opts,
+      clang::DiagnosticConsumer *client = nullptr, bool shouldOwnClient = true);
+  void CreateDiagnostics(
+      clang::DiagnosticConsumer *client = nullptr, bool shouldOwnClient = true);
+};
+
+} // end namespace Fortran::frontend
+#endif // LLVM_FLANG_FRONTEND_COMPILERINSTANCE_H
Index: flang/CMakeLists.txt
===================================================================
--- flang/CMakeLists.txt
+++ flang/CMakeLists.txt
@@ -17,6 +17,7 @@
 endif()
 
 option(LINK_WITH_FIR "Link driver with FIR and LLVM" ON)
+option(FLANG_BUILD_NEW_DRIVER "Build the flang driver frontend" OFF)
 
 # Flang requires C++17.
 set(CMAKE_CXX_STANDARD 17)
@@ -192,6 +193,14 @@
   endif()
 endif()
 
+if(FLANG_BUILD_NEW_DRIVER)
+    # TODO:Removed when clangDriver and clangBasics are not in clang/lib
+    set(CLANG_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../clang/include )
+    set(CLANG_TABLEGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/tools/clang/include)
+    include_directories(SYSTEM ${CLANG_INCLUDE_DIR})
+    include_directories(SYSTEM ${CLANG_TABLEGEN_OUTPUT_DIR})
+endif()
+
 if(LINK_WITH_FIR)
   # tco tool and FIR lib output directories
   set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
Index: clang/unittests/Driver/ToolChainTest.cpp
===================================================================
--- clang/unittests/Driver/ToolChainTest.cpp
+++ clang/unittests/Driver/ToolChainTest.cpp
@@ -35,7 +35,7 @@
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
   Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags,
-                   InMemoryFileSystem);
+                   "clang LLVM compiler", InMemoryFileSystem);
 
   const char *EmptyFiles[] = {
       "foo.cpp",
@@ -89,7 +89,7 @@
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
   Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
-                   InMemoryFileSystem);
+                   "clang LLVM compiler", InMemoryFileSystem);
 
   const char *EmptyFiles[] = {
       "foo.cpp", "/home/test/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o",
@@ -130,13 +130,13 @@
       new llvm::vfs::InMemoryFileSystem);
 
   Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
-                  InMemoryFileSystem);
+                  "clang LLVM compiler", InMemoryFileSystem);
   CCDriver.setCheckInputsExist(false);
   Driver CXXDriver("/home/test/bin/clang++", "arm-linux-gnueabi", Diags,
-                   InMemoryFileSystem);
+                   "clang LLVM compiler", InMemoryFileSystem);
   CXXDriver.setCheckInputsExist(false);
   Driver CLDriver("/home/test/bin/clang-cl", "arm-linux-gnueabi", Diags,
-                  InMemoryFileSystem);
+                  "clang LLVM compiler", InMemoryFileSystem);
   CLDriver.setCheckInputsExist(false);
 
   std::unique_ptr<Compilation> CC(CCDriver.BuildCompilation(
Index: clang/unittests/Driver/SanitizerArgsTest.cpp
===================================================================
--- clang/unittests/Driver/SanitizerArgsTest.cpp
+++ clang/unittests/Driver/SanitizerArgsTest.cpp
@@ -57,7 +57,7 @@
         new DiagnosticIDs, Opts,
         new TextDiagnosticPrinter(llvm::errs(), Opts.get()));
     DriverInstance.emplace(ClangBinary, "x86_64-unknown-linux-gnu", Diags,
-                           prepareFS(ExtraFiles));
+                           "clang LLVM compiler", prepareFS(ExtraFiles));
 
     std::vector<const char *> Args = {ClangBinary};
     for (const auto &A : ExtraArgs)
Index: clang/test/Driver/flang/multiple-inputs.f90
===================================================================
--- clang/test/Driver/flang/multiple-inputs.f90
+++ clang/test/Driver/flang/multiple-inputs.f90
@@ -1,7 +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-LABEL: "{{[^"]*}}flang-new" "-fc1"
 ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90"
-! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang" "-fc1"
+! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang-new" "-fc1"
 ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/two.f90"
Index: clang/test/Driver/flang/multiple-inputs-mixed.f90
===================================================================
--- clang/test/Driver/flang/multiple-inputs-mixed.f90
+++ clang/test/Driver/flang/multiple-inputs-mixed.f90
@@ -1,7 +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-LABEL: "{{[^"]*}}flang-new{{[^"/]*}}" "-fc1"
 ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90"
 ! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}clang{{[^"/]*}}" "-cc1"
 ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/other.c"
Index: clang/test/Driver/flang/flang_ucase.F90
===================================================================
--- clang/test/Driver/flang/flang_ucase.F90
+++ clang/test/Driver/flang/flang_ucase.F90
@@ -13,7 +13,7 @@
 ! * (no type specified, resulting in an object file)
 
 ! All invocations should begin with flang -fc1, consume up to here.
-! ALL-LABEL: "{{[^"]*}}flang" "-fc1"
+! ALL-LABEL: "{{[^"]*}}flang-new" "-fc1"
 
 ! Check that f90 files are not treated as "previously preprocessed"
 ! ... in --driver-mode=flang.
Index: clang/test/Driver/flang/flang.f90
===================================================================
--- clang/test/Driver/flang/flang.f90
+++ clang/test/Driver/flang/flang.f90
@@ -13,7 +13,7 @@
 ! * (no type specified, resulting in an object file)
 
 ! All invocations should begin with flang -fc1, consume up to here.
-! ALL-LABEL: "{{[^"]*}}flang" "-fc1"
+! ALL-LABEL: "{{[^"]*}}flang-new" "-fc1"
 
 ! Check that f90 files are not treated as "previously preprocessed"
 ! ... in --driver-mode=flang.
Index: clang/lib/Tooling/Tooling.cpp
===================================================================
--- clang/lib/Tooling/Tooling.cpp
+++ clang/lib/Tooling/Tooling.cpp
@@ -78,7 +78,7 @@
           IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
   driver::Driver *CompilerDriver =
       new driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(),
-                         *Diagnostics, std::move(VFS));
+                         *Diagnostics, "clang LLVM compiler", std::move(VFS));
   CompilerDriver->setTitle("clang_based_tool");
   return CompilerDriver;
 }
Index: clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
===================================================================
--- clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -40,8 +40,8 @@
   Args.push_back("-fsyntax-only");
 
   // FIXME: We shouldn't have to pass in the path info.
-  driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(),
-                           *Diags, VFS);
+  driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(), *Diags,
+                           "clang LLVM compiler", VFS);
 
   // Don't check that inputs exist, they may have been remapped.
   TheDriver.setCheckInputsExist(false);
Index: clang/lib/Driver/ToolChains/Flang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Flang.cpp
+++ clang/lib/Driver/ToolChains/Flang.cpp
@@ -69,11 +69,13 @@
   CmdArgs.push_back(Input.getFilename());
 
   const auto& D = C.getDriver();
-  const char* Exec = Args.MakeArgString(D.GetProgramPath("flang", TC));
+  // flang-new is a experimental binary for the new flang driver
+  // TODO:Replace by flang when the new driver is fully functional
+  const char *Exec = Args.MakeArgString(D.GetProgramPath("flang-new", TC));
   C.addCommand(std::make_unique<Command>(
       JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs));
 }
 
-Flang::Flang(const ToolChain &TC) : Tool("flang", "flang frontend", TC) {}
+Flang::Flang(const ToolChain &TC) : Tool("flang-new", "flang frontend", TC) {}
 
 Flang::~Flang() {}
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -121,12 +121,12 @@
 }
 
 Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
-               DiagnosticsEngine &Diags,
+               DiagnosticsEngine &Diags, std::string Title,
                IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
     : Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode),
       SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None),
       ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
-      DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr),
+      DriverTitle(Title), CCPrintOptionsFilename(nullptr),
       CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr),
       CCCPrintBindings(false), CCPrintOptions(false), CCPrintHeaders(false),
       CCLogDiagnostics(false), CCGenDiagnostics(false),
@@ -1566,6 +1566,14 @@
   if (!ShowHidden)
     ExcludedFlagsBitmask |= HelpHidden;
 
+  if (IsFlangMode()) {
+    ExcludedFlagsBitmask |= options::CLOption;
+    ExcludedFlagsBitmask |= options::CC1AsOption;
+    ExcludedFlagsBitmask |= options::CC1Option;
+    IncludedFlagsBitmask |= options::FlangOption;
+  } else
+    ExcludedFlagsBitmask |= options::FlangOption;
+
   std::string Usage = llvm::formatv("{0} [options] file...", Name).str();
   getOpts().PrintHelp(llvm::outs(), Usage.c_str(), DriverTitle.c_str(),
                       IncludedFlagsBitmask, ExcludedFlagsBitmask,
@@ -1573,9 +1581,15 @@
 }
 
 void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
-  // FIXME: The following handlers should use a callback mechanism, we don't
-  // know what the client would like to do.
-  OS << getClangFullVersion() << '\n';
+  if (IsFlangMode()) {
+    // OS << "Flang experimental driver (falang-new)" << '\n';
+    // return;
+    OS << getClangToolFullVersion("flang-new") << '\n';
+  } else {
+    // FIXME: The following handlers should use a callback mechanism, we don't
+    // know what the client would like to do.
+    OS << getClangFullVersion() << '\n';
+  }
   const ToolChain &TC = C.getDefaultToolChain();
   OS << "Target: " << TC.getTripleString() << '\n';
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -56,6 +56,10 @@
 // be used), add this flag.
 def LinkOption : OptionFlag;
 
+// FlangOption - This is considered a "core" Flang option, available in
+// flang mode.
+def FlangOption : OptionFlag;
+
 // A short name to show in documentation. The name will be interpreted as rST.
 class DocName<string name> { string DocName = name; }
 
@@ -2069,7 +2073,7 @@
     Flags<[DriverOption]>,
     HelpText<"Restore the default behavior of not embedding source text in DWARF debug sections">;
 def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
-def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption]>,
+def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption, FlangOption]>,
   HelpText<"Display available options">;
 def ibuiltininc : Flag<["-"], "ibuiltininc">,
   HelpText<"Enable builtin #include directories even when -nostdinc is used "
@@ -3012,7 +3016,7 @@
 def _serialize_diags : Separate<["-", "--"], "serialize-diagnostics">, Flags<[DriverOption]>,
   HelpText<"Serialize compiler diagnostics to a file">;
 // We give --version different semantics from -version.
-def _version : Flag<["--"], "version">, Flags<[CoreOption, CC1Option]>,
+def _version : Flag<["--"], "version">, Flags<[CoreOption, CC1Option, FlangOption]>,
   HelpText<"Print version information">;
 def _signed_char : Flag<["--"], "signed-char">, Alias<fsigned_char>;
 def _std : Separate<["--"], "std">, Alias<std_EQ>;
Index: clang/include/clang/Driver/Options.h
===================================================================
--- clang/include/clang/Driver/Options.h
+++ clang/include/clang/Driver/Options.h
@@ -34,7 +34,8 @@
   CC1AsOption = (1 << 11),
   NoDriverOption = (1 << 12),
   LinkOption = (1 << 13),
-  Ignored = (1 << 14),
+  FlangOption = (1 << 14),
+  Ignored = (1 << 15),
 };
 
 enum ID {
Index: clang/include/clang/Driver/Driver.h
===================================================================
--- clang/include/clang/Driver/Driver.h
+++ clang/include/clang/Driver/Driver.h
@@ -301,7 +301,7 @@
                                       StringRef CustomResourceDir = "");
 
   Driver(StringRef ClangExecutable, StringRef TargetTriple,
-         DiagnosticsEngine &Diags,
+         DiagnosticsEngine &Diags, std::string Title = "clang LLVM compiler",
          IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
 
   /// @name Accessors
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to