forked from OSchip/llvm-project
[Clang] Add VerboseOutputStream to CompilerInstance
Remove one instance of a hardcoded output stream in CompilerInstance::ExecuteAction. There are still other cases of output being hard-coded to standard streams in ExecuteCompilerInvocation, but this patch covers the case when no flags like -version or -help are passed, namely the "X warnings and Y errors generated." diagnostic. Differential Revision: https://reviews.llvm.org/D53768 llvm-svn: 375442
This commit is contained in:
parent
ca7f4d8b85
commit
87cb734c04
|
@ -155,6 +155,12 @@ class CompilerInstance : public ModuleLoader {
|
|||
/// One or more modules failed to build.
|
||||
bool ModuleBuildFailed = false;
|
||||
|
||||
/// The stream for verbose output if owned, otherwise nullptr.
|
||||
std::unique_ptr<raw_ostream> OwnedVerboseOutputStream;
|
||||
|
||||
/// The stream for verbose output.
|
||||
raw_ostream *VerboseOutputStream = &llvm::errs();
|
||||
|
||||
/// Holds information about the output file.
|
||||
///
|
||||
/// If TempFilename is not empty we must rename it to Filename at the end.
|
||||
|
@ -217,9 +223,6 @@ public:
|
|||
/// \param Act - The action to execute.
|
||||
/// \return - True on success.
|
||||
//
|
||||
// FIXME: This function should take the stream to write any debugging /
|
||||
// verbose output to as an argument.
|
||||
//
|
||||
// FIXME: Eliminate the llvm_shutdown requirement, that should either be part
|
||||
// of the context or else not CompilerInstance specific.
|
||||
bool ExecuteAction(FrontendAction &Act);
|
||||
|
@ -349,6 +352,21 @@ public:
|
|||
return *Diagnostics->getClient();
|
||||
}
|
||||
|
||||
/// }
|
||||
/// @name VerboseOutputStream
|
||||
/// }
|
||||
|
||||
/// Replace the current stream for verbose output.
|
||||
void setVerboseOutputStream(raw_ostream &Value);
|
||||
|
||||
/// Replace the current stream for verbose output.
|
||||
void setVerboseOutputStream(std::unique_ptr<raw_ostream> Value);
|
||||
|
||||
/// Get the current stream for verbose output.
|
||||
raw_ostream &getVerboseOutputStream() {
|
||||
return *VerboseOutputStream;
|
||||
}
|
||||
|
||||
/// }
|
||||
/// @name Target Info
|
||||
/// {
|
||||
|
|
|
@ -84,6 +84,16 @@ void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
|
|||
Diagnostics = Value;
|
||||
}
|
||||
|
||||
void CompilerInstance::setVerboseOutputStream(raw_ostream &Value) {
|
||||
OwnedVerboseOutputStream.release();
|
||||
VerboseOutputStream = &Value;
|
||||
}
|
||||
|
||||
void CompilerInstance::setVerboseOutputStream(std::unique_ptr<raw_ostream> Value) {
|
||||
OwnedVerboseOutputStream.swap(Value);
|
||||
VerboseOutputStream = OwnedVerboseOutputStream.get();
|
||||
}
|
||||
|
||||
void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }
|
||||
void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
|
||||
|
||||
|
@ -896,9 +906,7 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
|
|||
// DesiredStackSpace available.
|
||||
noteBottomOfStack();
|
||||
|
||||
// FIXME: Take this as an argument, once all the APIs we used have moved to
|
||||
// taking it as an input instead of hard-coding llvm::errs.
|
||||
raw_ostream &OS = llvm::errs();
|
||||
raw_ostream &OS = getVerboseOutputStream();
|
||||
|
||||
if (!Act.PrepareToExecute(*this))
|
||||
return false;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "clang/CodeGen/BackendUtil.h"
|
||||
#include "clang/CodeGen/CodeGenAction.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
#include "clang/FrontendTool/Utils.h"
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
@ -43,4 +44,58 @@ TEST(FrontendOutputTests, TestOutputStream) {
|
|||
EXPECT_TRUE(!IRBuffer.empty());
|
||||
EXPECT_TRUE(StringRef(IRBuffer.data()).startswith("BC"));
|
||||
}
|
||||
|
||||
TEST(FrontendOutputTests, TestVerboseOutputStreamShared) {
|
||||
auto Invocation = std::make_shared<CompilerInvocation>();
|
||||
Invocation->getPreprocessorOpts().addRemappedFile(
|
||||
"test.cc", MemoryBuffer::getMemBuffer("invalid").release());
|
||||
Invocation->getFrontendOpts().Inputs.push_back(
|
||||
FrontendInputFile("test.cc", Language::CXX));
|
||||
Invocation->getFrontendOpts().ProgramAction = EmitBC;
|
||||
Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
|
||||
CompilerInstance Compiler;
|
||||
|
||||
std::string VerboseBuffer;
|
||||
raw_string_ostream VerboseStream(VerboseBuffer);
|
||||
|
||||
Compiler.setInvocation(std::move(Invocation));
|
||||
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
|
||||
Compiler.createDiagnostics(
|
||||
new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
|
||||
Compiler.setVerboseOutputStream(VerboseStream);
|
||||
|
||||
bool Success = ExecuteCompilerInvocation(&Compiler);
|
||||
EXPECT_FALSE(Success);
|
||||
EXPECT_TRUE(!VerboseStream.str().empty());
|
||||
EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated"));
|
||||
}
|
||||
|
||||
TEST(FrontendOutputTests, TestVerboseOutputStreamOwned) {
|
||||
std::string VerboseBuffer;
|
||||
bool Success;
|
||||
{
|
||||
auto Invocation = std::make_shared<CompilerInvocation>();
|
||||
Invocation->getPreprocessorOpts().addRemappedFile(
|
||||
"test.cc", MemoryBuffer::getMemBuffer("invalid").release());
|
||||
Invocation->getFrontendOpts().Inputs.push_back(
|
||||
FrontendInputFile("test.cc", Language::CXX));
|
||||
Invocation->getFrontendOpts().ProgramAction = EmitBC;
|
||||
Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
|
||||
CompilerInstance Compiler;
|
||||
|
||||
std::unique_ptr<raw_ostream> VerboseStream =
|
||||
std::make_unique<raw_string_ostream>(VerboseBuffer);
|
||||
|
||||
Compiler.setInvocation(std::move(Invocation));
|
||||
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
|
||||
Compiler.createDiagnostics(
|
||||
new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
|
||||
Compiler.setVerboseOutputStream(std::move(VerboseStream));
|
||||
|
||||
Success = ExecuteCompilerInvocation(&Compiler);
|
||||
}
|
||||
EXPECT_FALSE(Success);
|
||||
EXPECT_TRUE(!VerboseBuffer.empty());
|
||||
EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue