GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/parse/scan2.c Lines: 410 413 99.3 %
Date: 2020-10-03 09:50:08 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
31
ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
17
62
  struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
18
31
    .scope=env->scope->depth, .flag=ae_flag_scan2 };
19
31
  return envset_run(&es, t);
20
}
21
22
21483
ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
23
21483
  const Type t = get_type(decl->type);
24

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

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

7757
  if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
106
3336
        prim->prim_type == ae_prim_interp)
107
1088
    CHECK_BB(scan2_exp(env, prim->d.exp))
108
3333
  else if(prim->prim_type == ae_prim_id) {
109
2132
    const Value v = prim_value(env, prim->d.var);
110
2132
    if(v)
111
1508
      SET_FLAG(v, used);
112

1201
  } else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
113
22
    return scan2_exp(env, prim->d.array->exp);
114
1179
  else if(prim->prim_type == ae_prim_range)
115
3
    return scan2_range(env, prim->d.range);
116
4396
  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
1283
ANN static m_bool multi_decl(const Env env, const Exp e, const Symbol op) {
130
1283
  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
1282
  return GW_OK;
136
}
137
138
642
ANN static inline m_bool scan2_exp_binary(const Env env, const Exp_Binary* bin) {
139
642
  CHECK_BB(scan2_exp(env, bin->lhs))
140
642
  CHECK_BB(scan2_exp(env, bin->rhs))
141
642
  CHECK_BB(multi_decl(env, bin->lhs, bin->op))
142
641
  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

27901
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

12
scan2_stmt_func(each, Stmt_Each,, !(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
459
ANN static inline m_bool scan2_stmt_code(const Env env, const Stmt_Code stmt) {
225
459
  if(stmt->stmt_list)
226
396
    { RET_NSPC(scan2_stmt_list(env, stmt->stmt_list)) }
227
63
  return GW_OK;
228
}
229
230
2494
ANN static inline m_bool scan2_stmt_exp(const Env env, const Stmt_Exp stmt) {
231
2494
  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
284
4
ANN static m_bool scan2_stmt_pp(const Env env, const Stmt_PP stmt) {
285
4
  if(stmt->pp_type == ae_pp_include)
286
3
    env->name = stmt->data;
287
4
  return GW_OK;
288
}
289
290
DECL_STMT_FUNC(scan2, m_bool, Env)
291
292
2800
ANN static m_bool scan2_stmt(const Env env, const Stmt stmt) {
293
2800
  return scan2_stmt_func[stmt->stmt_type](env, &stmt->d);
294
}
295
296
2633
ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) {
297
2633
  do CHECK_BB(scan2_stmt(env, list->stmt))
298
2631
  while((list = list->next));
299
1103
  return GW_OK;
300
}
301
302
8664
ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) {
303
8664
  const m_bool base = tmpl_base(f->base->tmpl);
304
8664
  const m_bool tmpl = GET_FLAG(overload, template);
305

8664
  if(isa(overload->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, overload->type)) {
306
5
    if(!GET_FLAG(f->base, typedef))
307
      ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
308
  }
309


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

79
      } while((ff = ff->next) && ++i);
396
   }
397

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

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

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

84963
  return  GET_FLAG(fdef->base, global) ||
534
42581
    (fdef->base->tmpl && !fdef->base->tmpl->call);
535
}
536
537
42451
ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
538
42451
  if(GET_FLAG(fdef->base, global))
539
2
    env->context->global = 1;
540
84902
  const Func_Def f = !is_cpy(fdef) ?
541
42451
    fdef : scan2_cpy_fdef(env, fdef);
542
42451
  const m_uint scope = !GET_FLAG(f->base, global) ? env->scope->depth : env_push_global(env);
543

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

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

64
  if(cdef->base.tmpl && cdef->base.tmpl->list)
568
21
    CHECK_BB(template_push_types(env, cdef->base.tmpl))
569
64
  const m_bool ret = scan2_parent(env, cdef);
570

64
  if(cdef->base.tmpl && cdef->base.tmpl->list)
571
21
    nspc_pop_type(env->gwion->mp, env->curr);
572
64
  return ret;
573
}
574
575
264
ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
576
264
  if(tmpl_base(cdef->base.tmpl))
577
18
    return GW_OK;
578
246
  const Type t = cdef->base.type;
579
246
  if(GET_FLAG(t, scan2))return GW_OK;
580

246
  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2))
581
    CHECK_BB(ensure_scan2(env, t->e->owner_class))
582
246
  SET_FLAG(t, scan2);
583
246
  if(cdef->base.ext)
584
64
    CHECK_BB(cdef_parent(env, cdef))
585
246
  if(cdef->body)
586
204
    CHECK_BB(env_body(env, cdef, scan2_section))
587
246
  return GW_OK;
588
}
589
590
949
ANN m_bool scan2_ast(const Env env, Ast ast) {
591
949
  do CHECK_BB(scan2_section(env, ast->section))
592
946
  while((ast = ast->next));
593
555
  return GW_OK;
594
}