diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -47,31 +47,36 @@ } void InputOutputTestAction::ExecuteAction() { - // Get the name of the file from FrontendInputFile current. - std::string path{GetCurrentFileOrBufferName()}; + CompilerInstance &ci = instance(); + + // Create a stream for errors std::string buf; llvm::raw_string_ostream error_stream{buf}; - bool binaryMode = true; - // Set/store input file info into CompilerInstance. - CompilerInstance &ci = instance(); + // Read the input file Fortran::parser::AllSources &allSources{ci.allSources()}; + std::string path{GetCurrentFileOrBufferName()}; const Fortran::parser::SourceFile *sf; - sf = allSources.Open(path, error_stream); + if (path == "-") + sf = allSources.ReadStandardInput(error_stream); + else + sf = allSources.Open(path, error_stream); llvm::ArrayRef fileContent = sf->content(); - // Output file descriptor to receive the content of input file. + // Output file descriptor to receive the contents of the input file. std::unique_ptr os; - // Do not write on the output file if using outputStream_. - if (ci.IsOutputStreamNull()) { + // Copy the contents from the input file to the output file + if (!ci.IsOutputStreamNull()) { + // An output stream (outputStream_) was set earlier + ci.WriteOutputStream(fileContent.data()); + } else { + // No pre-set output stream - create an output file os = ci.CreateDefaultOutputFile( - binaryMode, GetCurrentFileOrBufferName(), "txt"); + /*binary=*/true, GetCurrentFileOrBufferName(), "txt"); if (!os) return; (*os) << fileContent.data(); - } else { - ci.WriteOutputStream(fileContent.data()); } } diff --git a/flang/test/Flang-Driver/input-from-stdin.f90 b/flang/test/Flang-Driver/input-from-stdin.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Flang-Driver/input-from-stdin.f90 @@ -0,0 +1,44 @@ +! Verify that reading from stdin works as expected + +! REQUIRES: new-flang-driver + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! TODO: Add support for `flang-new -` +! Currently `bin/flang-new -E -` defaults to `-x c` and e.g. F90 is not allowed +! in `-x ` (see `clang::driver::types::canTypeBeUserSpecified` in +! Types.cpp) + +!--------------------------------------- +! FLANG FRONTEND DRIVER (flang-new -fc1) +!--------------------------------------- +! Test `-test-io` - the driver handles the file I/O for the corresponding action (`InputOutputTestAction`) +! RUN: cat %s | flang-new -fc1 -E | FileCheck %s --check-prefix=PP-NOT-DEFINED +! RUN: cat %s | flang-new -fc1 -DNEW -E | FileCheck %s --check-prefix=PP-DEFINED + +! Test `-E` - the driver relies on the prescanner API for handling file I/O for +! the corresponding action (`PrintPreprocessedAction`) +! RUN: cat %s | flang-new -fc1 -test-io | FileCheck %s --check-prefix=IO --match-full-lines +! RUN: cat %s | flang-new -fc1 -DNEW -test-io | FileCheck %s --check-prefix=IO --match-full-lines + +!------------------------- +! EXPECTED OUTPUT for `-E` +!------------------------- +! PP-NOT-DEFINED: program b +! PP-DEFINED: program a + +!------------------------------- +! EXPECTED OUTPUT for `-test-io` +!------------------------------- +! IO: #ifdef NEW +! IO-NEXT: Program A +! IO-NEXT: #else +! IO-NEXT: Program B +! IO-NEXT: #endif + +#ifdef NEW + Program A +#else + Program B +#endif