GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/parse/scan2.c Lines: 405 408 99.3 %
Date: 2020-07-24 14:14:26 Branches: 298 368 81.0 %

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
35
ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
17
70
  struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
18
35
    .scope=env->scope->depth, .flag=ae_flag_scan2 };
19
35
  return envset_run(&es, t);
20
}
21
22
22827
ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
23
22827
  const Type t = get_type(decl->type);
24

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

43247
    SET_ACCESS(d, v)
67
  }
68
43428
  d->base->func = v->d.func_ref = f;
69
43428
  return f->value_ref = v;
70
}
71
72
73
69
ANN m_bool scan2_fptr_def(const Env env NUSED, const Fptr_Def fptr) {
74
69
  if(!tmpl_base(fptr->base->tmpl)) {
75
54
    const Func_Def def = fptr->type->e->d.func->def;
76
54
    if(def->base->args) {
77
24
      RET_NSPC(scan2_args(def))
78
    }
79
  } else
80
15
    SET_FLAG(fptr->type, func);
81
45
  return GW_OK;
82
}
83
84
750
ANN m_bool scan2_type_def(const Env env, const Type_Def tdef) {
85
750
  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
2230
ANN static inline Value prim_value(const Env env, const Symbol s) {
90
2230
  const Value value = nspc_lookup_value1(env->curr, s);
91
2230
  if(env->class_def)
92
391
    return value ?: find_value(env->class_def, s);
93
1839
  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
4622
ANN static inline m_bool scan2_prim(const Env env, const Exp_Primary* prim) {
105

8069
  if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
106
3447
        prim->prim_type == ae_prim_interp)
107
1180
    CHECK_BB(scan2_exp(env, prim->d.exp))
108
3442
  else if(prim->prim_type == ae_prim_id) {
109
2230
    const Value v = prim_value(env, prim->d.var);
110
2230
    if(v)
111
1607
      SET_FLAG(v, used);
112

1212
  } else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
113
22
    return scan2_exp(env, prim->d.array->exp);
114
1190
  else if(prim->prim_type == ae_prim_range)
115
3
    return scan2_range(env, prim->d.range);
116
4597
  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
1453
ANN static m_bool multi_decl(const Env env, const Exp e, const Symbol op) {
130
1453
  if(e->exp_type == ae_exp_decl) {
131
153
    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
152
    SET_FLAG(e->d.exp_decl.list->self->value, used);
134
  }
135
1452
  return GW_OK;
136
}
137
138
727
ANN static inline m_bool scan2_exp_binary(const Env env, const Exp_Binary* bin) {
139
727
  CHECK_BB(scan2_exp(env, bin->lhs))
140
727
  CHECK_BB(scan2_exp(env, bin->rhs))
141
727
  CHECK_BB(multi_decl(env, bin->lhs, bin->op))
142
726
  return multi_decl(env, bin->rhs, bin->op);
143
}
144
145
37
ANN static inline m_bool scan2_exp_cast(const Env env, const Exp_Cast* cast) {
146
37
  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
539
ANN static inline m_bool scan2_exp_call(const Env env, const Exp_Call* exp_call) {
154
539
  if(exp_call->tmpl)
155
33
    return GW_OK;
156
506
  CHECK_BB(scan2_exp(env, exp_call->func))
157
506
  const Exp args = exp_call->args;
158
506
  return args ? scan2_exp(env, args) : GW_OK;
159
}
160
161
543
ANN static inline m_bool scan2_exp_dot(const Env env, const Exp_Dot* member) {
162
543
  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
147
ANN static m_bool scan2_exp_unary(const Env env, const Exp_Unary * unary) {
172

147
  if((unary->op == insert_symbol("spork") || unary->op == insert_symbol("fork")) && unary->code) {
173
25
    RET_NSPC(scan2_stmt(env, unary->code))
174
122
  } else if(unary->exp)
175
98
    return scan2_exp(env, unary->exp);
176
24
  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

29511
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

6
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


34
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
504
ANN static inline m_bool scan2_stmt_code(const Env env, const Stmt_Code stmt) {
225
504
  if(stmt->stmt_list)
226
444
    { RET_NSPC(scan2_stmt_list(env, stmt->stmt_list)) }
227
60
  return GW_OK;
228
}
229
230
2691
ANN static inline m_bool scan2_stmt_exp(const Env env, const Stmt_Exp stmt) {
231
2691
  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
3051
ANN static m_bool scan2_stmt(const Env env, const Stmt stmt) {
288
3051
  return scan2_stmt_func[stmt->stmt_type](env, &stmt->d);
289
}
290
291
2894
ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) {
292
2894
  do CHECK_BB(scan2_stmt(env, list->stmt))
293
2892
  while((list = list->next));
294
1142
  return GW_OK;
295
}
296
297
8855
ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) {
298
8855
  const m_bool base = tmpl_base(f->base->tmpl);
299
8855
  const m_bool tmpl = GET_FLAG(overload, template);
300

8855
  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


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

80
      } while((ff = ff->next) && ++i);
390
   }
391

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

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

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

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

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

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

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

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

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