Coverage Report

Created: 2018-06-18 20:01

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/Common/ErrorHandler.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ErrorHandler.cpp ---------------------------------------------------===//
2
//
3
//                             The LLVM Linker
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#include "lld/Common/ErrorHandler.h"
11
12
#include "lld/Common/Threads.h"
13
14
#include "llvm/ADT/Twine.h"
15
#include "llvm/IR/DiagnosticInfo.h"
16
#include "llvm/IR/DiagnosticPrinter.h"
17
#include "llvm/Support/ManagedStatic.h"
18
#include "llvm/Support/raw_ostream.h"
19
#include <mutex>
20
21
#if !defined(_MSC_VER) && !defined(__MINGW32__)
22
#include <unistd.h>
23
#endif
24
25
using namespace llvm;
26
using namespace lld;
27
28
// The functions defined in this file can be called from multiple threads,
29
// but outs() or errs() are not thread-safe. We protect them using a mutex.
30
static std::mutex Mu;
31
32
// Prints "\n" or does nothing, depending on Msg contents of
33
// the previous call of this function.
34
3.24k
static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
35
3.24k
  // True if the previous error message contained "\n".
36
3.24k
  // We want to separate multi-line error messages with a newline.
37
3.24k
  static bool Flag;
38
3.24k
39
3.24k
  if (Flag)
40
93
    *ErrorOS << "\n";
41
3.24k
  Flag = StringRef(Msg.str()).contains('\n');
42
3.24k
}
43
44
220k
ErrorHandler &lld::errorHandler() {
45
220k
  static ErrorHandler Handler;
46
220k
  return Handler;
47
220k
}
48
49
0
void lld::exitLld(int Val) {
50
0
  // Delete the output buffer so that any tempory file is deleted.
51
0
  errorHandler().OutputBuffer.reset();
52
0
53
0
  // Dealloc/destroy ManagedStatic variables before calling
54
0
  // _exit(). In a non-LTO build, this is a nop. In an LTO
55
0
  // build allows us to get the output of -time-passes.
56
0
  llvm_shutdown();
57
0
58
0
  outs().flush();
59
0
  errs().flush();
60
0
  _exit(Val);
61
0
}
62
63
5
void lld::diagnosticHandler(const DiagnosticInfo &DI) {
64
5
  SmallString<128> S;
65
5
  raw_svector_ostream OS(S);
66
5
  DiagnosticPrinterRawOStream DP(OS);
67
5
  DI.print(DP);
68
5
  warn(S);
69
5
}
70
71
510
void lld::checkError(Error E) {
72
510
  handleAllErrors(std::move(E),
73
510
                  [&](ErrorInfoBase &EIB) 
{ error(EIB.message()); }3
);
74
510
}
75
76
1.44k
void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
77
1.44k
  *ErrorOS << LogName << ": ";
78
1.44k
  if (ColorDiagnostics) {
79
4
    ErrorOS->changeColor(C, true);
80
4
    *ErrorOS << S;
81
4
    ErrorOS->resetColor();
82
1.44k
  } else {
83
1.44k
    *ErrorOS << S;
84
1.44k
  }
85
1.44k
}
86
87
5.17k
void ErrorHandler::log(const Twine &Msg) {
88
5.17k
  if (Verbose) {
89
171
    std::lock_guard<std::mutex> Lock(Mu);
90
171
    *ErrorOS << LogName << ": " << Msg << "\n";
91
171
  }
92
5.17k
}
93
94
202
void ErrorHandler::message(const Twine &Msg) {
95
202
  std::lock_guard<std::mutex> Lock(Mu);
96
202
  outs() << Msg << "\n";
97
202
  outs().flush();
98
202
}
99
100
817
void ErrorHandler::warn(const Twine &Msg) {
101
817
  if (FatalWarnings) {
102
7
    error(Msg);
103
7
    return;
104
7
  }
105
810
106
810
  std::lock_guard<std::mutex> Lock(Mu);
107
810
  newline(ErrorOS, Msg);
108
810
  print("warning: ", raw_ostream::MAGENTA);
109
810
  *ErrorOS << Msg << "\n";
110
810
}
111
112
2.43k
void ErrorHandler::error(const Twine &Msg) {
113
2.43k
  std::lock_guard<std::mutex> Lock(Mu);
114
2.43k
  newline(ErrorOS, Msg);
115
2.43k
116
2.43k
  if (ErrorLimit == 0 || 
ErrorCount < ErrorLimit2.38k
) {
117
630
    print("error: ", raw_ostream::RED);
118
630
    *ErrorOS << Msg << "\n";
119
1.80k
  } else if (ErrorCount == ErrorLimit) {
120
4
    print("error: ", raw_ostream::RED);
121
4
    *ErrorOS << ErrorLimitExceededMsg << "\n";
122
4
    if (ExitEarly)
123
0
      exitLld(1);
124
2.43k
  }
125
2.43k
126
2.43k
  ++ErrorCount;
127
2.43k
}
128
129
0
void ErrorHandler::fatal(const Twine &Msg) {
130
0
  error(Msg);
131
0
  exitLld(1);
132
0
}