Coverage Report

Created: 2018-10-23 15:26

/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.29k
static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
35
3.29k
  // True if the previous error message contained "\n".
36
3.29k
  // We want to separate multi-line error messages with a newline.
37
3.29k
  static bool Flag;
38
3.29k
39
3.29k
  if (Flag)
40
99
    *ErrorOS << "\n";
41
3.29k
  Flag = StringRef(Msg.str()).contains('\n');
42
3.29k
}
43
44
249k
ErrorHandler &lld::errorHandler() {
45
249k
  static ErrorHandler Handler;
46
249k
  return Handler;
47
249k
}
48
49
0
void lld::exitLld(int Val) {
50
0
  // Delete any temporary file, while keeping the memory mapping open.
51
0
  if (errorHandler().OutputBuffer)
52
0
    errorHandler().OutputBuffer->discard();
53
0
54
0
  // Dealloc/destroy ManagedStatic variables before calling
55
0
  // _exit(). In a non-LTO build, this is a nop. In an LTO
56
0
  // build allows us to get the output of -time-passes.
57
0
  llvm_shutdown();
58
0
59
0
  outs().flush();
60
0
  errs().flush();
61
0
  _exit(Val);
62
0
}
63
64
2
void lld::diagnosticHandler(const DiagnosticInfo &DI) {
65
2
  SmallString<128> S;
66
2
  raw_svector_ostream OS(S);
67
2
  DiagnosticPrinterRawOStream DP(OS);
68
2
  DI.print(DP);
69
2
  switch (DI.getSeverity()) {
70
2
  case DS_Error:
71
1
    error(S);
72
1
    break;
73
2
  case DS_Warning:
74
1
    warn(S);
75
1
    break;
76
2
  case DS_Remark:
77
0
  case DS_Note:
78
0
    message(S);
79
0
    break;
80
2
  }
81
2
}
82
83
616
void lld::checkError(Error E) {
84
616
  handleAllErrors(std::move(E),
85
616
                  [&](ErrorInfoBase &EIB) 
{ error(EIB.message()); }3
);
86
616
}
87
88
1.49k
void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
89
1.49k
  *ErrorOS << LogName << ": ";
90
1.49k
  if (ColorDiagnostics) {
91
4
    ErrorOS->changeColor(C, true);
92
4
    *ErrorOS << S;
93
4
    ErrorOS->resetColor();
94
1.49k
  } else {
95
1.49k
    *ErrorOS << S;
96
1.49k
  }
97
1.49k
}
98
99
12.1k
void ErrorHandler::log(const Twine &Msg) {
100
12.1k
  if (Verbose) {
101
249
    std::lock_guard<std::mutex> Lock(Mu);
102
249
    *ErrorOS << LogName << ": " << Msg << "\n";
103
249
  }
104
12.1k
}
105
106
257
void ErrorHandler::message(const Twine &Msg) {
107
257
  std::lock_guard<std::mutex> Lock(Mu);
108
257
  outs() << Msg << "\n";
109
257
  outs().flush();
110
257
}
111
112
674
void ErrorHandler::warn(const Twine &Msg) {
113
674
  if (FatalWarnings) {
114
11
    error(Msg);
115
11
    return;
116
11
  }
117
663
118
663
  std::lock_guard<std::mutex> Lock(Mu);
119
663
  newline(ErrorOS, Msg);
120
663
  print("warning: ", raw_ostream::MAGENTA);
121
663
  *ErrorOS << Msg << "\n";
122
663
}
123
124
2.63k
void ErrorHandler::error(const Twine &Msg) {
125
2.63k
  std::lock_guard<std::mutex> Lock(Mu);
126
2.63k
  newline(ErrorOS, Msg);
127
2.63k
128
2.63k
  if (ErrorLimit == 0 || 
ErrorCount < ErrorLimit2.56k
) {
129
827
    print("error: ", raw_ostream::RED);
130
827
    *ErrorOS << Msg << "\n";
131
1.80k
  } else if (ErrorCount == ErrorLimit) {
132
6
    print("error: ", raw_ostream::RED);
133
6
    *ErrorOS << ErrorLimitExceededMsg << "\n";
134
6
    if (ExitEarly)
135
0
      exitLld(1);
136
2.63k
  }
137
2.63k
138
2.63k
  ++ErrorCount;
139
2.63k
}
140
141
0
void ErrorHandler::fatal(const Twine &Msg) {
142
0
  error(Msg);
143
0
  exitLld(1);
144
0
}