GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/parse/scan2.c Lines: 406 409 99.3 %
Date: 2020-09-14 00:22:58 Branches: 296 366 80.9 %

Line Branch Exec Source
1
#include "gwion_util.h"
2
#include "gwion_ast.h"
3
#include "gwion_env.h"
4
#include "vm.h"
5
#include "template.h"
6
#include "traverse.h"
7
#include "parse.h"
8
#include "operator.h"
9
#include "object.h"
10
#include "instr.h"
11
#include "import.h"
12
13
ANN static m_bool scan2_stmt(const Env, const Stmt);
14
ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
15
16
30
ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
17
60
  struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
18
30
    .scope=env->scope->depth, .flag=ae_flag_scan2 };
19
30
  return envset_run(&es, t);
20
}
21
22
21422
ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
23
21422
  const Type t = get_type(decl->type);
24

21422
  if(t->e->def && !GET_FLAG(t, scan2))
25
24
    CHECK_BB(ensure_scan2(env, t))
26
21422
  Var_Decl_List list = decl->list;
27
  do {
28
21430
    const Var_Decl var = list->self;
29
21430
    const Exp array = var->array ? var->array->exp : NULL;
30
21430
    if(array)
31
35
      CHECK_BB(scan2_exp(env, array))
32
21430
    nspc_add_value(env->curr, var->xid, var->value);
33
21430
  } while((list = list->next));
34
21422
  return GW_OK;
35
}
36
37
21422
ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) {
38
21422
  const m_bool global = GET_FLAG(decl->td, global);
39
21422
  const m_uint scope = !global ? env->scope->depth : env_push_global(env);
40
21422
  const m_bool ret = scan2_decl(env, decl);
41
21422
  if(global)
42
12
    env_pop(env, scope);
43
21422
  return ret;
44
}
45
46
16550
ANN static m_bool scan2_args(const Func_Def f) {
47
16550
  Arg_List list = f->base->args;
48
  do {
49
23741
    const Value v = list->var_decl->value;
50
23741
    v->from->offset = f->stack_depth;
51
23741
    f->stack_depth += v->type->size;
52
23741
  } while((list = list->next));
53
16550
  return GW_OK;
54
}
55
56
42323
ANN static Value scan2_func_assign(const Env env, const Func_Def d,
57
    const Func f, const Value v) {
58
42323
  valuefrom(env, v->from);
59
42323
  SET_FLAG(v, func | ae_flag_const);
60
42323
  if(!env->class_def)
61
193
    SET_FLAG(v, global);
62
  else {
63
42130
    if(GET_FLAG(f, member))
64
41391
      SET_FLAG(v, member);
65
739
    else SET_FLAG(v, static);
66

42130
    SET_ACCESS(d, v)
67
  }
68
42323
  d->base->func = v->d.func_ref = f;
69
42323
  return f->value_ref = v;
70
}
71
72
73
71
ANN m_bool scan2_fptr_def(const Env env NUSED, const Fptr_Def fptr) {
74
71
  if(!tmpl_base(fptr->base->tmpl)) {
75
56
    const Func_Def def = fptr->type->e->d.func->def;
76
56
    if(def->base->args) {
77
24
      RET_NSPC(scan2_args(def))
78
    }
79
  } else
80
15
    SET_FLAG(fptr->type, func);
81
47
  return GW_OK;
82
}
83
84
731
ANN m_bool scan2_type_def(const Env env, const Type_Def tdef) {
85
731
  if(!tdef->type->e->def) return GW_OK;
86
8
  return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->def) : GW_OK;
87
}
88
89
2122
ANN static inline Value prim_value(const Env env, const Symbol s) {
90
2122
  const Value value = nspc_lookup_value1(env->curr, s);
91
2122
  if(env->class_def)
92
401
    return value ?: find_value(env->class_def, s);
93
1721
  return value;
94
}
95
96
12
ANN static m_bool scan2_range(const Env env, Range *range) {
97
12
  if(range->start)
98
11
    CHECK_BB(scan2_exp(env, range->start))
99
12
  if(range->end)
100
8
    CHECK_BB(scan2_exp(env, range->end))
101
12
  return GW_OK;
102
}
103
104
4401
ANN static inline m_bool scan2_prim(const Env env, const Exp_Primary* prim) {
105

7723
  if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
106
3322
        prim->prim_type == ae_prim_interp)
107
1084
    CHECK_BB(scan2_exp(env, prim->d.exp))
108
3317
  else if(prim->prim_type == ae_prim_id) {
109
2122
    const Value v = prim_value(env, prim->d.var);
110
2122
    if(v)
111
1502
      SET_FLAG(v, used);
112

1195
  } else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
113
22
    return scan2_exp(env, prim->d.array->exp);
114
1173
  else if(prim->prim_type == ae_prim_range)
115
3
    return scan2_range(env, prim->d.range);
116
4376
  return GW_OK;
117
}
118
119
30
ANN static inline m_bool scan2_exp_array(const Env env, const Exp_Array* array) {
120
30
  CHECK_BB(scan2_exp(env, array->base))
121
30
  return scan2_exp(env, array->array->exp);
122
}
123
124
9
ANN static inline m_bool scan2_exp_slice(const Env env, const Exp_Slice* exp) {
125
9
  CHECK_BB(scan2_exp(env, exp->base))
126
9
  return scan2_range(env, exp->range);
127
}
128
129
1275
ANN static m_bool multi_decl(const Env env, const Exp e, const Symbol op) {
130
1275
  if(e->exp_type == ae_exp_decl) {
131
158
    if(e->d.exp_decl.list->next)
132
1
      ERR_B(e->pos, _("cant '%s' from/to a multi-variable declaration."), s_name(op))
133
157
    SET_FLAG(e->d.exp_decl.list->self->value, used);
134
  }
135
1274
  return GW_OK;
136
}
137
138
638
ANN static inline m_bool scan2_exp_binary(const Env env, const Exp_Binary* bin) {
139
638
  CHECK_BB(scan2_exp(env, bin->lhs))
140
638
  CHECK_BB(scan2_exp(env, bin->rhs))
141
638
  CHECK_BB(multi_decl(env, bin->lhs, bin->op))
142
637
  return multi_decl(env, bin->rhs, bin->op);
143
}
144
145
40
ANN static inline m_bool scan2_exp_cast(const Env env, const Exp_Cast* cast) {
146
40
  return scan2_exp(env, cast->exp);
147
}
148
149
37
ANN static inline m_bool scan2_exp_post(const Env env, const Exp_Postfix* post) {
150
37
  return scan2_exp(env, post->exp);
151
}
152
153
552
ANN static inline m_bool scan2_exp_call(const Env env, const Exp_Call* exp_call) {
154
552
  if(exp_call->tmpl)
155
32
    return GW_OK;
156
520
  CHECK_BB(scan2_exp(env, exp_call->func))
157
520
  const Exp args = exp_call->args;
158
520
  return args ? scan2_exp(env, args) : GW_OK;
159
}
160
161
553
ANN static inline m_bool scan2_exp_dot(const Env env, const Exp_Dot* member) {
162
553
  return scan2_exp(env, member->base);
163
}
164
165
10
ANN static inline m_bool scan2_exp_if(const Env env, const Exp_If* exp_if) {
166
10
  CHECK_BB(scan2_exp(env, exp_if->cond))
167

10
  CHECK_BB(scan2_exp(env, exp_if->if_exp ?: exp_if->cond))
168
10
  return scan2_exp(env, exp_if->else_exp);
169
}
170
171
141
ANN static m_bool scan2_exp_unary(const Env env, const Exp_Unary * unary) {
172

141
  if((unary->op == insert_symbol("spork") || unary->op == insert_symbol("fork")) && unary->code) {
173
25
    RET_NSPC(scan2_stmt(env, unary->code))
174
116
  } else if(unary->exp)
175
91
    return scan2_exp(env, unary->exp);
176
25
  return GW_OK;
177
}
178
179
11
ANN static inline m_bool _scan2_stmt_match_case(const restrict Env env, const Stmt_Match stmt) {
180
11
  CHECK_BB(scan2_exp(env, stmt->cond))
181
11
  if(stmt->when)
182
4
    CHECK_BB(scan2_exp(env, stmt->when))
183
11
  return scan2_stmt_list(env, stmt->list);
184
}
185
186
11
ANN static inline m_bool scan2_stmt_match_case(const restrict Env env, const Stmt_Match stmt) {
187
11
  RET_NSPC(_scan2_stmt_match_case(env, stmt))
188
}
189
190
7
ANN static inline m_bool _scan2_stmt_match(const restrict Env env, const Stmt_Match stmt) {
191
7
  if(stmt->where)
192
2
    CHECK_BB(scan2_stmt(env, stmt->where))
193
7
  Stmt_List list = stmt->list;
194
11
  do CHECK_BB(scan2_stmt_match_case(env, &list->stmt->d.stmt_match))
195
11
  while((list = list->next));
196
7
  return GW_OK;
197
}
198
199
7
ANN static inline m_bool scan2_stmt_match(const restrict Env env, const Stmt_Match stmt) {
200
7
  CHECK_BB(scan2_exp(env, stmt->cond))
201
7
  RET_NSPC(_scan2_stmt_match(env, stmt))
202
}
203
204
#define scan2_exp_lambda dummy_func
205

27816
HANDLE_EXP_FUNC(scan2, m_bool, Env)
206
207
#define scan2_stmt_func(name, type, prolog, exp) describe_stmt_func(scan2, name, type, prolog, exp)
208

26
scan2_stmt_func(flow, Stmt_Flow,, !(scan2_exp(env, stmt->cond) < 0 ||
209
    scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
210

10
scan2_stmt_func(varloop, Stmt_VarLoop,, !(scan2_exp(env, stmt->exp) < 0 ||
211
    scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
212


11
scan2_stmt_func(for, Stmt_For,, !(scan2_stmt(env, stmt->c1) < 0 ||
213
    scan2_stmt(env, stmt->c2) < 0 ||
214
    (stmt->c3 && scan2_exp(env, stmt->c3) < 0) ||
215
    scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
216

11
scan2_stmt_func(auto, Stmt_Auto,, !(scan2_exp(env, stmt->exp) < 0 ||
217
    scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
218

8
scan2_stmt_func(loop, Stmt_Loop,, !(scan2_exp(env, stmt->cond) < 0 ||
219
    scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
220


39
scan2_stmt_func(if, Stmt_If,, !(scan2_exp(env, stmt->cond) < 0 ||
221
    scan2_stmt(env, stmt->if_body) < 0 ||
222
    (stmt->else_body && scan2_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
223
224
456
ANN static inline m_bool scan2_stmt_code(const Env env, const Stmt_Code stmt) {
225
456
  if(stmt->stmt_list)
226
393
    { RET_NSPC(scan2_stmt_list(env, stmt->stmt_list)) }
227
63
  return GW_OK;
228
}
229
230
2482
ANN static inline m_bool scan2_stmt_exp(const Env env, const Stmt_Exp stmt) {
231
2482
  return stmt->val ? scan2_exp(env, stmt->val) : 1;
232
}
233
234
__attribute__((returns_nonnull))
235
8
ANN static Map scan2_label_map(const Env env) {
236
8
  Map m, label = env_label(env);
237
18
  const m_uint* key = env->class_def && !env->func ?
238
10
    (m_uint*)env->class_def : (m_uint*)env->func;
239
8
  if(!label->ptr)
240
7
    map_init(label);
241
8
  if(!(m = (Map)map_get(label, (vtype)key))) {
242
7
    m = new_map(env->gwion->mp);
243
7
    map_set(label, (vtype)key, (vtype)m);
244
  }
245
8
  return m;
246
}
247
248
15
ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) {
249
15
  if(stmt->is_label) {
250
8
    const Map m = scan2_label_map(env);
251
8
    if(map_get(m, (vtype)stmt->name))
252
1
      ERR_B(stmt_self(stmt)->pos, _("label '%s' already defined"), s_name(stmt->name))
253
7
    map_set(m, (vtype)stmt->name, (vtype)stmt);
254
7
    vector_init(&stmt->data.v);
255
  }
256
14
  return GW_OK;
257
}
258
259
18
ANN static m_bool scan2_union_decl(const Env env, const Decl_List list) {
260
18
  Decl_List l = list;
261
34
  do CHECK_BB(scan2_exp_decl(env, &l->self->d.exp_decl))
262
//  do CHECK_BB(scan2_exp(env, l->self))
263
34
  while((l = l->next));
264
18
  return GW_OK;
265
}
266
267
22
ANN m_bool scan2_union_def(const Env env, const Union_Def udef) {
268
22
  if(tmpl_base(udef->tmpl))
269
4
    return GW_OK;
270
18
  const m_uint scope = union_push(env, udef);
271
18
  const m_bool ret = scan2_union_decl(env, udef->l);
272
18
  union_pop(env, udef, scope);
273
18
  union_flag(udef, ae_flag_scan2);
274
18
  return ret;
275
}
276
277
278
#define scan2_stmt_while    scan2_stmt_flow
279
#define scan2_stmt_until    scan2_stmt_flow
280
#define scan2_stmt_continue (void*)dummy_func
281
#define scan2_stmt_break    (void*)dummy_func
282
#define scan2_stmt_return   scan2_stmt_exp
283
#define scan2_stmt_pp       dummy_func
284
285
DECL_STMT_FUNC(scan2, m_bool, Env)
286
287
2784
ANN static m_bool scan2_stmt(const Env env, const Stmt stmt) {
288
2784
  return scan2_stmt_func[stmt->stmt_type](env, &stmt->d);
289
}
290
291
2618
ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) {
292
2618
  do CHECK_BB(scan2_stmt(env, list->stmt))
293
2616
  while((list = list->next));
294
1095
  return GW_OK;
295
}
296
297
8637
ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) {
298
8637
  const m_bool base = tmpl_base(f->base->tmpl);
299
8637
  const m_bool tmpl = GET_FLAG(overload, template);
300

8637
  if(isa(overload->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, overload->type)) {
301
5
    if(!GET_FLAG(f, typedef))
302
      ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
303
  }
304


8637
  if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f, template)))
305
1
    ERR_B(f->pos, _("must overload template function with template"))
306
8636
  return GW_OK;
307
}
308
309
42323
ANN static Func scan_new_func(const Env env, const Func_Def f, const m_str name) {
310
42323
  const Func func = new_func(env->gwion->mp, name, f);
311
42323
  if(env->class_def) {
312
42130
    if(GET_FLAG(env->class_def, template))
313
15
      SET_FLAG(func, ref);
314
42130
    if(!GET_FLAG(f, static))
315
41391
      SET_FLAG(func, member);
316
  }
317
42323
  return func;
318
}
319
320
42323
ANN static Type func_type(const Env env, const Func func) {
321
42323
  const Type base = env->gwion->type[func->def->base->td ? et_function : et_lambda];
322
42323
  const Type t = type_copy(env->gwion->mp, base);
323
42323
  t->xid = ++env->scope->type_xid;
324
42323
  t->e->parent = base;
325
42323
  t->name = func->name;
326
42323
  t->e->owner = env->curr;
327
42323
  t->e->owner_class = env->class_def;
328
42323
  if(GET_FLAG(func, member))
329
41391
    t->size += SZ_INT;
330
42323
  t->e->d.func = func;
331
42323
  return t;
332
}
333
334
42323
ANN2(1,2) static Value func_value(const Env env, const Func f,
335
    const Value overload) {
336
42323
  const Type  t = func_type(env, f);
337
42323
  const Value v = new_value(env->gwion->mp, t, t->name);
338
42323
  valuefrom(env, v->from);
339
42323
  CHECK_OO(scan2_func_assign(env, f->def, f, v))
340
42323
  if(!overload) {
341
33693
    ADD_REF(v);
342
33693
    nspc_add_value_front(env->curr, f->def->base->xid, v);
343
8630
  } else if(overload->d.func_ref) {
344
8630
    f->next = overload->d.func_ref->next;
345
8630
    overload->d.func_ref->next = f;
346
  }
347
42323
  return v;
348
}
349
350
41964
ANN static m_bool scan2_func_def_builtin(MemPool p, const Func func, const m_str name) {
351
41964
  SET_FLAG(func, builtin);
352
41964
  SET_FLAG(func->value_ref, builtin);
353
41964
  func->code = new_vm_code(p, NULL, func->def->stack_depth, func->flag, name);
354
41964
  func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
355
41964
  return GW_OK;
356
}
357
358
61
ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Value overload) {
359
61
  const m_str name = s_name(f->base->xid);
360
61
  const Func func = scan_new_func(env, f, name);
361
61
  const Value value = func_value(env, func, overload);
362
61
  SET_FLAG(value, valid | ae_flag_template);
363
61
  SET_FLAG(value->type, func); // the only types with func flag, name could be better
364
61
  Type type = env->class_def;
365
61
  Nspc nspc = env->curr;
366
61
  uint i = 0;
367
  do {
368
67
    const Value v = nspc_lookup_value0(nspc, f->base->xid);
369
67
    if(v) {
370
67
      Func ff = v->d.func_ref;
371
67
      if(!ff)continue;
372
      do {
373
85
        if(ff->def == f) {
374
61
          ++i;
375
61
          continue;
376
        }
377
24
        if(compat_func(ff->def, f) > 0) {
378
6
          if(ff->value_ref->from->owner == env->curr)
379
            ERR_B(f->pos, "template function '%s' already defined with those arguments in this namespace", name)
380
6
          const Symbol sym = func_symbol(env, env->curr->name, name,
381
            "template", ff->vt_index);
382
6
          nspc_add_value(env->curr, sym, value);
383
6
          if(!overload) {
384
6
            ADD_REF(value)
385
6
            nspc_add_value(env->curr, f->base->xid, value);
386
          }
387
6
          func->vt_index = ff->vt_index;
388
6
          return GW_OK;
389
        }
390

79
      } while((ff = ff->next) && ++i);
391
   }
392

61
  } while(type && (type = type->e->parent) && (nspc = type->nspc));
393
55
  --i;
394
55
  const Symbol sym = func_symbol(env, env->curr->name, name, "template", i);
395
55
  nspc_add_value(env->curr, sym, value);
396
55
  if(!overload) {
397
46
    ADD_REF(value)
398
46
    nspc_add_value(env->curr, f->base->xid, value);
399
46
    nspc_add_func(env->curr, f->base->xid, func);
400
  } else
401
9
    func->vt_index = ++overload->from->offset;
402
55
  if(GET_FLAG(f, builtin)) {
403
2
    CHECK_BB(scan2_func_def_builtin(env->gwion->mp, func, func->name))
404
2
    SET_FLAG(func, builtin);
405
2
    SET_FLAG(value, builtin);
406
  }
407
55
  return GW_OK;
408
}
409
410
24
ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) {
411
24
  const m_str str = s_name(f->base->xid);
412
24
  struct Op_Func opfunc = { .ck=strcmp(str, "@implicit") ? 0 : opck_usr_implicit };
413
48
  struct Op_Import opi = { .ret=f->base->ret_type, .pos=f->pos,
414
24
      .data=(uintptr_t)f->base->func, .func=&opfunc };
415
24
  func_operator(f, &opi);
416
24
  CHECK_BB(add_op(env->gwion, &opi))
417
24
  operator_set_func(&opi);
418
24
  return GW_OK;
419
}
420
421
301
ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) {
422
301
  const Func former = env->func;
423
301
  env->func = f->base->func;
424
301
  CHECK_BB(scan2_stmt_code(env, &f->d.code->d.stmt_code))
425
301
  env->func = former;
426
301
  return GW_OK;
427
}
428
429
42262
ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
430
42262
  if(!GET_FLAG(f, builtin))
431
300
    SET_FLAG(f->base->func, pure);
432
42262
  if(f->base->xid == insert_symbol("@dtor"))
433
6
    SET_FLAG(env->class_def, dtor);
434
42262
}
435
436
63
ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
437
63
  const m_str name = s_name(f->base->xid);
438
  struct Vector_ v;
439
63
  ID_List id = f->base->tmpl->list;
440
63
  m_uint tlen = 0;
441
63
  vector_init(&v);
442
  do {
443
67
    const Type t = nspc_lookup_type0(env->curr, id->xid);
444
67
    if(!t)return NULL;
445
67
    vector_add(&v, (vtype)t);
446
67
    tlen += strlen(t->name);
447

67
  } while((id = id->next) && ++tlen);
448
63
  char tmpl_name[tlen + 2];
449
63
  m_str str = tmpl_name;
450
130
  for(m_uint i = 0; i < vector_size(&v); ++i) {
451
67
    const m_str s = ((Type)vector_at(&v, i))->name;
452
67
    strcpy(str, s);
453
67
    str += strlen(s);
454
67
    if(i + 1 < vector_size(&v))
455
4
      *str++ = ',';
456
  }
457
63
  tmpl_name[tlen+1] = '\0';
458
63
  vector_release(&v);
459
63
  const Symbol sym = func_symbol(env, env->curr->name, name, tmpl_name, (m_uint)f->base->tmpl->base);
460
63
  return s_name(sym);
461
}
462
463
464
42262
ANN2(1,2,4) static Value func_create(const Env env, const Func_Def f,
465
     const Value overload, const m_str name) {
466
42262
  const Func func = scan_new_func(env, f, name);
467
42262
  nspc_add_func(env->curr, insert_symbol(func->name), func);
468
42262
  const Value v = func_value(env, func, overload);
469
42262
  scan2_func_def_flag(env, f);
470
42262
  if(GET_FLAG(f, builtin))
471
41962
    CHECK_BO(scan2_func_def_builtin(env->gwion->mp, func, func->name))
472
42262
  nspc_add_value(env->curr, insert_symbol(func->name), v);
473
42262
  return v;
474
}
475
476
42268
ANN2(1,2) static m_str func_name(const Env env, const Func_Def f, const Value v) {
477
42268
  if(!f->base->tmpl) {
478
92959
    const Symbol sym  = func_symbol(env, env->curr->name,
479
50759
        s_name(f->base->xid), NULL, v ? ++v->from->offset : 0);
480
42200
    return s_name(sym);
481
  }
482
68
  return f->base->func ? f->base->func->name : func_tmpl_name(env, f);
483
}
484
485
42268
ANN2(1,2) m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) {
486
42268
  const m_str name = func_name(env, f, overload ?: NULL);
487
42268
  if(!name)return GW_ERROR;
488
42268
  const Func base = f->base->func;
489
42268
  if(!base)
490
42262
    CHECK_OB(func_create(env, f, overload, name))
491
  else
492
6
    f->base->func = base;
493
42268
  if(f->base->args)
494
16526
    CHECK_BB(scan2_args(f))
495

42268
  if(!GET_FLAG(f, builtin) && f->d.code)
496
301
    CHECK_BB(scan2_func_def_code(env, f))
497
42268
  if(!base) {
498
42262
    if(GET_FLAG(f, op))
499
24
      CHECK_BB(scan2_func_def_op(env, f))
500
42262
    SET_FLAG(f->base->func->value_ref, valid);
501
  }
502
42268
  return GW_OK;
503
}
504
505
42330
ANN m_bool scan2_fdef(const Env env, const Func_Def f) {
506
42330
  const Value overload = nspc_lookup_value2(env->curr, f->base->xid); // try0
507
42330
  if(overload)
508
8637
    CHECK_BB(scan2_func_def_overload(env, f, overload))
509
42329
  return (!tmpl_base(f->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)(env, f, overload);
510
}
511
512
__attribute__((returns_nonnull))
513
63
static ANN Func_Def scan2_cpy_fdef(const Env env, const Func_Def fdef) {
514
63
  const Func_Def f = cpy_func_def(env->gwion->mp, fdef);
515
63
  f->base->ret_type = fdef->base->ret_type;
516
63
  Arg_List a = f->base->args, b = fdef->base->args;
517
192
  while(a) {
518
66
    a->var_decl->value = b->var_decl->value;
519
66
    a->type = b->type;
520
66
    a = a->next;
521
66
    b = b->next;
522
  }
523
63
  scan1_func_def(env, f);
524
63
  return f;
525
}
526
527
42330
static inline int is_cpy(const Func_Def fdef) {
528

84721
  return  GET_FLAG(fdef, global) ||
529
42457
    (fdef->base->tmpl && !fdef->base->tmpl->call);
530
}
531
532
42330
ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
533
42330
  if(GET_FLAG(fdef, global))
534
2
    env->context->global = 1;
535
84660
  const Func_Def f = !is_cpy(fdef) ?
536
42330
    fdef : scan2_cpy_fdef(env, fdef);
537
42330
  const m_uint scope = !GET_FLAG(f, global) ? env->scope->depth : env_push_global(env);
538

42330
  f->stack_depth = (env->class_def && !GET_FLAG(f, static) && !GET_FLAG(f, global)) ? SZ_INT : 0;
539
42330
  if(GET_FLAG(f, variadic))
540
14
    f->stack_depth += SZ_INT;
541
42330
  const m_bool ret = scanx_fdef(env, env, f, (_exp_func)scan2_fdef);
542
42330
  if(GET_FLAG(f, global))
543
2
    env_pop(env, scope);
544
42330
  CHECK_BB(ret)
545
42329
  fdef->base->func = f->base->func; // only needed if 'is_cpy()'
546
42329
  return GW_OK;
547
}
548
549
#define scan2_enum_def dummy_func
550
1301
HANDLE_SECTION_FUNC(scan2, m_bool, Env)
551
552
64
ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
553
64
  const Type parent = cdef->base.type->e->parent;
554

64
  if(parent->e->def && !GET_FLAG(parent, scan2))
555
6
    CHECK_BB(ensure_scan2(env, parent))
556
64
  if(cdef->base.ext->array)
557
9
    CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
558
64
  return GW_OK;
559
}
560
561
64
ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
562

64
  if(cdef->base.tmpl && cdef->base.tmpl->list)
563
21
    CHECK_BB(template_push_types(env, cdef->base.tmpl))
564
64
  const m_bool ret = scan2_parent(env, cdef);
565

64
  if(cdef->base.tmpl && cdef->base.tmpl->list)
566
21
    nspc_pop_type(env->gwion->mp, env->curr);
567
64
  return ret;
568
}
569
570
261
ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
571
261
  if(tmpl_base(cdef->base.tmpl))
572
17
    return GW_OK;
573
244
  const Type t = cdef->base.type;
574
244
  if(GET_FLAG(t, scan2))return GW_OK;
575

244
  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2))
576
    CHECK_BB(ensure_scan2(env, t->e->owner_class))
577
244
  SET_FLAG(t, scan2);
578
244
  if(cdef->base.ext)
579
64
    CHECK_BB(cdef_parent(env, cdef))
580
244
  if(cdef->body)
581
203
    CHECK_BB(env_body(env, cdef, scan2_section))
582
244
  return GW_OK;
583
}
584
585
943
ANN m_bool scan2_ast(const Env env, Ast ast) {
586
943
  do CHECK_BB(scan2_section(env, ast->section))
587
940
  while((ast = ast->next));
588
550
  return GW_OK;
589
}