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