Coverage Report

Created: 2019-05-19 14:56

/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
// 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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "lld/Common/ErrorHandler.h"
10
11
#include "lld/Common/Threads.h"
12
13
#include "llvm/ADT/Twine.h"
14
#include "llvm/IR/DiagnosticInfo.h"
15
#include "llvm/IR/DiagnosticPrinter.h"
16
#include "llvm/Support/ManagedStatic.h"
17
#include "llvm/Support/raw_ostream.h"
18
#include <mutex>
19
20
#if !defined(_MSC_VER) && !defined(__MINGW32__)
21
#include <unistd.h>
22
#endif
23
24
using namespace llvm;
25
using namespace lld;
26
27
// The functions defined in this file can be called from multiple threads,
28
// but outs() or errs() are not thread-safe. We protect them using a mutex.
29
static std::mutex Mu;
30
31
// Prints "\n" or does nothing, depending on Msg contents of
32
// the previous call of this function.
33
3.45k
static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
34
3.45k
  // True if the previous error message contained "\n".
35
3.45k
  // We want to separate multi-line error messages with a newline.
36
3.45k
  static bool Flag;
37
3.45k
38
3.45k
  if (Flag)
39
109
    *ErrorOS << "\n";
40
3.45k
  Flag = StringRef(Msg.str()).contains('\n');
41
3.45k
}
42
43
270k
ErrorHandler &lld::errorHandler() {
44
270k
  static ErrorHandler Handler;
45
270k
  return Handler;
46
270k
}
47
48
0
void lld::exitLld(int Val) {
49
0
  // Delete any temporary file, while keeping the memory mapping open.
50
0
  if (errorHandler().OutputBuffer)
51
0
    errorHandler().OutputBuffer->discard();
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
3
void lld::diagnosticHandler(const DiagnosticInfo &DI) {
64
3
  SmallString<128> S;
65
3
  raw_svector_ostream OS(S);
66
3
  DiagnosticPrinterRawOStream DP(OS);
67
3
  DI.print(DP);
68
3
  switch (DI.getSeverity()) {
69
3
  case DS_Error:
70
1
    error(S);
71
1
    break;
72
3
  case DS_Warning:
73
2
    warn(S);
74
2
    break;
75
3
  case DS_Remark:
76
0
  case DS_Note:
77
0
    message(S);
78
0
    break;
79
3
  }
80
3
}
81
82
650
void lld::checkError(Error E) {
83
650
  handleAllErrors(std::move(E),
84
650
                  [&](ErrorInfoBase &EIB) 
{ error(EIB.message()); }3
);
85
650
}
86
87
1.65k
void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
88
1.65k
  *ErrorOS << LogName << ": ";
89
1.65k
  if (ColorDiagnostics) {
90
8
    ErrorOS->changeColor(C, true);
91
8
    *ErrorOS << S;
92
8
    ErrorOS->resetColor();
93
1.64k
  } else {
94
1.64k
    *ErrorOS << S;
95
1.64k
  }
96
1.65k
}
97
98
16.0k
void ErrorHandler::log(const Twine &Msg) {
99
16.0k
  if (Verbose) {
100
270
    std::lock_guard<std::mutex> Lock(Mu);
101
270
    *ErrorOS << LogName << ": " << Msg << "\n";
102
270
  }
103
16.0k
}
104
105
282
void ErrorHandler::message(const Twine &Msg) {
106
282
  std::lock_guard<std::mutex> Lock(Mu);
107
282
  outs() << Msg << "\n";
108
282
  outs().flush();
109
282
}
110
111
756
void ErrorHandler::warn(const Twine &Msg) {
112
756
  if (FatalWarnings) {
113
12
    error(Msg);
114
12
    return;
115
12
  }
116
744
117
744
  std::lock_guard<std::mutex> Lock(Mu);
118
744
  newline(ErrorOS, Msg);
119
744
  print("warning: ", raw_ostream::MAGENTA);
120
744
  *ErrorOS << Msg << "\n";
121
744
}
122
123
2.71k
void ErrorHandler::error(const Twine &Msg) {
124
2.71k
  std::lock_guard<std::mutex> Lock(Mu);
125
2.71k
  newline(ErrorOS, Msg);
126
2.71k
127
2.71k
  if (ErrorLimit == 0 || 
ErrorCount < ErrorLimit2.64k
) {
128
905
    print("error: ", raw_ostream::RED);
129
905
    *ErrorOS << Msg << "\n";
130
1.80k
  } else if (ErrorCount == ErrorLimit) {
131
6
    print("error: ", raw_ostream::RED);
132
6
    *ErrorOS << ErrorLimitExceededMsg << "\n";
133
6
    if (ExitEarly)
134
0
      exitLld(1);
135
2.71k
  }
136
2.71k
137
2.71k
  ++ErrorCount;
138
2.71k
}
139
140
0
void ErrorHandler::fatal(const Twine &Msg) {
141
0
  error(Msg);
142
0
  exitLld(1);
143
0
}