1257b2971SCaroline Concatto //===- unittests/Frontend/CompilerInstanceTest.cpp - CI tests -------------===//
2257b2971SCaroline Concatto //
3257b2971SCaroline Concatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4257b2971SCaroline Concatto // See https://llvm.org/LICENSE.txt for license information.
5257b2971SCaroline Concatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6257b2971SCaroline Concatto //
7257b2971SCaroline Concatto //===----------------------------------------------------------------------===//
8257b2971SCaroline Concatto 
9257b2971SCaroline Concatto #include "flang/Frontend/CompilerInstance.h"
108d51d37eSAndrzej Warzynski #include "flang/Frontend/TextDiagnosticPrinter.h"
11257b2971SCaroline Concatto #include "clang/Basic/DiagnosticOptions.h"
12b564b12bSAndrzej Warzynski #include "llvm/Support/FileSystem.h"
13257b2971SCaroline Concatto 
1410c94d8cSAndrzej Warzynski #include "gtest/gtest.h"
1510c94d8cSAndrzej Warzynski 
16257b2971SCaroline Concatto using namespace llvm;
17257b2971SCaroline Concatto using namespace Fortran::frontend;
18257b2971SCaroline Concatto 
19257b2971SCaroline Concatto namespace {
20257b2971SCaroline Concatto 
TEST(CompilerInstance,SanityCheckForFileManager)214c5906cfSCaroline Concatto TEST(CompilerInstance, SanityCheckForFileManager) {
224c5906cfSCaroline Concatto   const char *inputSource = "InputSourceFile";
234c5906cfSCaroline Concatto   std::string inputFile = "buffer-file-test.f";
244c5906cfSCaroline Concatto   std::error_code ec;
254c5906cfSCaroline Concatto 
264c5906cfSCaroline Concatto   // 1. Create the input file for the file manager
274c5906cfSCaroline Concatto   // AllSources (which is used to manage files inside every compiler instance),
284c5906cfSCaroline Concatto   // works with paths. This means that it requires a physical file. Create one.
294c5906cfSCaroline Concatto   std::unique_ptr<llvm::raw_fd_ostream> os{
304c5906cfSCaroline Concatto       new llvm::raw_fd_ostream(inputFile, ec, llvm::sys::fs::OF_None)};
314c5906cfSCaroline Concatto   if (ec)
324c5906cfSCaroline Concatto     FAIL() << "Failed to create the input file";
334c5906cfSCaroline Concatto 
344c5906cfSCaroline Concatto   // Populate the input file with the pre-defined input and flush it.
354c5906cfSCaroline Concatto   *(os) << inputSource;
364c5906cfSCaroline Concatto   os.reset();
374c5906cfSCaroline Concatto 
384c5906cfSCaroline Concatto   // Get the path of the input file
394c5906cfSCaroline Concatto   llvm::SmallString<64> cwd;
404c5906cfSCaroline Concatto   if (std::error_code ec = llvm::sys::fs::current_path(cwd))
414c5906cfSCaroline Concatto     FAIL() << "Failed to obtain the current working directory";
424c5906cfSCaroline Concatto   std::string testFilePath(cwd.c_str());
434c5906cfSCaroline Concatto   testFilePath += "/" + inputFile;
444c5906cfSCaroline Concatto 
454c5906cfSCaroline Concatto   // 2. Set up CompilerInstance (i.e. specify the input file)
464c5906cfSCaroline Concatto   std::string buf;
47*1e462fafSAndrzej Warzynski   llvm::raw_string_ostream errorStream{buf};
484c5906cfSCaroline Concatto   CompilerInstance compInst;
494c5906cfSCaroline Concatto   const Fortran::parser::SourceFile *sf =
50*1e462fafSAndrzej Warzynski       compInst.getAllSources().Open(testFilePath, errorStream);
514c5906cfSCaroline Concatto 
524c5906cfSCaroline Concatto   // 3. Verify the content of the input file
534c5906cfSCaroline Concatto   // This is just a sanity check to make sure that CompilerInstance is capable
544c5906cfSCaroline Concatto   // of reading input files.
554c5906cfSCaroline Concatto   llvm::ArrayRef<char> fileContent = sf->content();
564c5906cfSCaroline Concatto   EXPECT_FALSE(fileContent.size() == 0);
574c5906cfSCaroline Concatto   EXPECT_TRUE(
584c5906cfSCaroline Concatto       llvm::StringRef(fileContent.data()).startswith("InputSourceFile"));
594c5906cfSCaroline Concatto 
604c5906cfSCaroline Concatto   // 4. Delete the test file
614c5906cfSCaroline Concatto   ec = llvm::sys::fs::remove(inputFile);
624c5906cfSCaroline Concatto   if (ec)
634c5906cfSCaroline Concatto     FAIL() << "Failed to delete the test file";
644c5906cfSCaroline Concatto }
654c5906cfSCaroline Concatto 
TEST(CompilerInstance,AllowDiagnosticLogWithUnownedDiagnosticConsumer)66257b2971SCaroline Concatto TEST(CompilerInstance, AllowDiagnosticLogWithUnownedDiagnosticConsumer) {
67257b2971SCaroline Concatto   // 1. Set-up a basic DiagnosticConsumer
68257b2971SCaroline Concatto   std::string diagnosticOutput;
69257b2971SCaroline Concatto   llvm::raw_string_ostream diagnosticsOS(diagnosticOutput);
708d51d37eSAndrzej Warzynski   auto diagPrinter = std::make_unique<Fortran::frontend::TextDiagnosticPrinter>(
71257b2971SCaroline Concatto       diagnosticsOS, new clang::DiagnosticOptions());
72257b2971SCaroline Concatto 
73257b2971SCaroline Concatto   // 2. Create a CompilerInstance (to manage a DiagnosticEngine)
74257b2971SCaroline Concatto   CompilerInstance compInst;
75257b2971SCaroline Concatto 
76257b2971SCaroline Concatto   // 3. Set-up DiagnosticOptions
77257b2971SCaroline Concatto   auto diagOpts = new clang::DiagnosticOptions();
78257b2971SCaroline Concatto   // Tell the diagnostics engine to emit the diagnostic log to STDERR. This
79257b2971SCaroline Concatto   // ensures that a chained diagnostic consumer is created so that the test can
80257b2971SCaroline Concatto   // exercise the unowned diagnostic consumer in a chained consumer.
81257b2971SCaroline Concatto   diagOpts->DiagnosticLogFile = "-";
82257b2971SCaroline Concatto 
83257b2971SCaroline Concatto   // 4. Create a DiagnosticEngine with an unowned consumer
84257b2971SCaroline Concatto   IntrusiveRefCntPtr<clang::DiagnosticsEngine> diags =
85*1e462fafSAndrzej Warzynski       compInst.createDiagnostics(diagOpts, diagPrinter.get(),
86257b2971SCaroline Concatto           /*ShouldOwnClient=*/false);
87257b2971SCaroline Concatto 
88257b2971SCaroline Concatto   // 5. Report a diagnostic
89257b2971SCaroline Concatto   diags->Report(clang::diag::err_expected) << "no crash";
90257b2971SCaroline Concatto 
91257b2971SCaroline Concatto   // 6. Verify that the reported diagnostic wasn't lost and did end up in the
92257b2971SCaroline Concatto   // output stream
93257b2971SCaroline Concatto   ASSERT_EQ(diagnosticsOS.str(), "error: expected no crash\n");
94257b2971SCaroline Concatto }
95257b2971SCaroline Concatto } // namespace
96