FE 0.13.1
Header-only C++ frontend library
Loading...
Searching...
No Matches
driver.h
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4
5#include <memory>
6#include <utility>
7
8#include "fe/dbg.h"
9#include "fe/diag.h"
10#include "fe/error.h"
11#include "fe/src.h"
12#include "fe/sym.h"
13#include "fe/vector.h"
14
15namespace fe {
16
17/// Use/derive from this class for "global" variables that you need all over the place.
18/// Well, there are not really global - that's the point of this class.
19/// It manages a SymPool, a SrcMap, the interned Dbg%s, the Diag that lays out a diagnostic, and the Error they land in.
20/// @note Deliberately free of virtual functions - Driver::diag is where you plug in behavior of your own.
21/// @warning Not movable: Driver::error - and a Diag of your own - point back here.
22struct Driver : public SymPool {
23public:
25
26 /// Installs @p diag right away, so Driver::error renders through it from the very first message.
27 /// @warning Never `nullptr`.
28 explicit Driver(std::unique_ptr<Diag> diag);
29
31 Driver(const Driver&) = delete;
32 Driver(Driver&&) = delete;
34
35 /// @name Diagnostics
36 /// Every frontend building block reports into Driver::error; Error::ack it before this Driver dies.
37 ///@{
38 Error& error() { return error_; }
39 const Error& error() const { return error_; }
40
41 // clang-format off
42 template<class... Args> Error& error(Loc loc, std::format_string<Args...> fmt, Args&&... args) { return error_.error(loc, fmt, std::forward<Args>(args)...); }
43 template<class... Args> Error& warn (Loc loc, std::format_string<Args...> fmt, Args&&... args) { return error_.warn (loc, fmt, std::forward<Args>(args)...); }
44 template<class... Args> Error& note ( std::format_string<Args...> fmt, Args&&... args) { return error_.note ( fmt, std::forward<Args>(args)...); }
45 template<class... Args> Error& note (Loc loc, std::format_string<Args...> fmt, Args&&... args) { return error_.note (loc, fmt, std::forward<Args>(args)...); }
46 // clang-format on
47
48 Diag& diag() { return *diag_; }
49 const Diag& diag() const { return *diag_; }
50
51 /// Installs @p diag - a subclass of your own, typically - and yields the previous one.
52 /// @warning Never `nullptr`.
53 std::unique_ptr<Diag> diag(std::unique_ptr<Diag> diag) {
54 assert(diag && "a Driver always has a Diag");
55 return std::exchange(diag_, std::move(diag));
56 }
57 ///@}
58
59 /// @name Source Files
60 /// Register every file you lex here: a Loc is only as good as the SrcMap that keeps its Src alive.
61 ///@{
62 SrcMap& src() { return src_; }
63 const SrcMap& src() const { return src_; }
64 ///@}
65
66 /// @name Dbg Interning
67 /// A node only has to store the DbgKey instead of a full Dbg.
68 /// Both halves of a Dbg are already owned here:
69 /// Dbg::sym is interned in this Driver's SymPool and Dbg::loc points into Driver::src.
70 ///@{
71 Dbg dbg(DbgKey key) const { return dbgs_[key.key_]; }
72
73 /// Interns @p dbg and yields its DbgKey.
75 if (auto i = dbg2key_.find(dbg); i != dbg2key_.end()) return DbgKey(i->second);
76 auto key = uint32_t(dbgs_.size());
77 dbgs_.emplace_back(dbg);
78 dbg2key_.emplace(dbg, key);
79 return DbgKey(key);
80 }
81 ///@}
82
83private:
84 std::unique_ptr<Diag> diag_;
85 Error error_;
86 SrcMap src_;
87 Vector<Dbg> dbgs_ = {Dbg()}; ///< Key `0` is the empty Dbg.
88 DbgMap<uint32_t> dbg2key_ = {
89 {Dbg(), 0}
90 };
91};
92
93} // namespace fe
Opaque handle to a Dbg interned in a Driver; see Driver::dbg.
Definition dbg.h:102
constexpr DbgKey() noexcept=default
The empty Dbg.
How a diagnostic lays out - and how much of it an Error keeps.
Definition diag.h:19
Collects diagnostics and hands each to the Diag that lays it out.
Definition error.h:27
Error & warn(Loc loc, std::format_string< Args... > s, Args &&... args)
Definition error.h:104
Error & note(std::format_string< Args... > s, Args &&... args)
A = note: continuation of the diagnostic being built; it has no Loc of its own to point at.
Definition error.h:107
Error & error(Loc loc, std::format_string< Args... > s, Args &&... args)
Definition error.h:103
Interns the text - and the std::filesystem::path - of every file a Loc may point into.
Definition src.h:133
SymPool(const SymPool &)=delete
This is a thin wrapper for absl::InlinedVector<T, N, A> which is a drop-in replacement for std::vecto...
Definition vector.h:39
Definition algo.h:17
The debug info of an entity: where it came from and what it was called.
Definition dbg.h:22
constexpr Dbg() noexcept=default
Error & note(Loc loc, std::format_string< Args... > fmt, Args &&... args)
Definition driver.h:45
const Error & error() const
Definition driver.h:39
Dbg dbg(DbgKey key) const
Definition driver.h:71
Error & warn(Loc loc, std::format_string< Args... > fmt, Args &&... args)
Definition driver.h:43
SrcMap & src()
Definition driver.h:62
Driver(const Driver &)=delete
Diag & diag()
Definition driver.h:48
Driver(Driver &&)=delete
DbgKey dbg(Dbg dbg)
Interns dbg and yields its DbgKey.
Definition driver.h:74
const SrcMap & src() const
Definition driver.h:63
Error & error(Loc loc, std::format_string< Args... > fmt, Args &&... args)
Definition driver.h:42
Driver(std::unique_ptr< Diag > diag)
Installs diag right away, so Driver::error renders through it from the very first message.
Error & note(std::format_string< Args... > fmt, Args &&... args)
Definition driver.h:44
std::unique_ptr< Diag > diag(std::unique_ptr< Diag > diag)
Installs diag - a subclass of your own, typically - and yields the previous one.
Definition driver.h:53
Error & error()
Definition driver.h:38
Driver & operator=(Driver)=delete
const Diag & diag() const
Definition driver.h:49
Location within a Src: the half-open byte range [Loc::begin, Loc::end).
Definition loc.h:46