Coverage Report

Created: 2019-01-18 03:29

/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.32k
static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
35
3.32k
  // True if the previous error message contained "\n".
36
3.32k
  // We want to separate multi-line error messages with a newline.
37
3.32k
  static bool Flag;
38
3.32k
39
3.32k
  if (Flag)
40
102
    *ErrorOS << "\n";
41
3.32k
  Flag = StringRef(Msg.str()).contains('\n');
42
3.32k
}
43
44
255k
ErrorHandler &lld::errorHandler() {
45
255k
  static ErrorHandler Handler;
46
255k
  return Handler;
47
255k
}
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
622
void lld::checkError(Error E) {
84
622
  handleAllErrors(std::move(E),
85
622
                  [&](ErrorInfoBase &EIB) 
{ error(EIB.message()); }3
);
86
622
}
87
88
1.52k
void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
89
1.52k
  *ErrorOS << LogName << ": ";
90
1.52k
  if (ColorDiagnostics) {
91
4
    ErrorOS->changeColor(C, true);
92
4
    *ErrorOS << S;
93
4
    ErrorOS->resetColor();
94
1.51k
  } else {
95
1.51k
    *ErrorOS << S;
96
1.51k
  }
97
1.52k
}
98
99
12.7k
void ErrorHandler::log(const Twine &Msg) {
100
12.7k
  if (Verbose) {
101
249
    std::lock_guard<std::mutex> Lock(Mu);
102
249
    *ErrorOS << LogName << ": " << Msg << "\n";
103
249
  }
104
12.7k
}
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
689
void ErrorHandler::warn(const Twine &Msg) {
113
689
  if (FatalWarnings) {
114
13
    error(Msg);
115
13
    return;
116
13
  }
117
676
118
676
  std::lock_guard<std::mutex> Lock(Mu);
119
676
  newline(ErrorOS, Msg);
120
676
  print("warning: ", raw_ostream::MAGENTA);
121
676
  *ErrorOS << Msg << "\n";
122
676
}
123
124
2.64k
void ErrorHandler::error(const Twine &Msg) {
125
2.64k
  std::lock_guard<std::mutex> Lock(Mu);
126
2.64k
  newline(ErrorOS, Msg);
127
2.64k
128
2.64k
  if (ErrorLimit == 0 || 
ErrorCount < ErrorLimit2.57k
) {
129
839
    print("error: ", raw_ostream::RED);
130
839
    *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.64k
  }
137
2.64k
138
2.64k
  ++ErrorCount;
139
2.64k
}
140
141
0
void ErrorHandler::fatal(const Twine &Msg) {
142
0
  error(Msg);
143
0
  exitLld(1);
144
0
}