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 "gtest/gtest.h"
19 using namespace clang
;
20 using namespace clang::frontend
;
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
;
34 SmallVector
<char, 256> IRBuffer
;
35 std::unique_ptr
<raw_pwrite_stream
> IRStream(
36 new raw_svector_ostream(IRBuffer
));
38 Compiler
.setOutputStream(std::move(IRStream
));
39 Compiler
.setInvocation(std::move(Invocation
));
40 Compiler
.createDiagnostics();
42 bool Success
= ExecuteCompilerInvocation(&Compiler
);
44 EXPECT_TRUE(!IRBuffer
.empty());
45 EXPECT_TRUE(StringRef(IRBuffer
.data()).startswith("BC"));
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
;
58 std::string VerboseBuffer
;
59 raw_string_ostream
VerboseStream(VerboseBuffer
);
61 Compiler
.setOutputStream(std::make_unique
<raw_null_ostream
>());
62 Compiler
.setInvocation(std::move(Invocation
));
63 IntrusiveRefCntPtr
<DiagnosticOptions
> DiagOpts
= new DiagnosticOptions();
64 Compiler
.createDiagnostics(
65 new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts
), true);
66 Compiler
.setVerboseOutputStream(VerboseStream
);
68 bool Success
= ExecuteCompilerInvocation(&Compiler
);
69 EXPECT_FALSE(Success
);
70 EXPECT_TRUE(!VerboseStream
.str().empty());
71 EXPECT_TRUE(StringRef(VerboseBuffer
.data()).contains("errors generated"));
74 TEST(FrontendOutputTests
, TestVerboseOutputStreamOwned
) {
75 std::string VerboseBuffer
;
78 auto Invocation
= std::make_shared
<CompilerInvocation
>();
79 Invocation
->getPreprocessorOpts().addRemappedFile(
80 "test.cc", MemoryBuffer::getMemBuffer("invalid").release());
81 Invocation
->getFrontendOpts().Inputs
.push_back(
82 FrontendInputFile("test.cc", Language::CXX
));
83 Invocation
->getFrontendOpts().ProgramAction
= EmitBC
;
84 Invocation
->getTargetOpts().Triple
= "i386-unknown-linux-gnu";
85 CompilerInstance Compiler
;
87 std::unique_ptr
<raw_ostream
> VerboseStream
=
88 std::make_unique
<raw_string_ostream
>(VerboseBuffer
);
90 Compiler
.setOutputStream(std::make_unique
<raw_null_ostream
>());
91 Compiler
.setInvocation(std::move(Invocation
));
92 IntrusiveRefCntPtr
<DiagnosticOptions
> DiagOpts
= new DiagnosticOptions();
93 Compiler
.createDiagnostics(
94 new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts
), true);
95 Compiler
.setVerboseOutputStream(std::move(VerboseStream
));
97 Success
= ExecuteCompilerInvocation(&Compiler
);
99 EXPECT_FALSE(Success
);
100 EXPECT_TRUE(!VerboseBuffer
.empty());
101 EXPECT_TRUE(StringRef(VerboseBuffer
.data()).contains("errors generated"));
104 TEST(FrontendOutputTests
, TestVerboseOutputStreamOwnedNotLeaked
) {
105 CompilerInstance Compiler
;
106 Compiler
.setVerboseOutputStream(std::make_unique
<raw_null_ostream
>());
108 // Trust leak sanitizer bots to catch a leak here.
109 Compiler
.setVerboseOutputStream(llvm::nulls());
112 } // anonymous namespace