xref: /llvm-project/clang/unittests/Frontend/OutputStreamTest.cpp (revision df9a14d7bbf1180e4f1474254c9d7ed6bcb4ce55)
1aba98fc9SAlexey Sotkin //===- unittests/Frontend/OutputStreamTest.cpp --- FrontendAction tests --===//
2aba98fc9SAlexey Sotkin //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6aba98fc9SAlexey Sotkin //
7aba98fc9SAlexey Sotkin //===----------------------------------------------------------------------===//
8aba98fc9SAlexey Sotkin 
909d890d7SRainer Orth #include "clang/Basic/LangStandard.h"
10aba98fc9SAlexey Sotkin #include "clang/CodeGen/BackendUtil.h"
11aba98fc9SAlexey Sotkin #include "clang/CodeGen/CodeGenAction.h"
12aba98fc9SAlexey Sotkin #include "clang/Frontend/CompilerInstance.h"
1387cb734cSScott Linder #include "clang/Frontend/TextDiagnosticPrinter.h"
14aba98fc9SAlexey Sotkin #include "clang/FrontendTool/Utils.h"
15aba98fc9SAlexey Sotkin #include "clang/Lex/PreprocessorOptions.h"
16*df9a14d7SKadir Cetinkaya #include "llvm/Support/VirtualFileSystem.h"
17aba98fc9SAlexey Sotkin #include "gtest/gtest.h"
18aba98fc9SAlexey Sotkin 
19aba98fc9SAlexey Sotkin using namespace llvm;
20aba98fc9SAlexey Sotkin using namespace clang;
21aba98fc9SAlexey Sotkin using namespace clang::frontend;
22aba98fc9SAlexey Sotkin 
23aba98fc9SAlexey Sotkin namespace {
24aba98fc9SAlexey Sotkin 
25aba98fc9SAlexey Sotkin TEST(FrontendOutputTests, TestOutputStream) {
26aba98fc9SAlexey Sotkin   auto Invocation = std::make_shared<CompilerInvocation>();
27aba98fc9SAlexey Sotkin   Invocation->getPreprocessorOpts().addRemappedFile(
28aba98fc9SAlexey Sotkin       "test.cc", MemoryBuffer::getMemBuffer("").release());
29aba98fc9SAlexey Sotkin   Invocation->getFrontendOpts().Inputs.push_back(
3009d890d7SRainer Orth       FrontendInputFile("test.cc", Language::CXX));
312108a974SBenjamin Kramer   Invocation->getFrontendOpts().ProgramAction = EmitBC;
32aba98fc9SAlexey Sotkin   Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
33aba98fc9SAlexey Sotkin   CompilerInstance Compiler;
34aba98fc9SAlexey Sotkin 
35aba98fc9SAlexey Sotkin   SmallVector<char, 256> IRBuffer;
36aba98fc9SAlexey Sotkin   std::unique_ptr<raw_pwrite_stream> IRStream(
37aba98fc9SAlexey Sotkin       new raw_svector_ostream(IRBuffer));
38aba98fc9SAlexey Sotkin 
39aba98fc9SAlexey Sotkin   Compiler.setOutputStream(std::move(IRStream));
40aba98fc9SAlexey Sotkin   Compiler.setInvocation(std::move(Invocation));
41*df9a14d7SKadir Cetinkaya   Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());
42aba98fc9SAlexey Sotkin 
43aba98fc9SAlexey Sotkin   bool Success = ExecuteCompilerInvocation(&Compiler);
44aba98fc9SAlexey Sotkin   EXPECT_TRUE(Success);
45aba98fc9SAlexey Sotkin   EXPECT_TRUE(!IRBuffer.empty());
46f3dcc235SKazu Hirata   EXPECT_TRUE(StringRef(IRBuffer.data()).starts_with("BC"));
47aba98fc9SAlexey Sotkin }
4887cb734cSScott Linder 
4987cb734cSScott Linder TEST(FrontendOutputTests, TestVerboseOutputStreamShared) {
5087cb734cSScott Linder   auto Invocation = std::make_shared<CompilerInvocation>();
5187cb734cSScott Linder   Invocation->getPreprocessorOpts().addRemappedFile(
5287cb734cSScott Linder       "test.cc", MemoryBuffer::getMemBuffer("invalid").release());
5387cb734cSScott Linder   Invocation->getFrontendOpts().Inputs.push_back(
5487cb734cSScott Linder       FrontendInputFile("test.cc", Language::CXX));
552108a974SBenjamin Kramer   Invocation->getFrontendOpts().ProgramAction = EmitBC;
5687cb734cSScott Linder   Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
5787cb734cSScott Linder   CompilerInstance Compiler;
5887cb734cSScott Linder 
5987cb734cSScott Linder   std::string VerboseBuffer;
6087cb734cSScott Linder   raw_string_ostream VerboseStream(VerboseBuffer);
6187cb734cSScott Linder 
62ecc99910SBenjamin Kramer   Compiler.setOutputStream(std::make_unique<raw_null_ostream>());
6387cb734cSScott Linder   Compiler.setInvocation(std::move(Invocation));
6487cb734cSScott Linder   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
6587cb734cSScott Linder   Compiler.createDiagnostics(
66*df9a14d7SKadir Cetinkaya       *llvm::vfs::getRealFileSystem(),
6787cb734cSScott Linder       new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
6887cb734cSScott Linder   Compiler.setVerboseOutputStream(VerboseStream);
6987cb734cSScott Linder 
7087cb734cSScott Linder   bool Success = ExecuteCompilerInvocation(&Compiler);
7187cb734cSScott Linder   EXPECT_FALSE(Success);
72918972bdSJOE1994   EXPECT_TRUE(!VerboseBuffer.empty());
7387cb734cSScott Linder   EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated"));
7487cb734cSScott Linder }
7587cb734cSScott Linder 
7687cb734cSScott Linder TEST(FrontendOutputTests, TestVerboseOutputStreamOwned) {
7787cb734cSScott Linder   std::string VerboseBuffer;
7887cb734cSScott Linder   bool Success;
7987cb734cSScott Linder   {
8087cb734cSScott Linder     auto Invocation = std::make_shared<CompilerInvocation>();
8187cb734cSScott Linder     Invocation->getPreprocessorOpts().addRemappedFile(
8287cb734cSScott Linder         "test.cc", MemoryBuffer::getMemBuffer("invalid").release());
8387cb734cSScott Linder     Invocation->getFrontendOpts().Inputs.push_back(
8487cb734cSScott Linder         FrontendInputFile("test.cc", Language::CXX));
8587cb734cSScott Linder     Invocation->getFrontendOpts().ProgramAction = EmitBC;
8687cb734cSScott Linder     Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
8787cb734cSScott Linder     CompilerInstance Compiler;
8887cb734cSScott Linder 
8987cb734cSScott Linder     std::unique_ptr<raw_ostream> VerboseStream =
9087cb734cSScott Linder         std::make_unique<raw_string_ostream>(VerboseBuffer);
9187cb734cSScott Linder 
92ecc99910SBenjamin Kramer     Compiler.setOutputStream(std::make_unique<raw_null_ostream>());
9387cb734cSScott Linder     Compiler.setInvocation(std::move(Invocation));
9487cb734cSScott Linder     IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
9587cb734cSScott Linder     Compiler.createDiagnostics(
96*df9a14d7SKadir Cetinkaya         *llvm::vfs::getRealFileSystem(),
9787cb734cSScott Linder         new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
9887cb734cSScott Linder     Compiler.setVerboseOutputStream(std::move(VerboseStream));
9987cb734cSScott Linder 
10087cb734cSScott Linder     Success = ExecuteCompilerInvocation(&Compiler);
10187cb734cSScott Linder   }
10287cb734cSScott Linder   EXPECT_FALSE(Success);
10387cb734cSScott Linder   EXPECT_TRUE(!VerboseBuffer.empty());
10487cb734cSScott Linder   EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated"));
10587cb734cSScott Linder }
106b61f288aSDuncan P. N. Exon Smith 
1078afabff6SDuncan P. N. Exon Smith TEST(FrontendOutputTests, TestVerboseOutputStreamOwnedNotLeaked) {
1088afabff6SDuncan P. N. Exon Smith   CompilerInstance Compiler;
1098afabff6SDuncan P. N. Exon Smith   Compiler.setVerboseOutputStream(std::make_unique<raw_null_ostream>());
1108afabff6SDuncan P. N. Exon Smith 
1118afabff6SDuncan P. N. Exon Smith   // Trust leak sanitizer bots to catch a leak here.
1128afabff6SDuncan P. N. Exon Smith   Compiler.setVerboseOutputStream(llvm::nulls());
1138afabff6SDuncan P. N. Exon Smith }
1148afabff6SDuncan P. N. Exon Smith 
115b61f288aSDuncan P. N. Exon Smith } // anonymous namespace
116