GCC Code Coverage Report


Directory: ./
File: src/ast/constant.h
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 21 23 91.3%
Functions: 28 44 63.6%
Branches: 26 66 39.4%

Line Branch Exec Source
1 #ifndef LYTHON_CONSTANT_HEADER
2 #define LYTHON_CONSTANT_HEADER
3
4 #include "dtypes.h"
5 #include <iostream>
6
7 #define CLANG_FMT_FIX
8
9 namespace lython {
10
11 struct NativeObject;
12
13 struct ConstantValue {
14 public:
15 struct invalid_t {
16 bool operator==(invalid_t const& t) const { return true; }
17 };
18
19 struct none_t {
20 bool operator==(none_t const& t) const { return true; }
21 };
22
23 static ConstantValue const& none() {
24
3/8
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
12 static ConstantValue n{none_t()};
25 12 return n;
26 }
27
28 #define ConstantType(POC, CPX) \
29 POD(Invalid, ConstantValue::invalid_t, invalid) \
30 POD(i8, int8, i8) \
31 POD(i16, int16, i16) \
32 POD(i32, int32, i32) \
33 POD(i64, int64, i64) \
34 POD(u8, uint8, u8) \
35 POD(u16, uint16, u16) \
36 POD(u32, uint32, u32) \
37 POD(u64, uint64, u64) \
38 POD(f32, float32, f32) \
39 POD(f64, float64, f64) \
40 POD(Bool, bool, boolean) \
41 POD(None, ConstantValue::none_t, none) \
42 POD(Object, NativeObject*, object) \
43 CPX(String, String, string)
44
45 #define NUMERIC_CONSTANT(NUM) \
46 NUM(i8, int8, i8) \
47 NUM(i16, int16, i16) \
48 NUM(i32, int32, i32) \
49 NUM(i64, int64, i64) \
50 NUM(u8, uint8, u8) \
51 NUM(u16, uint16, u16) \
52 NUM(u32, uint32, u32) \
53 NUM(u64, uint64, u64) \
54 NUM(f32, float32, f32) \
55 NUM(f64, float64, f64) \
56 NUM(Bool, bool, boolean)
57
58 // clang-format off
59 enum Type {
60 #define ENUM(a) T##a,
61 #define POD(a, b, c) ENUM(a)
62 #define CPX(a, b, c) ENUM(a)
63
64 ConstantType(POD, CPX)
65
66 #undef CPX
67 #undef POD
68 #undef ENUM
69
70 };
71
72 #define POD(k, type, name) explicit ConstantValue(type v): kind(T##k) { value.name = v; }
73 #define CPX(k, type, name) explicit ConstantValue(type v): kind(TInvalid) { set_##name(v); }
74
75 ConstantType(POD, CPX);
76
77 #undef CPX
78 #undef POD
79 // clang-format on
80
81 ConstantValue() = default;
82
83 ConstantValue(ConstantValue const& vv): kind(TInvalid) { copy_union(vv.kind, vv.value); }
84
85 ~ConstantValue() { remove_cpx(); }
86
87 ConstantValue& operator=(ConstantValue const& vv) {
88 838 copy_union(vv.kind, vv.value);
89 838 return *this;
90 }
91
92 bool operator==(ConstantValue const& v) const {
93
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 60 times.
61 if (v.kind != kind) {
94 1 return false;
95 }
96
97 // clang-format off
98
5/16
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 26 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✓ Branch 11 taken 4 times.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 17 times.
✗ Branch 15 not taken.
60 switch (kind) {
99 #define CMP(kind, type, name) case T##kind: return value.name == v.value.name;
100
101 #define POD(kind, type, name) CMP(kind, type, name)
102 #define CPX(kind, type, name) CMP(kind, type, name)
103
104 60 ConstantType(POD, CPX);
105
106 #undef CPX
107 #undef POD
108 }
109 // clang-format on
110
111 return false;
112 }
113
114 void print(std::ostream& out) const;
115
116 bool is_none() const { return kind == TNone; }
117
118 // clang-format off
119 bool is_pod() const {
120 switch (kind) {
121 #define POD(kind, type, name) case T##kind: return true;
122 #define CPX(kind, type, name) case T##kind: return false;
123
124 ConstantType(POD, CPX);
125
126 #undef CPX
127 #undef POD
128 }
129 }
130 // clang-format on
131
132 Type type() const { return kind; }
133
134 template <typename T>
135 T const& get() const {
136 return value.i64;
137 }
138
139 Type get_kind() const {
140 13 return kind;
141 }
142
143 private:
144 // ast.Str, ast.Bytes, ast.NameConstant, ast.Ellipsis
145 union ValueVariant {
146 ValueVariant() {}
147 ~ValueVariant(){}
148
149 ; // clang-format off
150 #define ATTR(type, name) type name;
151 #define POD(kind, type, name) ATTR(type, name)
152 #define CPX(kind, type, name) ATTR(type, name)
153
154 ConstantType(POD, CPX);
155
156 #undef CPX
157 #undef POD
158 #undef ATTR
159 // clang-format on
160 };
161
162 ValueVariant value;
163 Type kind = TInvalid;
164
165 void _print_object(std::ostream& out) const;
166
167 template <typename T>
168 void set_cpx(Type ktype, T& memory, const T& data) {
169
1/2
✓ Branch 0 taken 218 times.
✗ Branch 1 not taken.
218 if (kind != ktype) {
170
1/4
✓ Branch 2 taken 218 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
218 new (&memory) T(data);
171 } else {
172 memory = data;
173 }
174 218 kind = ktype;
175 218 }
176
177 ; // clang-format off
178 #define POD(kind, type, name)
179 #define CPX(kind, type, name)\
180 void set_##name(const type &data) { set_cpx(T##kind, value.name, data); }
181
182 ConstantType(POD, CPX);
183
184 #undef CPX
185 #undef POD
186 // clang-format on
187
188 void remove_cpx() {
189 // clang-format off
190
7/16
✓ Branch 0 taken 1133 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1323 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 220 times.
✓ Branch 11 taken 134 times.
✓ Branch 12 taken 42 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 218 times.
✗ Branch 15 not taken.
3074 switch (kind) {
191
192 #define POD(kind, type, name) case T##kind: return;
193 #define CPX(kind, type, name) case T##kind: value.name.~type(); break;
194
195 3074 ConstantType(POD, CPX);
196
197 #undef CPX
198 #undef POD
199 }
200 // clang-format on
201 }
202
203 void copy_union(Type k, ValueVariant const& v) {
204
1/2
✓ Branch 0 taken 1130 times.
✗ Branch 1 not taken.
1130 if (kind != k) {
205 1130 remove_cpx();
206 }
207
208
6/16
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 831 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 113 times.
✓ Branch 11 taken 57 times.
✓ Branch 12 taken 18 times.
✓ Branch 13 taken 2 times.
✓ Branch 14 taken 109 times.
✗ Branch 15 not taken.
1130 switch (k) {
209 ; // clang-format off
210 #define POD(k, type, name)\
211 case T##k:{\
212 value.name = v.name;\
213 break;\
214 }
215
216 #define CPX(k, type, name)\
217 case T##k:{\
218 set_##name(v.name);\
219 break;\
220 }
221
222 1130 ConstantType(POD, CPX);
223
224 #undef CPX
225 #undef POD
226 // clang-format on
227 }
228 1130 kind = k;
229 1130 }
230 };
231
232 // Explicit specialization needs to be declare outisde of the class
233 #define POD(kind, type, name) \
234 template <> \
235 inline type const& ConstantValue::get<type>() const { \
236 return value.name; \
237 }
238 #define CPX(kind, type, name) \
239 template <> \
240 inline type const& ConstantValue::get<type>() const { \
241 return value.name; \
242 }
243
244 ConstantType(POD, CPX);
245
246 #undef CPX
247 #undef POD
248
249 } // namespace lython
250
251 #endif
252