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 "clang/Basic/LangStandard.h" 10 #include "clang/CodeGen/BackendUtil.h" 11 #include "clang/CodeGen/CodeGenAction.h" 12 #include "clang/Frontend/CompilerInstance.h" 13 #include "clang/Frontend/TextDiagnosticPrinter.h" 14 #include "clang/FrontendTool/Utils.h" 15 #include "clang/Lex/PreprocessorOptions.h" 16 #include "gtest/gtest.h" 17 18 using namespace llvm; 19 using namespace clang; 20 using namespace clang::frontend; 21 22 namespace { 23 24 TEST(FrontendOutputTests, TestOutputStream) { 25 auto Invocation = std::make_shared<CompilerInvocation>(); 26 Invocation->getPreprocessorOpts().addRemappedFile( 27 "test.cc", MemoryBuffer::getMemBuffer("").release()); 28 Invocation->getFrontendOpts().Inputs.push_back( 29 FrontendInputFile("test.cc", Language::CXX)); 30 Invocation->getFrontendOpts().ProgramAction = EmitBC; 31 Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu"; 32 CompilerInstance Compiler; 33 34 SmallVector<char, 256> IRBuffer; 35 std::unique_ptr<raw_pwrite_stream> IRStream( 36 new raw_svector_ostream(IRBuffer)); 37 38 Compiler.setOutputStream(std::move(IRStream)); 39 Compiler.setInvocation(std::move(Invocation)); 40 Compiler.createDiagnostics(); 41 42 bool Success = ExecuteCompilerInvocation(&Compiler); 43 EXPECT_TRUE(Success); 44 EXPECT_TRUE(!IRBuffer.empty()); 45 EXPECT_TRUE(StringRef(IRBuffer.data()).startswith("BC")); 46 } 47 48 TEST(FrontendOutputTests, TestVerboseOutputStreamShared) { 49 auto Invocation = std::make_shared<CompilerInvocation>(); 50 Invocation->getPreprocessorOpts().addRemappedFile( 51 "test.cc", MemoryBuffer::getMemBuffer("invalid").release()); 52 Invocation->getFrontendOpts().Inputs.push_back( 53 FrontendInputFile("test.cc", Language::CXX)); 54 Invocation->getFrontendOpts().ProgramAction = EmitBC; 55 Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu"; 56 CompilerInstance Compiler; 57 58 std::string VerboseBuffer; 59 raw_string_ostream VerboseStream(VerboseBuffer); 60 61 Compiler.setInvocation(std::move(Invocation)); 62 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 63 Compiler.createDiagnostics( 64 new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true); 65 Compiler.setVerboseOutputStream(VerboseStream); 66 67 bool Success = ExecuteCompilerInvocation(&Compiler); 68 EXPECT_FALSE(Success); 69 EXPECT_TRUE(!VerboseStream.str().empty()); 70 EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated")); 71 } 72 73 TEST(FrontendOutputTests, TestVerboseOutputStreamOwned) { 74 std::string VerboseBuffer; 75 bool Success; 76 { 77 auto Invocation = std::make_shared<CompilerInvocation>(); 78 Invocation->getPreprocessorOpts().addRemappedFile( 79 "test.cc", MemoryBuffer::getMemBuffer("invalid").release()); 80 Invocation->getFrontendOpts().Inputs.push_back( 81 FrontendInputFile("test.cc", Language::CXX)); 82 Invocation->getFrontendOpts().ProgramAction = EmitBC; 83 Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu"; 84 CompilerInstance Compiler; 85 86 std::unique_ptr<raw_ostream> VerboseStream = 87 std::make_unique<raw_string_ostream>(VerboseBuffer); 88 89 Compiler.setInvocation(std::move(Invocation)); 90 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 91 Compiler.createDiagnostics( 92 new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true); 93 Compiler.setVerboseOutputStream(std::move(VerboseStream)); 94 95 Success = ExecuteCompilerInvocation(&Compiler); 96 } 97 EXPECT_FALSE(Success); 98 EXPECT_TRUE(!VerboseBuffer.empty()); 99 EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated")); 100 } 101 } 102