Coverage Report

Created: 2018-01-17 21:32

/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/Support/Error.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
2.36k
static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
34
2.36k
  // True if the previous error message contained "\n".
35
2.36k
  // We want to separate multi-line error messages with a newline.
36
2.36k
  static bool Flag;
37
2.36k
38
2.36k
  if (Flag)
39
23
    *ErrorOS << "\n";
40
2.36k
  Flag = StringRef(Msg.str()).contains('\n');
41
2.36k
}
42
43
90.6k
ErrorHandler &lld::errorHandler() {
44
90.6k
  static ErrorHandler Handler;
45
90.6k
  return Handler;
46
90.6k
}
47
48
0
void lld::exitLld(int Val) {
49
0
  // Delete the output buffer so that any tempory file is deleted.
50
0
  errorHandler().OutputBuffer.reset();
51
0
52
0
  // Dealloc/destroy ManagedStatic variables before calling
53
0
  // _exit(). In a non-LTO build, this is a nop. In an LTO
54
0
  // build allows us to get the output of -time-passes.
55
0
  llvm_shutdown();
56
0
57
0
  outs().flush();
58
0
  errs().flush();
59
0
  _exit(Val);
60
0
}
61
62
567
void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
63
567
  *ErrorOS << LogName << ": ";
64
567
  if (ColorDiagnostics) {
65
6
    ErrorOS->changeColor(C, true);
66
6
    *ErrorOS << S;
67
6
    ErrorOS->resetColor();
68
561
  } else {
69
561
    *ErrorOS << S;
70
561
  }
71
567
}
72
73
1.78k
void ErrorHandler::log(const Twine &Msg) {
74
1.78k
  if (Verbose) {
75
55
    std::lock_guard<std::mutex> Lock(Mu);
76
55
    *ErrorOS << LogName << ": " << Msg << "\n";
77
55
  }
78
1.78k
}
79
80
80
void ErrorHandler::message(const Twine &Msg) {
81
80
  std::lock_guard<std::mutex> Lock(Mu);
82
80
  outs() << Msg << "\n";
83
80
  outs().flush();
84
80
}
85
86
289
void ErrorHandler::warn(const Twine &Msg) {
87
289
  if (FatalWarnings) {
88
1
    error(Msg);
89
1
    return;
90
1
  }
91
288
92
288
  std::lock_guard<std::mutex> Lock(Mu);
93
288
  newline(ErrorOS, Msg);
94
288
  print("warning: ", raw_ostream::MAGENTA);
95
288
  *ErrorOS << Msg << "\n";
96
288
}
97
98
2.07k
void ErrorHandler::error(const Twine &Msg) {
99
2.07k
  std::lock_guard<std::mutex> Lock(Mu);
100
2.07k
  newline(ErrorOS, Msg);
101
2.07k
102
2.07k
  if (ErrorLimit == 0 || 
ErrorCount < ErrorLimit2.05k
) {
103
276
    print("error: ", raw_ostream::RED);
104
276
    *ErrorOS << Msg << "\n";
105
1.80k
  } else if (ErrorCount == ErrorLimit) {
106
3
    print("error: ", raw_ostream::RED);
107
3
    *ErrorOS << ErrorLimitExceededMsg << "\n";
108
3
    if (ExitEarly)
109
0
      exitLld(1);
110
2.07k
  }
111
2.07k
112
2.07k
  ++ErrorCount;
113
2.07k
}
114
115
0
void ErrorHandler::fatal(const Twine &Msg) {
116
0
  error(Msg);
117
0
  exitLld(1);
118
0
}