[Support] Add convenience functions to WithColor. NFC.

Create convenience functions for printing error, warning and note to
stdout. Previously we had similar functions being used in dsymutil, but
given that this pattern is so common it makes sense to make it available
globally.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@330091 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jonas Devlieghere 2018-04-14 21:36:42 +00:00
parent 851a7606e9
commit 5baab4c85c
8 changed files with 78 additions and 88 deletions

View File

@ -41,6 +41,15 @@ public:
raw_ostream &get() { return OS; }
operator raw_ostream &() { return OS; }
/// Convenience method for printing "error: " to stderr.
static raw_ostream &error();
/// Convenience method for printing "warning: " to stderr.
static raw_ostream &warning();
/// Convenience method for printing "note: " to stderr.
static raw_ostream &note();
};
} // end namespace llvm

View File

@ -59,6 +59,18 @@ WithColor::WithColor(raw_ostream &OS, HighlightColor Color) : OS(OS) {
}
}
raw_ostream &WithColor::error() {
return WithColor(errs(), HighlightColor::Error).get() << "error: ";
}
raw_ostream &WithColor::warning() {
return WithColor(errs(), HighlightColor::Warning).get() << "warning: ";
}
raw_ostream &WithColor::note() {
return WithColor(errs(), HighlightColor::Note).get() << "note: ";
}
WithColor::~WithColor() {
if (colorsEnabled(OS))
OS.resetColor();

View File

@ -9,7 +9,6 @@
#include "DebugMap.h"
#include "BinaryHolder.h"
#include "ErrorReporting.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
@ -23,6 +22,7 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@ -63,10 +63,9 @@ void DebugMapObject::print(raw_ostream &OS) const {
Entries.reserve(Symbols.getNumItems());
for (const auto &Sym : make_range(Symbols.begin(), Symbols.end()))
Entries.push_back(std::make_pair(Sym.getKey(), Sym.getValue()));
llvm::sort(Entries.begin(), Entries.end(),
[](const Entry &LHS, const Entry &RHS) {
return LHS.first < RHS.first;
});
llvm::sort(
Entries.begin(), Entries.end(),
[](const Entry &LHS, const Entry &RHS) { return LHS.first < RHS.first; });
for (const auto &Sym : Entries) {
if (Sym.second.ObjectAddress)
OS << format("\t%016" PRIx64, uint64_t(*Sym.second.ObjectAddress));
@ -243,7 +242,8 @@ MappingTraits<dsymutil::DebugMapObject>::YamlDMO::denormalize(IO &IO) {
sys::path::append(Path, Filename);
auto ErrOrObjectFiles = BinHolder.GetObjectFiles(Path);
if (auto EC = ErrOrObjectFiles.getError()) {
warn_ostream() << "Unable to open " << Path << " " << EC.message() << '\n';
WithColor::warning() << "Unable to open " << Path << " " << EC.message()
<< '\n';
} else if (auto ErrOrObjectFile = BinHolder.Get(Ctxt.BinaryTriple)) {
// Rewrite the object file symbol addresses in the debug map. The YAML
// input is mainly used to test dsymutil without requiring binaries

View File

@ -9,7 +9,6 @@
#include "BinaryHolder.h"
#include "DebugMap.h"
#include "ErrorReporting.h"
#include "MachOUtils.h"
#include "NonRelocatableStringpool.h"
#include "dsymutil.h"
@ -79,6 +78,7 @@
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
@ -587,15 +587,15 @@ static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
} // namespace
void warn(Twine Warning, Twine Context) {
warn_ostream() << Warning + "\n";
WithColor::warning() << Warning + "\n";
if (!Context.isTriviallyEmpty())
note_ostream() << Twine("while processing ") + Context + "\n";
WithColor::note() << Twine("while processing ") + Context + "\n";
}
bool error(Twine Error, Twine Context) {
error_ostream() << Error + "\n";
WithColor::error() << Error + "\n";
if (!Context.isTriviallyEmpty())
note_ostream() << Twine("while processing ") + Context + "\n";
WithColor::note() << Twine("while processing ") + Context + "\n";
return false;
}
@ -2178,7 +2178,7 @@ void DwarfLinker::reportWarning(const Twine &Warning, const DebugMapObject &DMO,
DumpOpts.RecurseDepth = 0;
DumpOpts.Verbose = Options.Verbose;
note_ostream() << " in DIE:\n";
WithColor::note() << " in DIE:\n";
DIE->dump(errs(), 6 /* Indent */, DumpOpts);
}
@ -3999,9 +3999,9 @@ Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
// cache has expired and was pruned by clang. A more adventurous
// dsymutil would invoke clang to rebuild the module now.
if (!ModuleCacheHintDisplayed) {
note_ostream() << "The clang module cache may have expired since "
"this object file was built. Rebuilding the "
"object file will rebuild the module cache.\n";
WithColor::note() << "The clang module cache may have expired since "
"this object file was built. Rebuilding the "
"object file will rebuild the module cache.\n";
ModuleCacheHintDisplayed = true;
}
} else if (isArchive) {
@ -4010,12 +4010,13 @@ Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
// was built on a different machine. We don't want to discourage module
// debugging for convenience libraries within a project though.
if (!ArchiveHintDisplayed) {
note_ostream() << "Linking a static library that was built with "
"-gmodules, but the module cache was not found. "
"Redistributable static libraries should never be "
"built with module debugging enabled. The debug "
"experience will be degraded due to incomplete "
"debug information.\n";
WithColor::note()
<< "Linking a static library that was built with "
"-gmodules, but the module cache was not found. "
"Redistributable static libraries should never be "
"built with module debugging enabled. The debug "
"experience will be degraded due to incomplete "
"debug information.\n";
ArchiveHintDisplayed = true;
}
}
@ -4248,10 +4249,10 @@ bool DwarfLinker::link(const DebugMap &Map) {
Stat.getLastModificationTime() !=
sys::TimePoint<>(LinkContext.DMO.getTimestamp())) {
// Not using the helper here as we can easily stream TimePoint<>.
warn_ostream() << "Timestamp mismatch for " << File << ": "
<< Stat.getLastModificationTime() << " and "
<< sys::TimePoint<>(LinkContext.DMO.getTimestamp())
<< "\n";
WithColor::warning()
<< "Timestamp mismatch for " << File << ": "
<< Stat.getLastModificationTime() << " and "
<< sys::TimePoint<>(LinkContext.DMO.getTimestamp()) << "\n";
continue;
}

View File

@ -1,33 +0,0 @@
//===- ErrorReporting.h - dsymutil error reporting -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_DSYMUTIL_ERRORREPORTING_H
#define LLVM_TOOLS_DSYMUTIL_ERRORREPORTING_H
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
namespace dsymutil {
inline raw_ostream &error_ostream() {
return WithColor(errs(), HighlightColor::Error).get() << "error: ";
}
inline raw_ostream &warn_ostream() {
return WithColor(errs(), HighlightColor::Warning).get() << "warning: ";
}
inline raw_ostream &note_ostream() {
return WithColor(errs(), HighlightColor::Note).get() << "note: ";
}
} // namespace dsymutil
} // end namespace llvm
#endif // LLVM_TOOLS_DSYMUTIL_ERRORREPORTING_H

View File

@ -9,11 +9,11 @@
#include "BinaryHolder.h"
#include "DebugMap.h"
#include "ErrorReporting.h"
#include "MachOUtils.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
namespace {
@ -102,9 +102,10 @@ private:
StringRef BinaryPath);
void Warning(const Twine &Msg, StringRef File = StringRef()) {
warn_ostream() << "("
<< MachOUtils::getArchName(Result->getTriple().getArchName())
<< ") " << File << " " << Msg << "\n";
WithColor::warning() << "("
<< MachOUtils::getArchName(
Result->getTriple().getArchName())
<< ") " << File << " " << Msg << "\n";
if (PaperTrailWarnings) {
if (!File.empty())

View File

@ -10,7 +10,6 @@
#include "MachOUtils.h"
#include "BinaryHolder.h"
#include "DebugMap.h"
#include "ErrorReporting.h"
#include "NonRelocatableStringpool.h"
#include "dsymutil.h"
#include "llvm/MC/MCAsmLayout.h"
@ -21,6 +20,7 @@
#include "llvm/Object/MachO.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
@ -39,7 +39,7 @@ static bool runLipo(StringRef SDKPath, SmallVectorImpl<const char *> &Args) {
Path = sys::findProgramByName("lipo");
if (!Path) {
error_ostream() << "lipo: " << Path.getError().message() << "\n";
WithColor::error() << "lipo: " << Path.getError().message() << "\n";
return false;
}
@ -47,7 +47,7 @@ static bool runLipo(StringRef SDKPath, SmallVectorImpl<const char *> &Args) {
int result =
sys::ExecuteAndWait(*Path, Args.data(), nullptr, {}, 0, 0, &ErrMsg);
if (result) {
error_ostream() << "lipo: " << ErrMsg << "\n";
WithColor::error() << "lipo: " << ErrMsg << "\n";
return false;
}
@ -64,8 +64,8 @@ bool generateUniversalBinary(SmallVectorImpl<ArchAndFilename> &ArchFiles,
StringRef From(ArchFiles.front().Path);
if (sys::fs::rename(From, OutputFileName)) {
if (std::error_code EC = sys::fs::copy_file(From, OutputFileName)) {
error_ostream() << "while copying " << From << " to " << OutputFileName
<< ": " << EC.message() << "\n";
WithColor::error() << "while copying " << From << " to "
<< OutputFileName << ": " << EC.message() << "\n";
return false;
}
sys::fs::remove(From);

View File

@ -15,7 +15,6 @@
#include "dsymutil.h"
#include "CFBundle.h"
#include "DebugMap.h"
#include "ErrorReporting.h"
#include "MachOUtils.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@ -33,6 +32,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/thread.h"
#include <algorithm>
@ -161,8 +161,8 @@ static bool createPlistFile(llvm::StringRef Bin, llvm::StringRef BundleRoot) {
std::error_code EC;
llvm::raw_fd_ostream PL(InfoPlist, EC, llvm::sys::fs::F_Text);
if (EC) {
error_ostream() << "cannot create plist file " << InfoPlist << ": "
<< EC.message() << '\n';
WithColor::error() << "cannot create plist file " << InfoPlist << ": "
<< EC.message() << '\n';
return false;
}
@ -219,8 +219,8 @@ static bool createBundleDir(llvm::StringRef BundleBase) {
llvm::sys::path::append(Bundle, "Contents", "Resources", "DWARF");
if (std::error_code EC = create_directories(Bundle.str(), true,
llvm::sys::fs::perms::all_all)) {
error_ostream() << "cannot create directory " << Bundle << ": "
<< EC.message() << "\n";
WithColor::error() << "cannot create directory " << Bundle << ": "
<< EC.message() << "\n";
return false;
}
return true;
@ -228,8 +228,8 @@ static bool createBundleDir(llvm::StringRef BundleBase) {
static bool verify(llvm::StringRef OutputFile, llvm::StringRef Arch) {
if (OutputFile == "-") {
warn_ostream() << "verification skipped for " << Arch
<< "because writing to stdout.\n";
WithColor::warning() << "verification skipped for " << Arch
<< "because writing to stdout.\n";
return true;
}
@ -247,7 +247,7 @@ static bool verify(llvm::StringRef OutputFile, llvm::StringRef Arch) {
DIDumpOptions DumpOpts;
bool success = DICtx->verify(os, DumpOpts.noImplicitRecursion());
if (!success)
error_ostream() << "verification failed for " << Arch << '\n';
WithColor::error() << "verification failed for " << Arch << '\n';
return success;
}
@ -413,7 +413,7 @@ int main(int argc, char **argv) {
auto OptionsOrErr = getOptions();
if (!OptionsOrErr) {
error_ostream() << toString(OptionsOrErr.takeError());
WithColor::error() << toString(OptionsOrErr.takeError());
return 1;
}
@ -424,17 +424,17 @@ int main(int argc, char **argv) {
auto InputsOrErr = getInputs(OptionsOrErr->Update);
if (!InputsOrErr) {
error_ostream() << toString(InputsOrErr.takeError()) << '\n';
WithColor::error() << toString(InputsOrErr.takeError()) << '\n';
return 1;
}
if (!FlatOut && OutputFileOpt == "-") {
error_ostream() << "cannot emit to standard output without --flat\n";
WithColor::error() << "cannot emit to standard output without --flat\n";
return 1;
}
if (InputsOrErr->size() > 1 && FlatOut && !OutputFileOpt.empty()) {
error_ostream() << "cannot use -o with multiple inputs in flat mode\n";
WithColor::error() << "cannot use -o with multiple inputs in flat mode\n";
return 1;
}
@ -442,12 +442,13 @@ int main(int argc, char **argv) {
PaperTrailWarnings = true;
if (PaperTrailWarnings && InputIsYAMLDebugMap)
warn_ostream() << "Paper trail warnings are not supported for YAML input";
WithColor::warning()
<< "Paper trail warnings are not supported for YAML input";
for (const auto &Arch : ArchFlags)
if (Arch != "*" && Arch != "all" &&
!llvm::object::MachOObjectFile::isValidArch(Arch)) {
error_ostream() << "unsupported cpu architecture: '" << Arch << "'\n";
WithColor::error() << "unsupported cpu architecture: '" << Arch << "'\n";
return 1;
}
@ -464,8 +465,8 @@ int main(int argc, char **argv) {
Verbose, InputIsYAMLDebugMap);
if (auto EC = DebugMapPtrsOrErr.getError()) {
error_ostream() << "cannot parse the debug map for '" << InputFile
<< "': " << EC.message() << '\n';
WithColor::error() << "cannot parse the debug map for '" << InputFile
<< "': " << EC.message() << '\n';
return 1;
}
@ -479,7 +480,7 @@ int main(int argc, char **argv) {
// Ensure that the debug map is not empty (anymore).
if (DebugMapPtrsOrErr->empty()) {
error_ostream() << "no architecture to link\n";
WithColor::error() << "no architecture to link\n";
return 1;
}
@ -504,10 +505,9 @@ int main(int argc, char **argv) {
continue;
if (Map->begin() == Map->end())
warn_ostream() << "no debug symbols in executable (-arch "
<< MachOUtils::getArchName(
Map->getTriple().getArchName())
<< ")\n";
WithColor::warning()
<< "no debug symbols in executable (-arch "
<< MachOUtils::getArchName(Map->getTriple().getArchName()) << ")\n";
// Using a std::shared_ptr rather than std::unique_ptr because move-only
// types don't work with std::bind in the ThreadPool implementation.