Skip to content

Commit e528762

Browse files
committed
Switch to bison location tracking
Locations for AST nodes are now tracked with the help of bison location tracking. This is more accurate than what we currently do and easier to extend with more information. A zend_ast_loc structure is introduced, which is used for the location stack. Currently it only holds the start lineno, but can be extended to also hold end lineno and offset/column information in the future. All AST constructors now accept a zend_ast_loc* as first argument, and will use it to determine their lineno. Previously this used either the CG(zend_lineno), or the smallest AST lineno of child nodes. On the parser side, the location structure for a whole rule can be obtained using the &@$ character salad.
1 parent 1cf84f1 commit e528762

File tree

9 files changed

+449
-488
lines changed

9 files changed

+449
-488
lines changed

Zend/zend_ast.c

Lines changed: 56 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -45,83 +45,83 @@ static inline size_t zend_ast_list_size(uint32_t children) {
4545
return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children;
4646
}
4747

48-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) {
48+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(zend_ast_loc *loc, znode *node) {
4949
zend_ast_znode *ast;
5050

5151
ast = zend_ast_alloc(sizeof(zend_ast_znode));
5252
ast->kind = ZEND_AST_ZNODE;
5353
ast->attr = 0;
54-
ast->lineno = CG(zend_lineno);
54+
ast->lineno = loc->start_line;
5555
ast->node = *node;
5656
return (zend_ast *) ast;
5757
}
5858

59-
static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) {
59+
static zend_always_inline zend_ast * zend_ast_create_zval_int(
60+
zend_ast_loc *loc, zval *zv, uint32_t attr) {
6061
zend_ast_zval *ast;
6162

6263
ast = zend_ast_alloc(sizeof(zend_ast_zval));
6364
ast->kind = ZEND_AST_ZVAL;
6465
ast->attr = attr;
6566
ZVAL_COPY_VALUE(&ast->val, zv);
66-
Z_LINENO(ast->val) = lineno;
67+
Z_LINENO(ast->val) = loc->start_line;
6768
return (zend_ast *) ast;
6869
}
6970

70-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno) {
71-
return zend_ast_create_zval_int(zv, 0, lineno);
71+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(
72+
zend_ast_loc *loc, zval *zv, zend_ast_attr attr) {
73+
return zend_ast_create_zval_int(loc, zv, attr);
7274
}
7375

74-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) {
75-
return zend_ast_create_zval_int(zv, attr, CG(zend_lineno));
76+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zend_ast_loc *loc, zval *zv) {
77+
return zend_ast_create_zval_int(loc, zv, 0);
7678
}
7779

78-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv) {
79-
return zend_ast_create_zval_int(zv, 0, CG(zend_lineno));
80-
}
81-
82-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str) {
80+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_ast_loc *loc, zend_string *str) {
8381
zval zv;
8482
ZVAL_STR(&zv, str);
85-
return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
83+
return zend_ast_create_zval_int(loc, &zv, 0);
8684
}
8785

88-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval) {
86+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_ast_loc *loc, zend_long lval) {
8987
zval zv;
9088
ZVAL_LONG(&zv, lval);
91-
return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
89+
return zend_ast_create_zval_int(loc, &zv, 0);
9290
}
9391

94-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr) {
92+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(
93+
zend_ast_loc *loc, zend_string *name, zend_ast_attr attr) {
9594
zend_ast_zval *ast;
9695

9796
ast = zend_ast_alloc(sizeof(zend_ast_zval));
9897
ast->kind = ZEND_AST_CONSTANT;
9998
ast->attr = attr;
10099
ZVAL_STR(&ast->val, name);
101-
Z_LINENO(ast->val) = CG(zend_lineno);
100+
Z_LINENO(ast->val) = loc->start_line;
102101
return (zend_ast *) ast;
103102
}
104103

105-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name) {
104+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(
105+
zend_ast_loc *loc, zend_ast *class_name, zend_ast *name) {
106106
zend_string *name_str = zend_ast_get_str(name);
107107
if (zend_string_equals_literal_ci(name_str, "class")) {
108108
zend_string_release(name_str);
109-
return zend_ast_create(ZEND_AST_CLASS_NAME, class_name);
109+
return zend_ast_create(loc, ZEND_AST_CLASS_NAME, class_name);
110110
} else {
111-
return zend_ast_create(ZEND_AST_CLASS_CONST, class_name, name);
111+
return zend_ast_create(loc, ZEND_AST_CLASS_CONST, class_name, name);
112112
}
113113
}
114114

115115
ZEND_API zend_ast *zend_ast_create_decl(
116-
zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
116+
zend_ast_loc *loc, zend_ast_kind kind, uint32_t flags, zend_string *doc_comment,
117117
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3
118118
) {
119119
zend_ast_decl *ast;
120120

121121
ast = zend_ast_alloc(sizeof(zend_ast_decl));
122122
ast->kind = kind;
123123
ast->attr = 0;
124-
ast->start_lineno = start_lineno;
124+
ast->start_lineno = loc->start_line;
125125
ast->end_lineno = CG(zend_lineno);
126126
ast->flags = flags;
127127
ast->lex_pos = LANG_SCNG(yy_text);
@@ -136,63 +136,50 @@ ZEND_API zend_ast *zend_ast_create_decl(
136136
}
137137

138138
#if ZEND_AST_SPEC
139-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind) {
139+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_loc *loc, zend_ast_kind kind) {
140140
zend_ast *ast;
141141

142142
ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 0);
143143
ast = zend_ast_alloc(zend_ast_size(0));
144144
ast->kind = kind;
145145
ast->attr = 0;
146-
ast->lineno = CG(zend_lineno);
146+
ast->lineno = loc->start_line;
147147

148148
return ast;
149149
}
150150

151-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child) {
151+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(
152+
zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child) {
152153
zend_ast *ast;
153-
uint32_t lineno;
154154

155155
ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 1);
156156
ast = zend_ast_alloc(zend_ast_size(1));
157157
ast->kind = kind;
158158
ast->attr = 0;
159159
ast->child[0] = child;
160-
if (child) {
161-
lineno = zend_ast_get_lineno(child);
162-
} else {
163-
lineno = CG(zend_lineno);
164-
}
165-
ast->lineno = lineno;
166-
ast->lineno = lineno;
160+
ast->lineno = loc->start_line;
167161

168162
return ast;
169163
}
170164

171-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
165+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(
166+
zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
172167
zend_ast *ast;
173-
uint32_t lineno;
174168

175169
ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 2);
176170
ast = zend_ast_alloc(zend_ast_size(2));
177171
ast->kind = kind;
178172
ast->attr = 0;
179173
ast->child[0] = child1;
180174
ast->child[1] = child2;
181-
if (child1) {
182-
lineno = zend_ast_get_lineno(child1);
183-
} else if (child2) {
184-
lineno = zend_ast_get_lineno(child2);
185-
} else {
186-
lineno = CG(zend_lineno);
187-
}
188-
ast->lineno = lineno;
175+
ast->lineno = loc->start_line;
189176

190177
return ast;
191178
}
192179

193-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3) {
180+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(
181+
zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3) {
194182
zend_ast *ast;
195-
uint32_t lineno;
196183

197184
ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 3);
198185
ast = zend_ast_alloc(zend_ast_size(3));
@@ -201,23 +188,14 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast
201188
ast->child[0] = child1;
202189
ast->child[1] = child2;
203190
ast->child[2] = child3;
204-
if (child1) {
205-
lineno = zend_ast_get_lineno(child1);
206-
} else if (child2) {
207-
lineno = zend_ast_get_lineno(child2);
208-
} else if (child3) {
209-
lineno = zend_ast_get_lineno(child3);
210-
} else {
211-
lineno = CG(zend_lineno);
212-
}
213-
ast->lineno = lineno;
191+
ast->lineno = loc->start_line;
214192

215193
return ast;
216194
}
217195

218-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) {
196+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(
197+
zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) {
219198
zend_ast *ast;
220-
uint32_t lineno;
221199

222200
ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 4);
223201
ast = zend_ast_alloc(zend_ast_size(4));
@@ -227,64 +205,45 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast
227205
ast->child[1] = child2;
228206
ast->child[2] = child3;
229207
ast->child[3] = child4;
230-
if (child1) {
231-
lineno = zend_ast_get_lineno(child1);
232-
} else if (child2) {
233-
lineno = zend_ast_get_lineno(child2);
234-
} else if (child3) {
235-
lineno = zend_ast_get_lineno(child3);
236-
} else if (child4) {
237-
lineno = zend_ast_get_lineno(child4);
238-
} else {
239-
lineno = CG(zend_lineno);
240-
}
241-
ast->lineno = lineno;
208+
ast->lineno = loc->start_line;
242209

243210
return ast;
244211
}
245212

246-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind) {
213+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_loc *loc, zend_ast_kind kind) {
247214
zend_ast *ast;
248215
zend_ast_list *list;
249216

250217
ast = zend_ast_alloc(zend_ast_list_size(4));
251218
list = (zend_ast_list *) ast;
252219
list->kind = kind;
253220
list->attr = 0;
254-
list->lineno = CG(zend_lineno);
221+
list->lineno = loc->start_line;
255222
list->children = 0;
256223

257224
return ast;
258225
}
259226

260-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child) {
227+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(
228+
zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child) {
261229
zend_ast *ast;
262230
zend_ast_list *list;
263-
uint32_t lineno;
264231

265232
ast = zend_ast_alloc(zend_ast_list_size(4));
266233
list = (zend_ast_list *) ast;
267234
list->kind = kind;
268235
list->attr = 0;
269236
list->children = 1;
270237
list->child[0] = child;
271-
if (child) {
272-
lineno = zend_ast_get_lineno(child);
273-
if (lineno > CG(zend_lineno)) {
274-
lineno = CG(zend_lineno);
275-
}
276-
} else {
277-
lineno = CG(zend_lineno);
278-
}
279-
list->lineno = lineno;
238+
list->lineno = loc->start_line;
280239

281240
return ast;
282241
}
283242

284-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
243+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(
244+
zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
285245
zend_ast *ast;
286246
zend_ast_list *list;
287-
uint32_t lineno;
288247

289248
ast = zend_ast_alloc(zend_ast_list_size(4));
290249
list = (zend_ast_list *) ast;
@@ -293,82 +252,57 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zen
293252
list->children = 2;
294253
list->child[0] = child1;
295254
list->child[1] = child2;
296-
if (child1) {
297-
lineno = zend_ast_get_lineno(child1);
298-
if (lineno > CG(zend_lineno)) {
299-
lineno = CG(zend_lineno);
300-
}
301-
} else if (child2) {
302-
lineno = zend_ast_get_lineno(child2);
303-
if (lineno > CG(zend_lineno)) {
304-
lineno = CG(zend_lineno);
305-
}
306-
} else {
307-
list->children = 0;
308-
lineno = CG(zend_lineno);
309-
}
310-
list->lineno = lineno;
255+
list->lineno = loc->start_line;
311256

312257
return ast;
313258
}
314259
#else
315-
static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) {
260+
static zend_ast *zend_ast_create_from_va_list(
261+
zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, va_list va) {
316262
uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
317263
zend_ast *ast;
318264

319265
ast = zend_ast_alloc(zend_ast_size(children));
320266
ast->kind = kind;
321267
ast->attr = attr;
322-
ast->lineno = (uint32_t) -1;
323-
324-
for (i = 0; i < children; ++i) {
325-
ast->child[i] = va_arg(va, zend_ast *);
326-
if (ast->child[i] != NULL) {
327-
uint32_t lineno = zend_ast_get_lineno(ast->child[i]);
328-
if (lineno < ast->lineno) {
329-
ast->lineno = lineno;
330-
}
331-
}
332-
}
333-
334-
if (ast->lineno == UINT_MAX) {
335-
ast->lineno = CG(zend_lineno);
336-
}
268+
ast->lineno = loc->start_line;
337269

338270
return ast;
339271
}
340272

341-
ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...) {
273+
ZEND_API zend_ast *zend_ast_create_ex(
274+
zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, ...) {
342275
va_list va;
343276
zend_ast *ast;
344277

345278
va_start(va, attr);
346-
ast = zend_ast_create_from_va_list(kind, attr, va);
279+
ast = zend_ast_create_from_va_list(loc, kind, attr, va);
347280
va_end(va);
348281

349282
return ast;
350283
}
351284

352-
ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...) {
285+
ZEND_API zend_ast *zend_ast_create(zend_ast_loc *loc, zend_ast_kind kind, ...) {
353286
va_list va;
354287
zend_ast *ast;
355288

356289
va_start(va, kind);
357-
ast = zend_ast_create_from_va_list(kind, 0, va);
290+
ast = zend_ast_create_from_va_list(loc, kind, 0, va);
358291
va_end(va);
359292

360293
return ast;
361294
}
362295

363-
ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...) {
296+
ZEND_API zend_ast *zend_ast_create_list(
297+
zend_ast_loc *loc, uint32_t init_children, zend_ast_kind kind, ...) {
364298
zend_ast *ast;
365299
zend_ast_list *list;
366300

367301
ast = zend_ast_alloc(zend_ast_list_size(4));
368302
list = (zend_ast_list *) ast;
369303
list->kind = kind;
370304
list->attr = 0;
371-
list->lineno = CG(zend_lineno);
305+
list->lineno = loc->start_line;
372306
list->children = 0;
373307

374308
{
@@ -378,12 +312,6 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki
378312
for (i = 0; i < init_children; ++i) {
379313
zend_ast *child = va_arg(va, zend_ast *);
380314
ast = zend_ast_list_add(ast, child);
381-
if (child != NULL) {
382-
uint32_t lineno = zend_ast_get_lineno(child);
383-
if (lineno < ast->lineno) {
384-
ast->lineno = lineno;
385-
}
386-
}
387315
}
388316
va_end(va);
389317
}

0 commit comments

Comments
 (0)