FE 0.13.1
Header-only C++ frontend library
Loading...
Searching...
No Matches
loc.h
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4#include <cstdint>
5
6#include <algorithm>
7#include <iosfwd>
8
9#include "fe/sym.h"
10
11namespace fe {
12
13class Src;
14
15/// Byte offset into a Src; pass around as value.
16/// A Pos%ition is just an index - fe::Src turns it back into the row/column a human wants to read.
17/// @warning Files beyond 4GiB wrap around, and the largest offset doubles as the "invalid" sentinel.
18struct Pos {
19 static constexpr uint32_t Invalid = uint32_t(-1);
20
21 constexpr Pos() = default; ///< Creates an invalid Pos%ition.
22 constexpr explicit Pos(uint32_t off)
23 : off(off) {}
24
25 constexpr explicit operator bool() const { return off != Invalid; } ///< Is a valid Pos%ition?
26 constexpr auto operator<=>(const Pos&) const = default;
27 constexpr Pos operator+(uint32_t n) const {
28 assert(*this && (uint64_t)off + n < Invalid);
29 return Pos(off + n);
30 }
31 void dump() const;
32
33 uint32_t off = Invalid;
34
35 /// `fe/loc.h` only declares the stream output and dump helpers.
36 /// Link `fe-lib` for the default implementation, or provide your own.
37 friend std::ostream& operator<<(std::ostream& os, Pos pos);
38};
39
40/// Loc%ation within a Src: the half-open byte range `[Loc::begin, Loc::end)`.
41/// It's only two machine words on a 64 bit arch, so pass around as value.
42/// An *empty* range is a Loc%ation *between* two characters - what you want to point at
43/// when something is missing rather than wrong; see Loc::anew_end.
44/// @warning Loc::src is only a pointer and it is your job to guarantee that the underlying
45/// fe::Src outlives this Loc%ation; fe::SrcMap owns one for you.
46struct Loc {
47 /// How much of a Loc a diagnostic spells out; see Diag::loc_style.
48 enum class Style {
49 Full, ///< `path:row:col-row:col` - the whole range.
50 RowCol, ///< `path:row:col`
51 Row, ///< `path:row`
52 MSVC, ///< `path(row,col)`
53 };
54
55 constexpr Loc() = default; ///< Creates an invalid Loc%ation.
56 constexpr Loc(const Src* src, Pos begin, Pos end)
57 : src(src)
58 , begin(begin)
59 , end(end) {}
60 constexpr Loc(const Src* src, Pos pos)
61 : Loc(src, pos, pos) {} ///< The empty Loc%ation at @p pos.
62 constexpr Loc(Pos begin, Pos end)
63 : Loc(nullptr, begin, end) {}
64 constexpr Loc(Pos pos)
65 : Loc(nullptr, pos, pos) {}
66
67 constexpr Loc anew_begin() const { return {src, begin, begin}; }
68 constexpr Loc anew_end() const { return {src, end, end}; }
69 constexpr uint32_t size() const {
70 assert((bool)begin == (bool)end && begin <= end);
71 return end.off - begin.off;
72 }
73 constexpr Loc operator+(Pos pos) const { return {src, begin, pos}; }
74 constexpr Loc operator+(Loc loc) const { return {src, begin, loc.end}; } ///< The hull of both Loc%ations.
75
76 /// The overlap of both Loc%ations - invalid if they are disjoint or sit in different files.
77 /// Dual to operator+; since an invalid Loc is falsy, `if (a & b)` also reads as "do they overlap?".
78 /// An empty Loc overlaps nothing, not even itself.
79 /// @note Loc::src is only compared via pointer equality - which is all it takes, as fe::SrcMap
80 /// interns paths and hands out exactly one Src per file.
81 constexpr Loc operator&(Loc loc) const {
82 auto b = std::max(begin, loc.begin);
83 auto e = std::min(end, loc.end);
84 if (src != loc.src || b >= e) return {};
85 return {src, b, e};
86 }
87
88 constexpr explicit operator bool() const { return (bool)begin; } ///< Is a valid Loc%ation?
89 /// @note Loc::src is only checked via pointer equality.
90 constexpr bool operator==(Loc other) const { return begin == other.begin && end == other.end && src == other.src; }
91 void dump() const;
92
93 const Src* src = {};
94 Pos begin = {};
95 Pos end = {};
96 ///< It's called `end` because - just like an STL iterator - it refers to the byte
97 /// one **past** the last one within this Loc%ation.
98
99 /// Streams as `path:row:col-row:col`, resolved through Loc::src - or as raw offsets if it has none.
100 /// `fe/loc.h` only declares the stream output and dump helpers.
101 /// Link `fe-lib` for the default implementation, or provide your own.
102 friend std::ostream& operator<<(std::ostream& os, Loc loc);
103};
104
105// Keep Loc at two machine words so it is passed/returned in registers.
106static_assert(sizeof(void*) != 8 || sizeof(Loc) == 16, "Loc should stay two machine words");
107
108} // namespace fe
The content of one source file together with the offsets its rows start at.
Definition src.h:44
Definition algo.h:17
Location within a Src: the half-open byte range [Loc::begin, Loc::end).
Definition loc.h:46
void dump() const
constexpr Loc operator+(Loc loc) const
The hull of both Locations.
Definition loc.h:74
constexpr Loc(Pos pos)
Definition loc.h:64
constexpr Loc operator&(Loc loc) const
The overlap of both Locations - invalid if they are disjoint or sit in different files.
Definition loc.h:81
friend std::ostream & operator<<(std::ostream &os, Loc loc)
Streams as path:row:col-row:col, resolved through Loc::src - or as raw offsets if it has none.
constexpr Loc(const Src *src, Pos begin, Pos end)
Definition loc.h:56
Pos begin
Definition loc.h:94
constexpr bool operator==(Loc other) const
Definition loc.h:90
constexpr Loc anew_end() const
Definition loc.h:68
Style
How much of a Loc a diagnostic spells out; see Diag::loc_style.
Definition loc.h:48
constexpr uint32_t size() const
Definition loc.h:69
constexpr Loc operator+(Pos pos) const
Definition loc.h:73
const Src * src
Definition loc.h:93
constexpr Loc()=default
Creates an invalid Location.
constexpr Loc(const Src *src, Pos pos)
The empty Location at pos.
Definition loc.h:60
Pos end
It's called end because - just like an STL iterator - it refers to the byte one past the last one wit...
Definition loc.h:95
constexpr Loc(Pos begin, Pos end)
Definition loc.h:62
constexpr Loc anew_begin() const
Definition loc.h:67
Byte offset into a Src; pass around as value.
Definition loc.h:18
uint32_t off
Definition loc.h:33
static constexpr uint32_t Invalid
Definition loc.h:19
friend std::ostream & operator<<(std::ostream &os, Pos pos)
fe/loc.h only declares the stream output and dump helpers.
constexpr Pos operator+(uint32_t n) const
Definition loc.h:27
constexpr auto operator<=>(const Pos &) const =default
void dump() const
constexpr Pos(uint32_t off)
Definition loc.h:22
constexpr Pos()=default
Creates an invalid Position.