Coverage Report

Created: 2018-08-19 14:04

/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.34k
static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
35
3.34k
  // True if the previous error message contained "\n".
36
3.34k
  // We want to separate multi-line error messages with a newline.
37
3.34k
  static bool Flag;
38
3.34k
39
3.34k
  if (Flag)
40
94
    *ErrorOS << "\n";
41
3.34k
  Flag = StringRef(Msg.str()).contains('\n');
42
3.34k
}
43
44
231k
ErrorHandler &lld::errorHandler() {
45
231k
  static ErrorHandler Handler;
46
231k
  return Handler;
47
231k
}
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
1
void lld::diagnosticHandler(const DiagnosticInfo &DI) {
64
1
  SmallString<128> S;
65
1
  raw_svector_ostream OS(S);
66
1
  DiagnosticPrinterRawOStream DP(OS);
67
1
  DI.print(DP);
68
1
  switch (DI.getSeverity()) {
69
1
  case DS_Error:
70
0
    error(S);
71
0
    break;
72
1
  case DS_Warning:
73
1
    warn(S);
74
1
    break;
75
1
  case DS_Remark:
76
0
  case DS_Note:
77
0
    message(S);
78
0
    break;
79
1
  }
80
1
}
81
82
538
void lld::checkError(Error E) {
83
538
  handleAllErrors(std::move(E),
84
538
                  [&](ErrorInfoBase &EIB) 
{ error(EIB.message()); }3
);
85
538
}
86
87
1.55k
void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
88
1.55k
  *ErrorOS << LogName << ": ";
89
1.55k
  if (ColorDiagnostics) {
90
4
    ErrorOS->changeColor(C, true);
91
4
    *ErrorOS << S;
92
4
    ErrorOS->resetColor();
93
1.54k
  } else {
94
1.54k
    *ErrorOS << S;
95
1.54k
  }
96
1.55k
}
97
98
5.50k
void ErrorHandler::log(const Twine &Msg) {
99
5.50k
  if (Verbose) {
100
187
    std::lock_guard<std::mutex> Lock(Mu);
101
187
    *ErrorOS << LogName << ": " << Msg << "\n";
102
187
  }
103
5.50k
}
104
105
252
void ErrorHandler::message(const Twine &Msg) {
106
252
  std::lock_guard<std::mutex> Lock(Mu);
107
252
  outs() << Msg << "\n";
108
252
  outs().flush();
109
252
}
110
111
868
void ErrorHandler::warn(const Twine &Msg) {
112
868
  if (FatalWarnings) {
113
7
    error(Msg);
114
7
    return;
115
7
  }
116
861
117
861
  std::lock_guard<std::mutex> Lock(Mu);
118
861
  newline(ErrorOS, Msg);
119
861
  print("warning: ", raw_ostream::MAGENTA);
120
861
  *ErrorOS << Msg << "\n";
121
861
}
122
123
2.48k
void ErrorHandler::error(const Twine &Msg) {
124
2.48k
  std::lock_guard<std::mutex> Lock(Mu);
125
2.48k
  newline(ErrorOS, Msg);
126
2.48k
127
2.48k
  if (ErrorLimit == 0 || 
ErrorCount < ErrorLimit2.44k
) {
128
686
    print("error: ", raw_ostream::RED);
129
686
    *ErrorOS << Msg << "\n";
130
1.80k
  } else if (ErrorCount == ErrorLimit) {
131
4
    print("error: ", raw_ostream::RED);
132
4
    *ErrorOS << ErrorLimitExceededMsg << "\n";
133
4
    if (ExitEarly)
134
0
      exitLld(1);
135
2.48k
  }
136
2.48k
137
2.48k
  ++ErrorCount;
138
2.48k
}
139
140
0
void ErrorHandler::fatal(const Twine &Msg) {
141
0
  error(Msg);
142
0
  exitLld(1);
143
0
}