@@ -23,19 +23,17 @@ type ExprWidth struct {
23
23
bool is_signed;
24
24
}
25
25
26
- fn ExprWidth ExprWidth.mergeSmaller(ExprWidth* w1, ExprWidth* w2) {
26
+ fn ExprWidth ExprWidth.mergeSmaller(ExprWidth w1, ExprWidth w2) {
27
27
ExprWidth result;
28
- if (w2.width < w1.width) result.width = w2.width;
29
- else result.width = w1.width;
30
- result.is_signed = w1.is_signed || w2.is_signed;
28
+ result.width = (w1.width < w2.width) ? w1.width : w2.width;
29
+ result.is_signed = w1.is_signed | w2.is_signed;
31
30
return result;
32
31
}
33
32
34
- fn ExprWidth ExprWidth.mergeWider(ExprWidth* w1, ExprWidth* w2) {
33
+ fn ExprWidth ExprWidth.mergeWider(ExprWidth w1, ExprWidth w2) {
35
34
ExprWidth result;
36
- if (w2.width > w1.width) result.width = w2.width;
37
- else result.width = w1.width;
38
- result.is_signed = w1.is_signed || w2.is_signed;
35
+ result.width = (w1.width > w2.width) ? w1.width : w2.width;
36
+ result.is_signed = w1.is_signed | w2.is_signed;
39
37
return result;
40
38
}
41
39
@@ -44,13 +42,8 @@ fn ExprWidth getExprWidth(const Expr* e) {
44
42
45
43
if (e.isCtv()) {
46
44
Value v = ctv_analyser.get_value(e);
47
- if (v.isNegative()) {
48
- result.width = v.getWidth();
49
- result.is_signed = true;
50
- } else {
51
- result.width = v.getWidth();
52
- result.is_signed = false;
53
- }
45
+ result.width = v.getWidth();
46
+ result.is_signed = v.isNegative();
54
47
return result;
55
48
}
56
49
@@ -63,26 +56,13 @@ fn ExprWidth getExprWidth(const Expr* e) {
63
56
case Nil:
64
57
break;
65
58
case Identifier:
66
- QualType qt = e.getType();
67
- qt = qt.getCanonicalType();
68
- if (qt.isBuiltin()) {
69
- BuiltinType* bi = qt.getBuiltin();
70
- result.width = cast<u8>(bi.getWidth());
71
- result.is_signed = bi.isSigned();
72
- } else {
73
- // pointer or something
74
- result.width = cast<u8>(ast.getWordSize() * 8);
75
- result.is_signed = true;
76
- }
77
- return result;
59
+ return getTypeWidth(e.getType());
78
60
case Type:
79
61
break;
80
62
case Call:
81
63
return getTypeWidth(e.getType());
82
64
case InitList:
83
- break;
84
65
case FieldDesignatedInit:
85
- break;
86
66
case ArrayDesignatedInit:
87
67
break;
88
68
case BinaryOperator:
@@ -92,27 +72,19 @@ fn ExprWidth getExprWidth(const Expr* e) {
92
72
case ConditionalOperator:
93
73
return getCondOpWidth(cast<ConditionalOperator*>(e));
94
74
case Builtin:
75
+ // TODO ToContainer -> width = 64
95
76
break;
96
77
case ArraySubscript:
78
+ // TODO BitOffset -> specific width
97
79
case Member:
98
- QualType qt = e.getType();
99
- qt = qt.getCanonicalType();
100
- if (qt.isPointer()) {
101
- result.width = 64; // TODO or 32
102
- result.is_signed = false;
103
- return result;
104
- }
105
- assert(qt.isBuiltin());
106
- BuiltinType* bi = qt.getBuiltin();
107
- result.width = cast<u8>(bi.getWidth());
108
- result.is_signed = bi.isSigned();
109
- return result;
80
+ return getTypeWidth(e.getType());
110
81
case Paren:
111
82
const ParenExpr* p = cast<ParenExpr*>(e);
112
83
return getExprWidth(p.getInner());
113
84
case BitOffset:
114
85
break;
115
86
case ExplicitCast:
87
+ // TODO: explicit cast may reduce signed values
116
88
QualType qt = e.getType();
117
89
qt = qt.getCanonicalType();
118
90
assert(qt.isBuiltin());
@@ -127,7 +99,7 @@ fn ExprWidth getExprWidth(const Expr* e) {
127
99
RangeExpr* b = cast<RangeExpr*>(e);
128
100
ExprWidth lhs = getExprWidth(b.getLHS());
129
101
ExprWidth rhs = getExprWidth(b.getRHS());
130
- return ExprWidth.mergeWider(& lhs, & rhs);
102
+ return ExprWidth.mergeWider(lhs, rhs);
131
103
}
132
104
133
105
e.dump();
@@ -138,7 +110,7 @@ fn ExprWidth getExprWidth(const Expr* e) {
138
110
fn ExprWidth getCondOpWidth(const ConditionalOperator* c) {
139
111
ExprWidth lhs = getExprWidth(c.getLHS());
140
112
ExprWidth rhs = getExprWidth(c.getRHS());
141
- return ExprWidth.mergeWider(& lhs, & rhs);
113
+ return ExprWidth.mergeWider(lhs, rhs);
142
114
}
143
115
144
116
fn ExprWidth getUnaryOpWidth(const UnaryOperator* u) {
@@ -183,37 +155,36 @@ fn ExprWidth getBinOpWidth(const BinaryOperator* b) {
183
155
case Multiply:
184
156
break;
185
157
case Divide:
186
- break ;
158
+ return getExprWidth(b.getLHS()) ;
187
159
case Remainder:
188
- // TODO special
189
- break;
160
+ return getExprWidth(b.getRHS());
190
161
case Add:
191
- break;
192
162
case Subtract:
193
163
break;
194
164
case ShiftLeft:
195
- break;
165
+ ExprWidth result = getExprWidth(b.getLHS());
166
+ if (result.width < 31) { result.width = 31; result.is_signed = true; }
167
+ return result;
196
168
case ShiftRight:
197
- break ;
169
+ return getExprWidth(b.getLHS()) ;
198
170
case LessThan:
199
171
case GreaterThan:
200
172
case LessEqual:
201
173
case GreaterEqual:
202
174
case Equal:
203
175
case NotEqual:
204
- ExprWidth result = { 1, 0 }
176
+ ExprWidth result = { .width = 1, .is_signed = false }
205
177
return result;
206
178
case And:
207
179
ExprWidth l = getExprWidth(b.getLHS());
208
180
ExprWidth r = getExprWidth(b.getRHS());
209
- return ExprWidth.mergeSmaller(& l, & r);
181
+ return ExprWidth.mergeSmaller(l, r);
210
182
case Xor:
211
- break;
212
183
case Or:
213
184
break;
214
185
case LAnd:
215
186
case LOr:
216
- ExprWidth result = { 1, 0 }
187
+ ExprWidth result = { .width = 1, .is_signed = false }
217
188
return result;
218
189
case Assign:
219
190
case MulAssign:
@@ -226,25 +197,29 @@ fn ExprWidth getBinOpWidth(const BinaryOperator* b) {
226
197
case AndAssign:
227
198
case XorAssign:
228
199
case OrAssign:
200
+ // TODO: refine this
229
201
return getExprWidth(b.getLHS());
230
202
}
231
203
232
204
ExprWidth lhs = getExprWidth(b.getLHS());
233
205
ExprWidth rhs = getExprWidth(b.getRHS());
234
- return ExprWidth.mergeWider(& lhs, & rhs);
206
+ return ExprWidth.mergeWider(lhs, rhs);
235
207
}
236
208
237
209
fn ExprWidth getTypeWidth(QualType qt) {
238
- if (qt.isPointer()) {
239
- // TODO or 32
240
- ExprWidth result = { .width = 64, .is_signed = false }
210
+ qt = qt.getCanonicalType();
211
+ if (qt.isEnum()) {
212
+ EnumType* et = qt.getEnumType();
213
+ qt = et.getImplType();
214
+ }
215
+ if (qt.isBuiltin()) {
216
+ const BuiltinType* bi = qt.getBuiltin();
217
+ ExprWidth result = { .width = cast<u8>(bi.getWidth()), .is_signed = bi.isSigned() }
241
218
return result;
242
219
}
243
- assert(qt.isBuiltin());
244
- const BuiltinType* bi = qt.getBuiltin();
245
- ExprWidth result;
246
- result.width = cast<u8>(bi.getWidth());
247
- result.is_signed = bi.isSigned();
220
+ // pointer or something
221
+ // TODO or 32
222
+ ExprWidth result = { .width = cast<u8>(ast.getWordSize() * 8), .is_signed = false }
248
223
return result;
249
224
}
250
225
0 commit comments