3#include <absl/container/flat_hash_map.h>
4#include <absl/container/flat_hash_set.h>
31 return print(os,
"{}{}: {}: {}{}", rang::fg::yellow,
msg.loc,
msg.tag, rang::fg::reset,
msg.str);
32 return print(os,
"{}{}: {}: {}{}", rang::fg::yellow,
msg.loc,
msg.tag, rang::fg::reset,
msg.str);
45 Error(Loc loc,
const std::string& str)
53 const auto&
msgs()
const {
return msgs_; }
55 assert(num_errors() + num_warnings() + num_notes() == msgs_.size());
65 template<
class... Args>
Error&
msg(Loc loc,
Tag tag,
const char* s, Args&&... args) {
66 msgs_.emplace_back(loc, tag,
fmt(s, std::forward<Args&&>(args)...));
71 template<
class... Args>
Error&
error(Loc loc,
const char* s, Args&&... args) { ++num_errors_;
return msg(loc, Tag::Error, s, std::forward<Args&&>(args)...); }
72 template<
class... Args>
Error&
warn (Loc loc,
const char* s, Args&&... args) { ++num_warnings_;
return msg(loc, Tag::Warn, s, std::forward<Args&&>(args)...); }
73 template<
class... Args>
Error&
note (Loc loc,
const char* s, Args&&... args) {
74 assert(num_errors() > 0 || num_warnings() > 0); ++num_notes_;
return msg(loc, Tag::Note, s, std::forward<Args&&>(args)...);
83 void ack(std::ostream& os = std::cerr);
89 case Tag::Error:
return o << rang::fg::red <<
"error";
90 case Tag::Warn:
return o << rang::fg::magenta <<
"warning";
91 case Tag::Note:
return o << rang::fg::green <<
"note";
92 default: fe::unreachable();
98 for (
const auto& msg : e.msgs()) os << msg << std::endl;
105 swap(e1.msgs_, e2.msgs_);
106 swap(e1.num_errors_, e2.num_errors_);
107 swap(e1.num_warnings_, e2.num_warnings_);
108 swap(e1.num_notes_, e2.num_notes_);
113 std::vector<Msg> msgs_;
114 size_t num_errors_ = 0;
115 size_t num_warnings_ = 0;
116 size_t num_notes_ = 0;
122template<
class... Args> [[noreturn]]
void error(Loc loc,
const char* f, Args&&... args) {
123 throw Error(loc,
fmt(f, std::forward<Args&&>(args)...));
131 constexpr Dbg() noexcept = default;
132 constexpr
Dbg(const
Dbg&) noexcept = default;
133 constexpr
Dbg(Loc loc, Sym sym) noexcept
136 constexpr Dbg(Loc loc) noexcept
138 constexpr Dbg(Sym sym) noexcept
145 Sym
sym()
const {
return sym_; }
146 Loc
loc()
const {
return loc_; }
147 bool is_anon()
const {
return !sym() || sym() ==
'_'; }
148 explicit operator bool()
const {
return sym().operator bool(); }
153 Dbg&
set(Sym sym) {
return sym_ = sym, *
this; }
154 Dbg&
set(Loc loc) {
return loc_ = loc, *
this; }
161 friend std::ostream&
operator<<(std::ostream& os,
const Dbg& dbg) {
return os << dbg.sym(); }
friend void swap(Error &e1, Error &e2) noexcept
Error & error(Loc loc, const char *s, Args &&... args)
const auto & msgs() const
Error(const Error &)=default
friend std::ostream & operator<<(std::ostream &o, Tag tag)
Error & note(Loc loc, const char *s, Args &&... args)
friend std::ostream & operator<<(std::ostream &os, const Error &e)
Error & warn(Loc loc, const char *s, Args &&... args)
size_t num_errors() const
Error(Loc loc, const std::string &str)
Creates a single Tag::Error message.
size_t num_warnings() const
Error & msg(Loc loc, Tag tag, const char *s, Args &&... args)
std::ostream & print(std::ostream &os, const char *s)
Base case.
std::string fmt(const char *s, Args &&... args)
Wraps mim::print to output a formatted std:string.
Dbg & operator=(const Dbg &) noexcept=default
friend std::ostream & operator<<(std::ostream &os, const Dbg &dbg)
constexpr Dbg(Loc loc) noexcept
constexpr Dbg() noexcept=default
constexpr Dbg(Sym sym) noexcept
friend std::ostream & operator<<(std::ostream &os, const Msg &msg)