1 //===- unittests/Frontend/OutputStreamTest.cpp --- FrontendAction tests --===//
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
7 //===----------------------------------------------------------------------===//
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 "llvm/Support/VirtualFileSystem.h"
17 #include "gtest/gtest.h"
20 using namespace clang
;
21 using namespace clang::frontend
;
25 TEST(FrontendOutputTests
, TestOutputStream
) {
26 auto Invocation
= std::make_shared
<CompilerInvocation
>();
27 Invocation
->getPreprocessorOpts().addRemappedFile(
28 "test.cc", MemoryBuffer::getMemBuffer("").release());
29 Invocation
->getFrontendOpts().Inputs
.push_back(
30 FrontendInputFile("test.cc", Language::CXX
));
31 Invocation
->getFrontendOpts().ProgramAction
= EmitBC
;
32 Invocation
->getTargetOpts().Triple
= "i386-unknown-linux-gnu";
33 CompilerInstance Compiler
;
35 SmallVector
<char, 256> IRBuffer
;
36 std::unique_ptr
<raw_pwrite_stream
> IRStream(
37 new raw_svector_ostream(IRBuffer
));
39 Compiler
.setOutputStream(std::move(IRStream
));
40 Compiler
.setInvocation(std::move(Invocation
));
41 Compiler
.createDiagnostics(*llvm::vfs::getRealFileSystem());
43 bool Success
= ExecuteCompilerInvocation(&Compiler
);
45 EXPECT_TRUE(!IRBuffer
.empty());
46 EXPECT_TRUE(StringRef(IRBuffer
.data()).starts_with("BC"));
49 TEST(FrontendOutputTests
, TestVerboseOutputStreamShared
) {
50 auto Invocation
= std::make_shared
<CompilerInvocation
>();
51 Invocation
->getPreprocessorOpts().addRemappedFile(
52 "test.cc", MemoryBuffer::getMemBuffer("invalid").release());
53 Invocation
->getFrontendOpts().Inputs
.push_back(
54 FrontendInputFile("test.cc", Language::CXX
));
55 Invocation
->getFrontendOpts().ProgramAction
= EmitBC
;
56 Invocation
->getTargetOpts().Triple
= "i386-unknown-linux-gnu";
57 CompilerInstance Compiler
;
59 std::string VerboseBuffer
;
60 raw_string_ostream
VerboseStream(VerboseBuffer
);
62 Compiler
.setOutputStream(std::make_unique
<raw_null_ostream
>());
63 Compiler
.setInvocation(std::move(Invocation
));
64 IntrusiveRefCntPtr
<DiagnosticOptions
> DiagOpts
= new DiagnosticOptions();
65 Compiler
.createDiagnostics(
66 *llvm::vfs::getRealFileSystem(),
67 new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts
), true);
68 Compiler
.setVerboseOutputStream(VerboseStream
);
70 bool Success
= ExecuteCompilerInvocation(&Compiler
);
71 EXPECT_FALSE(Success
);
72 EXPECT_TRUE(!VerboseBuffer
.empty());
73 EXPECT_TRUE(StringRef(VerboseBuffer
.data()).contains("errors generated"));
76 TEST(FrontendOutputTests
, TestVerboseOutputStreamOwned
) {
77 std::string VerboseBuffer
;
80 auto Invocation
= std::make_shared
<CompilerInvocation
>();
81 Invocation
->getPreprocessorOpts().addRemappedFile(
82 "test.cc", MemoryBuffer::getMemBuffer("invalid").release());
83 Invocation
->getFrontendOpts().Inputs
.push_back(
84 FrontendInputFile("test.cc", Language::CXX
));
85 Invocation
->getFrontendOpts().ProgramAction
= EmitBC
;
86 Invocation
->getTargetOpts().Triple
= "i386-unknown-linux-gnu";
87 CompilerInstance Compiler
;
89 std::unique_ptr
<raw_ostream
> VerboseStream
=
90 std::make_unique
<raw_string_ostream
>(VerboseBuffer
);
92 Compiler
.setOutputStream(std::make_unique
<raw_null_ostream
>());
93 Compiler
.setInvocation(std::move(Invocation
));
94 IntrusiveRefCntPtr
<DiagnosticOptions
> DiagOpts
= new DiagnosticOptions();
95 Compiler
.createDiagnostics(
96 *llvm::vfs::getRealFileSystem(),
97 new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts
), true);
98 Compiler
.setVerboseOutputStream(std::move(VerboseStream
));
100 Success
= ExecuteCompilerInvocation(&Compiler
);
102 EXPECT_FALSE(Success
);
103 EXPECT_TRUE(!VerboseBuffer
.empty());
104 EXPECT_TRUE(StringRef(VerboseBuffer
.data()).contains("errors generated"));
107 TEST(FrontendOutputTests
, TestVerboseOutputStreamOwnedNotLeaked
) {
108 CompilerInstance Compiler
;
109 Compiler
.setVerboseOutputStream(std::make_unique
<raw_null_ostream
>());
111 // Trust leak sanitizer bots to catch a leak here.
112 Compiler
.setVerboseOutputStream(llvm::nulls());
115 } // anonymous namespace