• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- unittests/Frontend/OutputStreamTest.cpp --- FrontendAction tests --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "gtest/gtest.h"
10 #include "flang/Frontend/CompilerInstance.h"
11 #include "flang/Frontend/CompilerInvocation.h"
12 #include "flang/Frontend/FrontendOptions.h"
13 #include "flang/FrontendTool/Utils.h"
14 #include "llvm/Support/FileSystem.h"
15 #include "llvm/Support/raw_ostream.h"
16 
17 using namespace Fortran::frontend;
18 
19 namespace {
20 
TEST(FrontendAction,TestInputOutputTestAction)21 TEST(FrontendAction, TestInputOutputTestAction) {
22   std::string inputFile = "io-file-test.f";
23   std::error_code ec;
24 
25   // 1. Create the input file for the file manager
26   // AllSources (which is used to manage files inside every compiler instance),
27   // works with paths. This means that it requires a physical file. Create one.
28   std::unique_ptr<llvm::raw_fd_ostream> os{
29       new llvm::raw_fd_ostream(inputFile, ec, llvm::sys::fs::OF_None)};
30   if (ec)
31     FAIL() << "Failed to create the input file";
32 
33   // Populate the input file with the pre-defined input and flush it.
34   *(os) << "End Program arithmetic";
35   os.reset();
36 
37   // Get the path of the input file
38   llvm::SmallString<64> cwd;
39   if (std::error_code ec = llvm::sys::fs::current_path(cwd))
40     FAIL() << "Failed to obtain the current working directory";
41   std::string testFilePath(cwd.c_str());
42   testFilePath += "/" + inputFile;
43 
44   // 2. Prepare the compiler (CompilerInvocation + CompilerInstance)
45   CompilerInstance compInst;
46   compInst.CreateDiagnostics();
47   auto invocation = std::make_shared<CompilerInvocation>();
48   invocation->frontendOpts().programAction_ = InputOutputTest;
49   compInst.set_invocation(std::move(invocation));
50   compInst.frontendOpts().inputs_.push_back(
51       FrontendInputFile(/*File=*/testFilePath, Language::Fortran));
52 
53   // 3. Set-up the output stream. Using output buffer wrapped as an output
54   // stream, as opposed to an actual file (or a file descriptor).
55   llvm::SmallVector<char, 256> outputFileBuffer;
56   std::unique_ptr<llvm::raw_pwrite_stream> outputFileStream(
57       new llvm::raw_svector_ostream(outputFileBuffer));
58   compInst.set_outputStream(std::move(outputFileStream));
59 
60   // 4. Run the earlier defined FrontendAction
61   bool success = ExecuteCompilerInvocation(&compInst);
62 
63   EXPECT_TRUE(success);
64   EXPECT_TRUE(!outputFileBuffer.empty());
65   EXPECT_TRUE(llvm::StringRef(outputFileBuffer.data())
66                   .startswith("End Program arithmetic"));
67 
68   // 5. Clear the input and the output files. Since we used an output buffer,
69   // there are no physical output files to delete.
70   ec = llvm::sys::fs::remove(inputFile);
71   if (ec)
72     FAIL() << "Failed to delete the test file";
73 
74   compInst.ClearOutputFiles(/*EraseFiles=*/false);
75 }
76 } // namespace
77