FE 0.15.0
A C++23 toolkit for writing compiler/interpreter frontends.
Loading...
Searching...
No Matches
dbg.h
Go to the documentation of this file.
1#pragma once
2
3#include <bit>
4#include <ostream>
5
6#ifdef FE_ABSL
7# include <absl/container/flat_hash_map.h>
8# include <absl/container/flat_hash_set.h>
9#else
10# include <unordered_map>
11# include <unordered_set>
12#endif
13
14#include "fe/format.h"
15#include "fe/hash.h"
16#include "fe/loc.h"
17#include "fe/sym.h"
18
19namespace fe {
20
21/// The debug info of an entity: where it came from and what it was called.
22struct Dbg {
23public:
24 /// @name Constructors
25 ///@{
26 constexpr Dbg() noexcept = default;
27 constexpr Dbg(const Dbg&) noexcept = default;
28 constexpr Dbg(Loc loc, Sym sym) noexcept
29 : loc_(loc)
30 , sym_(sym) {}
31 constexpr Dbg(Loc loc) noexcept
32 : Dbg(loc, {}) {}
33 constexpr Dbg(Sym sym) noexcept
34 : Dbg({}, sym) {}
35 Dbg& operator=(const Dbg&) noexcept = default;
36 ///@}
37
38 /// @name Getters
39 ///@{
40 constexpr Sym sym() const noexcept { return sym_; }
41 constexpr Loc loc() const noexcept { return loc_; }
42 /// Assumes `_` as the anonymous name.
43 constexpr bool is_anon() const noexcept { return !sym() || sym() == '_'; }
44 constexpr explicit operator bool() const noexcept { return sym().operator bool(); }
45 ///@}
46
47 /// @name Setters
48 ///@{
49 constexpr Dbg& set(Sym sym) noexcept { return sym_ = sym, *this; }
50 constexpr Dbg& set(Loc loc) noexcept { return loc_ = loc, *this; }
51 ///@}
52
53 /// @name Comparison and Hashing
54 ///@{
55 /// @note Like Loc::operator==, this only compares Loc::src by pointer identity.
56 constexpr bool operator==(const Dbg& other) const noexcept { return loc_ == other.loc_ && sym_ == other.sym_; }
57
58 struct Hash {
59 size_t operator()(Dbg dbg) const noexcept {
60 auto h = hash_begin(std::bit_cast<uintptr_t>(dbg.loc_.src));
61 h = hash_combine(h, dbg.loc_.begin.off);
62 h = hash_combine(h, dbg.loc_.end.off);
63 return hash_combine(h, Sym::Hash()(dbg.sym_));
64 }
65 };
66
67 struct Eq {
68 constexpr bool operator()(Dbg d1, Dbg d2) const noexcept { return d1 == d2; }
69 };
70
71 template<class H>
72 friend H AbslHashValue(H h, Dbg dbg) noexcept {
73 return H::combine(std::move(h), dbg.loc_.src, dbg.loc_.begin.off, dbg.loc_.end.off, dbg.sym_);
74 }
75 ///@}
76
77private:
78 Loc loc_;
79 Sym sym_;
80
81 friend std::ostream& operator<<(std::ostream& os, const Dbg& dbg) { return os << dbg.sym(); }
82};
83
84/// @name DbgMap/DbgSet
85///@{
86#ifdef FE_ABSL
87template<class V>
88using DbgMap = absl::flat_hash_map<Dbg, V, Dbg::Hash, Dbg::Eq>;
89using DbgSet = absl::flat_hash_set<Dbg, Dbg::Hash, Dbg::Eq>;
90#else
91template<class V>
92using DbgMap = std::unordered_map<Dbg, V, Dbg::Hash, Dbg::Eq>;
93using DbgSet = std::unordered_set<Dbg, Dbg::Hash, Dbg::Eq>;
94#endif
95///@}
96
97/// Opaque handle to a Dbg interned in a Driver; see Driver::dbg.
98/// Handing one node another's key copies the handle verbatim: no Dbg is materialised and nothing is
99/// looked up in the Driver's table.
100/// @warning A key is only meaningful within the Driver that interned it.
101class DbgKey {
102public:
103 constexpr DbgKey() noexcept = default; ///< The empty Dbg.
104
105 constexpr explicit operator bool() const noexcept { return key_ != 0; } ///< Not the empty Dbg?
106 constexpr bool operator==(const DbgKey&) const noexcept = default;
107
108private:
109 constexpr explicit DbgKey(uint32_t key) noexcept
110 : key_(key) {}
111
112 uint32_t key_ = 0;
113
114 friend struct Driver;
115};
116
117} // namespace fe
118
119#ifndef DOXYGEN
120template<>
121struct std::formatter<fe::Dbg> : fe::ostream_formatter {};
122#endif
constexpr bool operator==(const DbgKey &) const noexcept=default
constexpr DbgKey() noexcept=default
The empty Dbg.
friend struct Driver
Definition dbg.h:114
A Symbol just wraps a pointer to Sym::String, so pass Sym itself around as value.
Definition sym.h:37
Definition algo.h:17
constexpr size_t hash_begin() noexcept
Seeds a hash chain with the FNV-1 offset basis.
Definition hash.h:69
std::unordered_set< Dbg, Dbg::Hash, Dbg::Eq > DbgSet
Definition dbg.h:93
basic_ostream_formatter< char > ostream_formatter
Definition format.h:61
constexpr size_t hash_combine(size_t seed, T v) noexcept
Mixes v into seed word-wise, reusing the FNV-1 prime as multiplier.
Definition hash.h:73
std::unordered_map< Dbg, V, Dbg::Hash, Dbg::Eq > DbgMap
Definition dbg.h:92
constexpr bool operator()(Dbg d1, Dbg d2) const noexcept
Definition dbg.h:68
size_t operator()(Dbg dbg) const noexcept
Definition dbg.h:59
constexpr Loc loc() const noexcept
Definition dbg.h:41
constexpr Dbg & set(Sym sym) noexcept
Definition dbg.h:49
Dbg & operator=(const Dbg &) noexcept=default
constexpr bool operator==(const Dbg &other) const noexcept
Definition dbg.h:56
constexpr Dbg(Loc loc) noexcept
Definition dbg.h:31
friend std::ostream & operator<<(std::ostream &os, const Dbg &dbg)
Definition dbg.h:81
constexpr Dbg() noexcept=default
constexpr bool is_anon() const noexcept
Assumes _ as the anonymous name.
Definition dbg.h:43
friend H AbslHashValue(H h, Dbg dbg) noexcept
Definition dbg.h:72
constexpr Sym sym() const noexcept
Definition dbg.h:40
constexpr Dbg(Sym sym) noexcept
Definition dbg.h:33
constexpr Dbg & set(Loc loc) noexcept
Definition dbg.h:50
Location within a Src: the half-open byte range [Loc::begin, Loc::end).
Definition loc.h:42