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