forked from bpftrace/bpftrace
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdiagnostic.cpp
More file actions
99 lines (86 loc) · 2.58 KB
/
Copy pathdiagnostic.cpp
File metadata and controls
99 lines (86 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <algorithm>
#include <ranges>
#include "diagnostic.h"
#include "log.h"
namespace bpftrace::ast {
std::stringstream& Diagnostic::addContext(Location loc)
{
loc_->contexts.emplace_back(std::make_shared<LocationChain>(loc->current));
return loc_->contexts.back().msg;
}
void Diagnostics::emit(std::ostream& out) const
{
// Emit all errors first, following by all warnings.
emit(out, Severity::Error);
emit(out, Severity::Warning);
}
void Diagnostics::emit(std::ostream& out, Severity s) const
{
if (s == Severity::Warning && !Log::get().is_enabled(LogType::WARNING))
return;
foreach(s, [this, s, &out](const Diagnostic& d) { emit(out, s, d); });
}
void Diagnostics::emit(std::ostream& out, Severity s, const Diagnostic& d) const
{
// Build our sets of messages.
std::vector<std::pair<std::string, SourceLocation>> msgs;
std::vector<std::pair<std::string, SourceLocation>> parent_msgs;
auto loc = d.loc();
if (loc) {
msgs.emplace_back(d.msg(), loc->current);
for (const auto& context : loc->contexts) {
msgs.emplace_back(context.msg.str(), context.loc->current);
}
while (loc) {
auto& parent = loc->parent;
if (parent) {
parent_msgs.emplace_back(parent->msg.str(), parent->loc->current);
loc = parent->loc;
} else {
break;
}
}
}
switch (s) {
case Severity::Warning:
if (msgs.empty()) {
LOG(WARNING, out) << d.msg();
}
for (const auto& [msg, loc] : msgs) {
LOG(WARNING, loc.source_location(), loc.source_context(), out) << msg;
}
for (const auto& msg : d.hints()) {
LOG(HINT, out) << msg;
}
for (const auto& [msg, loc] : parent_msgs) {
LOG(WARNING, loc.source_location(), loc.source_context(), out) << msg;
}
break;
case Severity::Error:
if (msgs.empty()) {
LOG(ERROR, out) << d.msg();
}
for (const auto& [msg, loc] : msgs) {
LOG(ERROR, loc.source_location(), loc.source_context(), out) << msg;
}
for (const auto& msg : d.hints()) {
LOG(HINT, out) << msg;
}
for (const auto& [msg, loc] : parent_msgs) {
LOG(ERROR, loc.source_location(), loc.source_context(), out) << msg;
}
break;
}
}
void Diagnostics::add(Diagnostics&& other)
{
if (diagnostics_.size() < other.diagnostics_.size()) {
diagnostics_.resize(other.diagnostics_.size());
}
for (size_t i = 0; i < other.diagnostics_.size(); i++) {
for (auto& d : other.diagnostics_[i]) {
diagnostics_[i].emplace_back(std::move(d));
}
}
}
} // namespace bpftrace::ast