3 typedef int initID
, vtblID
;
5 typedef struct member_t
{
11 typedef struct puredm_t
{
12 struct puredm_t
*next
;
17 typedef struct tconst_t
{
18 struct tconst_t
*next
;
22 typedef struct anonunion_t
{
23 struct anonunion_t
*next
;
28 typedef struct localtdef_t
{
29 struct localtdef_t
*next
;
46 enum { ASTATUS_NORM
, ASTATUS_VIRT
, ASTATUS_VIRT2
, ASTATUS_FSCKD
}; // ancestor.status
59 enum { AU_STATUS_ND
, AU_STATUS_DD
, AU_STATUS_NU
, AU_STATUS_PV
, AU_STATUS_PEND
}; // autofunc.status
61 typedef struct autofunct_t
{
62 struct autofunct_t
*next
;
65 Token dname
, fname
, pname
;
73 enum { OK_CAN
, CANT_INCOMPL
, CANT_PUREV
, CANT_NUFO
}; // structure.caninst
79 bool notunion
, incomplete
, deftype
, class;
81 bool has_dtor
, dtor_nothrow
;
82 bool has_dtorable
, autodtor
;
83 bool unwind
, noctor
, evt
;
89 bool used
, printed
, vt_inthis
;
91 // object has const members
95 member
*firstmember
, *lastmember
;
100 // member function space
104 anonunion
*anonunions
;
107 // depends on declaration of these
119 // virtual table initializers
125 // has virtual ancestors
126 bool has_vbase
, has_vbase2
;
128 // downcast info for virtual inheritance
130 bool need_recalc_offsets
;
133 // members that need vt initialization
134 ctorable_t
*ctorables
;
135 bool ancestors_have_ctors
;
137 // can instantiate object
140 // class is merely an alias?
144 static structure
*structs
;
146 /******************************************************************************
148 database of structures, members and hierarchies
150 ******************************************************************************/
152 #define STAR_IF(x) x ? '*' : BLANKT
153 #define COMMA_IF(x) x ? ',' : BLANKT
154 #define ADDR_IF(x) x ? '&' : BLANKT
155 #define DOT_IF(x) x ? '.' : BLANKT
156 #define POINTSAT_IF(x) x ? POINTSAT : BLANKT
157 #define CONST_IF(x) (x) ? RESERVED_const : BLANKT
158 #define STATIC_IF(x) (x) ? RESERVED_static : BLANKT
160 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
162 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
165 static void show_ancest (recID r
)
169 ancestor
*a
= structs
[r
].ancestors
;
170 PRINTF ("Ancestors of "COLS
"%s"COLE
"\n", SNM (r
));
172 for (i
= 0; a
[i
].rec
!= -1; i
++) {
174 PRINTF (" ["COLS
"%s"COLE
"]", SNM (a
[i
].rec
));
176 if (a
[i
].status
== ASTATUS_VIRT
)
177 PRINTF ("\t[virtual"COLS
" %s"COLE
"]\n\t"COLS
, SNM (a
[i
].vbase
));
178 else if (a
[i
].status
== ASTATUS_VIRT2
)
179 PRINTF ("\t[virtual"COLS
" %s"COLE
"] "COLS
"-no data-"COLE
"\n\t"COLS
, SNM (a
[i
].vbase
));
180 else if (a
[i
].status
== ASTATUS_FSCKD
)
181 PRINTF (" -"COLS
"* fsckd *"COLE
" -\n\t"COLS
);
182 else PRINTF ("\n\t"COLS
);
184 INTPRINT (a
[i
].path
);
188 PRINTF (COLE
"\n Dirct\t"COLS
);
189 INTPRINT (a
[i
].cpath
);
198 static inline bool vparent (int i
)
200 return in2 (i
, ASTATUS_VIRT
, ASTATUS_VIRT2
);
203 static inline bool direct_ancest (ancestor
*a
)
211 static ctorable_t
*add_ctorable (recID r
)
213 if (!structs
[r
].ctorables
) {
214 structs
[r
].ctorables
= (ctorable_t
*) malloc (2 * sizeof (ctorable_t
));
215 structs
[r
].ctorables
[1].ot
= -1;
216 return &structs
[r
].ctorables
[0];
221 for (i
= 0; structs
[r
].ctorables
[i
].ot
!= -1; i
++);
223 structs
[r
].ctorables
= (ctorable_t
*) realloc (structs
[r
].ctorables
, (i
+ 2) * sizeof (ctorable_t
));
224 structs
[r
].ctorables
[i
+ 1].ot
= -1;
226 return &structs
[r
].ctorables
[i
];
229 static autofunc
*add_autofunc (recID r
)
231 autofunc
*a
= (autofunc
*) malloc (sizeof * a
);
232 a
->next
= structs
[r
].autofuncs
;
233 return structs
[r
].autofuncs
= a
;
236 Token
add_anonymous_union (recID r
, recID u
)
238 anonunion
*a
= (anonunion
*) malloc (sizeof * a
);
239 a
->next
= structs
[r
].anonunions
;
241 structs
[r
].anonunions
= a
;
242 return a
->n
= name_anon_union (structs
[r
].nanons
++, name_of_struct (r
));
245 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
247 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
249 Token
lookup_class_const (recID r
, Token m
)
252 for (t
= structs
[r
].consts
; t
; t
= t
->next
)
253 if (t
->m
== m
) return t
->r
;
257 void enter_class_const (recID r
, Token m
, Token re
)
261 if (!structs
[r
].consts
) {
262 structs
[r
].consts
= (tconst
*) malloc (sizeof (tconst
));
263 structs
[r
].consts
->m
= m
;
264 structs
[r
].consts
->r
= re
;
265 structs
[r
].consts
->next
= 0;
269 for (t
= structs
[r
].consts
; t
; t
= t
->next
)
275 t
= (tconst
*) malloc (sizeof (tconst
));
276 t
->next
= structs
[r
].consts
;
279 structs
[r
].consts
= t
;
282 static void inherit_class_consts (recID r
)
287 for (a
= structs
[r
].ancestors
; a
->rec
!= -1; a
++)
288 if (direct_ancest (a
))
289 for (t
= structs
[a
->rec
].consts
; t
; t
= t
->next
)
290 enter_class_const (r
, t
->m
, t
->r
);
293 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
295 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
297 Token
add_local_typedef (recID r
, Token tn
)
301 for (t
= structs
[r
].ltdef
; t
; t
= t
->next
)
303 parse_error_toktok (tn
, name_of_struct (r
), "local typedef redef");
305 t
= (localtdef
*) malloc (sizeof * t
);
306 t
->next
= structs
[r
].ltdef
;
307 structs
[r
].ltdef
= t
;
309 return t
->gn
= name_local_typedef (name_of_struct (r
), tn
);
312 bool have_local_typedef (recID r
, Token tn
)
315 for (t
= structs
[r
].ltdef
; t
; t
= t
->next
)
321 static Token
typedef_in (recID r
, Token tn
)
325 for (t
= structs
[r
].ltdef
; t
; t
= t
->next
)
326 if (t
->tn
== tn
) return t
->gn
;
330 Token
lookup_local_typedef (recID r
, Token tn
)
337 ret
= typedef_in (r
, tn
);
338 if ((a
= structs
[r
].ancestors
))
339 for (; a
->rec
!= -1; a
++)
340 if ((t
= typedef_in (a
->rec
, tn
))) {
347 } else if (d2
== d
) {
356 if (e
) expr_errort ("Ambiguous local typedef", tn
);
358 if (ret
&& objective
.recording
)
359 usage_typeID (lookup_typedef (ret
));
364 static Token
direct_vparent (recID rd
, recID rb
)
368 if (rd
== rb
) return 0;
370 if ((a
= structs
[rd
].ancestors
))
371 for (; a
->rec
!= -1; a
++)
372 if (a
->rec
== rb
&& a
->status
== ASTATUS_VIRT
373 && a
->path
[1] == -1) return a
->path
[0];
377 /* generate the code which sets the address of the common shared
378 base class instance to the pointers that are supposed to point to it */
379 static void gen_construction_code_vb (OUTSTREAM o
, recID r
, Token obj
)
383 ancestor
*a
= structs
[r
].ancestors
;
386 for (i
= 0; a
[i
].rec
!= -1; i
++)
387 if (a
[i
].status
== ASTATUS_VIRT
&& a
[i
].vbase
== a
[i
].rec
) {
388 recID vr
= a
[i
].vbase
, r2
;
389 for (j
= 0; a
[j
].rec
!= -1; j
++)
390 if (!is_aliasclass (a
[j
].rec
))
391 if ((m
= direct_vparent (r2
= aliasclass (a
[j
].rec
), vr
))) {
392 is_ancestor (r
, r2
, &p
, true);
393 outprintf (o
, obj
, POINTSAT
, ISTR (p
),
396 if (direct_vparent (r
, vr
)) {
397 outprintf (o
, obj
, POINTSAT
, a
[i
].path
[0], '=', -1);
399 is_ancestor (r
, vr
, &p
, true);
400 outprintf (o
, '&', obj
, POINTSAT
, ISTR (p
), ';', -1);
404 /* construction code in case base obj is just a vtable */
405 static void gen_construction_code_vb2 (OUTSTREAM o
, recID r
, Token obj
)
409 ancestor
*a
= structs
[r
].ancestors
;
412 for (i
= 0; a
[i
].rec
!= -1; i
++)
413 if (a
[i
].status
== ASTATUS_VIRT2
) {
417 for (j
= 0; a
[j
].rec
!= -1; j
++)
418 if (a
[j
].rec
!= a
[i
].rec
&& direct_ancest (&a
[j
])
419 && is_ancestor (aliasclass (a
[j
].rec
), a
[i
].rec
, &p
, 1)) {
420 p2
= a
[j
].cpath
?: a
[j
].path
;
421 if (p1
[0] == p2
[0]) continue;
422 outprintf (o
, obj
, POINTSAT
, ISTR (p2
), '.',
423 ISTR (p
), '.', RESERVED__v_p_t_r_
, '=', -1);
427 if (hp
) outprintf (o
, obj
, POINTSAT
, ISTR (a
[i
].cpath
), '.',
428 RESERVED__v_p_t_r_
, ';', -1);
432 /* generate the code that calls the init function for a ctorable */
433 static void call_init_func (OUTSTREAM o
, Token obj
, ctorable_t
*c
, Token
*path
)
435 if (c
->array
) outprintf (o
, i_call_initialization (c
->ot
), '(',
436 obj
, POINTSAT
, ISTR (path
), DOT_IF (path
[0] != -1), c
->obn
, ',',
437 RESERVED_sizeof
, obj
, POINTSAT
, ISTR (path
),
438 DOT_IF (path
[0] != -1), c
->obn
, '/',
439 RESERVED_sizeof
, '(', iRESERVED_struct (c
->ot
),
440 name_of_struct (c
->ot
), ')', ')', ';', -1);
441 else outprintf (o
, i_call_initialization (c
->ot
), '(',
442 '&', obj
, POINTSAT
, ISTR (path
), DOT_IF (path
[0] != -1),
443 c
->obn
, ',', RESERVED_1
, ')', ';', -1);
446 /* Construct all members that need construction indeed yes */
447 static void gen_member_construction (OUTSTREAM o
, recID r
, Token obj
)
450 ctorable_t
*c
= structs
[r
].ctorables
;
451 Token nopath
[] = { -1 };
454 if (c
) for (i
= 0; c
[i
].ot
!= -1; i
++)
455 call_init_func (o
, obj
, &c
[i
], nopath
);
457 if (structs
[r
].ancestors_have_ctors
)
458 for (a
= structs
[r
].ancestors
; a
->rec
!= -1; a
++)
459 if ((c
= structs
[a
->rec
].ctorables
))
460 for (i
= 0; c
[i
].ot
!= -1; i
++)
461 call_init_func (o
, obj
, &c
[i
], a
->cpath
?: a
->path
);
464 void gen_construction_code (OUTSTREAM o
, recID r
, Token obj
)
466 if (structs
[r
].has_vbase
)
467 gen_construction_code_vb (o
, r
, obj
);
468 if (structs
[r
].vtis
)
469 gen_vt_init (o
, r
, obj
, true);
470 if (structs
[r
].has_vbase2
)
471 gen_construction_code_vb2 (o
, r
, obj
);
472 if (structs
[r
].ctorables
|| structs
[r
].ancestors_have_ctors
)
473 gen_member_construction (o
, r
, obj
);
475 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
477 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
479 static intnode
*structtree
;
480 static int nstructs
, nallocstructs
;
482 recID
enter_struct (Token e
, Token tag
, bool unwind
, bool noctor
, bool evt
, bool sclass
)
484 intnode
*in
= intfind (structtree
, e
);
485 int pt
[3] = { nstructs
, '*', -1 };
489 if (unwind
&& !always_unwind (r
))
490 structs
[r
].unwind
= true;
492 structs
[r
].noctor
= true;
496 if (nstructs
== nallocstructs
)
497 structs
= (structure
*) realloc (structs
, (nallocstructs
+=96) * sizeof (structure
));
498 structs
[nstructs
].name
= e
;
499 structs
[nstructs
].notunion
= tag
!= RESERVED_union
;
500 structs
[nstructs
].deftype
= false;
501 structs
[nstructs
].class = tag
== RESERVED_class
;
502 structs
[nstructs
].incomplete
= true;
503 structs
[nstructs
].has_dtor
= false;
504 structs
[nstructs
].idtor
= 0;
505 structs
[nstructs
].vdtor
= 0;
506 structs
[nstructs
].dtor_name
= 0;
507 structs
[nstructs
].dtor_nothrow
= false;
508 structs
[nstructs
].Funcs
= 0;
509 structs
[nstructs
].has_dtorable
= false;
510 structs
[nstructs
].firstmember
= 0;
511 structs
[nstructs
].printed
= false;
512 structs
[nstructs
].unwind
= unwind
;
513 structs
[nstructs
].noctor
= noctor
;
514 structs
[nstructs
].evt
= evt
;
515 structs
[nstructs
].has_vbase
= 0;
516 structs
[nstructs
].has_vbase2
= 0;
517 structs
[nstructs
].rtti
= 0;
518 structs
[nstructs
].vtis
= 0;
519 structs
[nstructs
].ancestors
= 0;
520 structs
[nstructs
].ctorables
= 0;
521 structs
[nstructs
].autofuncs
= 0;
522 structs
[nstructs
].anonunions
= 0;
523 structs
[nstructs
].ltdef
= 0;
524 structs
[nstructs
].nanons
= 0;
525 structs
[nstructs
].consts
= 0;
526 structs
[nstructs
].caninst
= CANT_INCOMPL
;
527 structs
[nstructs
].type_pthis
= enter_type (pt
);
528 structs
[nstructs
].used
= false;
529 structs
[nstructs
].code
= 0;
530 structs
[nstructs
].depends
= 0;
531 structs
[nstructs
].ancestors_have_ctors
= 0;
532 structs
[nstructs
].need_recalc_offsets
= 0;
533 structs
[nstructs
].have_vi_decls
= 0;
534 structs
[nstructs
].vt_inthis
= false;
535 structs
[nstructs
].alias_class
= nstructs
;
536 structs
[nstructs
].constd
= 0;
537 structs
[nstructs
].pm
= 0;
538 structs
[nstructs
].keyfunc
= sclass
? -1 : 0;
539 structs
[nstructs
].havekey
= 0;
540 structs
[nstructs
].autodtor
= 0;
541 union ival i
= { i
: nstructs
};
542 intadd (&structtree
, e
, i
);
546 void keyfunc_candidate (recID o
, Token k
)
548 if (!structs
[o
].keyfunc
)
549 //{PRINTF ("Setting keyfunc of "COLS"%s"COLE":%s\n", SNM(o), expand (k));
550 structs
[o
].keyfunc
= k
;
554 void possible_keyfunc (recID o
, Token k
)
556 //PRINTF ("possible %s:%s ", SNM(o), expand(k));
557 if (structs
[o
].keyfunc
== k
)
558 //{PRINTF ("-ok-\n");
559 structs
[o
].havekey
= 1;
560 //}else PRINTF ("\n");
563 void set_depend (recID o
, recID i
)
566 if (structs
[o
].depends
) {
567 for (j
= 0; structs
[o
].depends
[j
] != -1; j
++);
571 structs
[o
].depends
= (recID
*) realloc (structs
[o
].depends
, j
* sizeof (recID
));
572 structs
[o
].depends
[j
- 2] = i
;
573 structs
[o
].depends
[j
- 1] = -1;
576 static void export_struct (recID r
)
580 if (structs
[r
].printed
) return;
584 const char *n
= expand(structs
[r
].name
);
585 if (strcmp(n
, "__jmp_buf_tag") == 0) { structs
[r
].printed
= true; return; }
589 if (structs
[r
].depends
)
590 for (i
= 0; structs
[r
].depends
[i
] != -1; i
++)
591 export_struct (structs
[r
].depends
[i
]);
593 if (structs
[r
].vtis
)
594 export_virtual_table_declaration (r
);
596 if (structs
[r
].Funcs
)
597 export_fspace_lwc (structs
[r
].Funcs
);
599 structs
[r
].printed
= true;
600 if (structs
[r
].code
)
601 outprintf (STRUCTS
, ISTR (structs
[r
].code
), -1);
604 void export_structs ()
607 for (r
= 0; r
< nstructs
; r
++)
611 static void commit_auto_functions (recID
);
613 /////////////////////////////////////////////////
614 // some things when declaration completes
615 /////////////////////////////////////////////////
617 void remove_struct_from_this (Token
*p
, recID r
)
620 if (intchr (p
, RESERVED_this
)) {
621 for (i
= 0; p
[i
] != RESERVED_this
; i
++);
622 while (p
[i
] != RESERVED_struct
&& p
[i
] != '(') i
--;
624 intcpy (p
+ i
, p
+ i
+ 1);
626 Token sn
= name_of_struct (r
);
627 for (i
= 0; p
[i
] != -1; p
++)
628 if (p
[i
] == RESERVED_struct
&& p
[i
+ 1] == sn
)
629 for (j
= i
; p
[j
] != -1; j
++)
633 static void adjust_protos (fspace S
, recID r
)
637 funcp
*p
= (funcp
*) S
->v
.p
;
638 for (; p
; p
= p
->next
)
639 if (p
->prototype
&& !(p
->flagz
& FUNCP_MODULAR
)) {
640 remove_struct_from_this (p
->prototype
, r
);
641 remove_struct_from_def (p
->name
);
643 adjust_protos (S
->less
, r
);
644 adjust_protos (S
->more
, r
);
647 static void make_empty_dtor (recID r
)
649 Token proto
[] = { RESERVED_static
, RESERVED_inline
, RESERVED_dtor
, '(', ')', ';', -1 };
650 SAVE_VAR (CODE
, proto
);
651 bool haskey
= structs
[r
].keyfunc
!= 0;
652 struct_declaration (r
, 0, 0);
653 if (!haskey
&& structs
[r
].keyfunc
)
654 structs
[r
].keyfunc
= 0;
656 store_define_dtor (structs
[r
].dtor_name
, r
);
659 static void study_destruction (recID r
)
661 bool b
= false, v
= false;
664 ancestor
*a
= structs
[r
].ancestors
;
666 for (m
= structs
[r
].firstmember
; m
; m
= m
->next
)
667 if (isstructure (m
->t
) && has_dtor (base_of (m
->t
))) {
672 if (a
) for (i
= 0; a
[i
].rec
!= -1; i
++)
673 if (vparent (a
[i
].status
)) v
= true;
674 else if (direct_ancest (&a
[i
]) && has_dtor (a
[i
].rec
))
677 // - vdtor is the destructor that doesn't call the dtors
678 // of the virtual base classes
679 // - idtor calls dtors of dtorable members and vdtors (or normal
680 // dtors in not exist) of direct non virtual parents.
681 // - the real dtor calls vdtor and then calls the dtors
682 // of virtual parents
685 if (!structs
[r
].has_dtor
)
687 structs
[r
].idtor
= name_intern_dtor (r
);
689 if (v
) structs
[r
].vdtor
= name_intern_vdtor (r
);
692 OUTSTREAM
dispatch_vdtor (recID r
, OUTSTREAM o
)
695 Token
*vd
= combine_output (o
);
696 OUTSTREAM n
= new_stream ();
697 ancestor
*a
= structs
[r
].ancestors
;
699 for (i
= 0; vd
[i
] != '{'; i
++)
700 output_itoken (n
, vd
[i
]);
701 outprintf (n
, '{', structs
[r
].vdtor
, '(', RESERVED_this
, ')', ';', -1);
702 for (i
= 0; a
[i
].rec
!= -1; i
++)
703 if (vparent (a
[i
].status
))
704 outprintf (n
, structs
[a
[i
].rec
].vdtor
?:
705 structs
[a
[i
].rec
].dtor_name
, '(',
706 ADDR_IF (a
[i
].cpath
&& a
[i
].cpath
[0] != -1), RESERVED_this
,
707 POINTSAT_IF ((a
[i
].cpath
?: a
[i
].path
) [0] != -1),
708 ISTR (a
[i
].cpath
?: a
[i
].path
), ')', ';', -1);
709 outprintf (n
, RESERVED_return
, RESERVED_this
, ';', '}', -1);
711 intsubst1 (vd
, structs
[r
].dtor_name
, structs
[r
].vdtor
);
712 outprintf (INTERNAL_CODE
, ISTR (vd
), -1);
718 void make_intern_dtor (recID r
)
722 ancestor
*a
= structs
[r
].ancestors
;
723 Token do_alias
= HaveAliases
? 0 : -1;
724 #ifdef BROKEN_ALIASES
728 OUTSTREAM O
= new_stream ();
730 outprintf (O
, R(static), R(inline), R(void), structs
[r
].idtor
, '(',
731 iRESERVED_struct (r
), name_of_struct (r
), '*', R(this), ')', '{', -1);
733 /* call dtors of dtorable data members */
734 for (m
= structs
[r
].firstmember
; m
; m
= m
->next
)
735 if (isstructure (m
->t
) && has_dtor (base_of (m
->t
))) {
736 outprintf (O
, dtor_name (base_of (m
->t
)),
737 '(', '&', RESERVED_this
, POINTSAT
, m
->m
, ')', ';', -1);
741 /* call vdtors of parents (non virtual parents that is) */
742 if (a
) for (i
= 0; a
[i
].rec
!= -1; i
++)
743 if (direct_ancest (&a
[i
]) && has_dtor (a
[i
].rec
) && !vparent (a
[i
].status
)
744 && !(structs
[a
[i
].rec
].autodtor
&& !idtor (a
[i
].rec
))) {
745 bool dointernal
= structs
[a
[i
].rec
].autodtor
;
747 /* If this is an auto function call only idtor of parent.
748 else if parent has vbases, call vdtor of parent.
749 else call dtor of parent */
750 dointernal
? idtor (a
[i
].rec
) :
751 structs
[a
[i
].rec
].vdtor
?:
752 dtor_name (a
[i
].rec
), '(',
753 ISTR (upcast1_this (r
, a
[i
].rec
)), ')', ';', -1);
754 if (do_alias
) do_alias
= -1;
755 else do_alias
= zero_offset (r
, a
[i
].rec
) && !dointernal
?
756 dtor_name (afcls
= a
[i
].rec
) : -1;
758 output_itoken (O
, '}');
760 /* do it with alias if all that has to be done is call the dtor of one parent
761 which is at offset 0 */
764 outprintf (O
= new_stream (), R(static), R(inline), R(void), structs
[r
].idtor
, '(',
765 iRESERVED_struct (r
), name_of_struct (r
), '*', R(this), ')',
766 alias_func (afcls
, do_alias
), ';', -1);
768 concate_streams (INTERNAL_CODE
, O
);
771 static void enter_virtuals (recID r
, fspace S
)
775 for (p
= S
->v
.p
; p
; p
= p
->next
)
776 if ((p
->flagz
& FUNCP_VIRTUAL
) && p
->prototype
) {
782 args
.ftype
= p
->type
;
783 args
.fmemb
= p
->flagz
& FUNCP_PURE
? 0 : p
->name
;
784 args
.flagz
= p
->flagz
;
785 // pass prototype to make fptr from
786 for (pr
= p
->prototype
; ISDCLFLAG (*pr
); pr
++);
787 args
.prototype
= allocaint (intlen (pr
) + 1);
788 intcpy (args
.prototype
, pr
);
789 intsubst1 (args
.prototype
, p
->name
, MARKER
);
790 args
.argv
= allocaint (intlen (p
->xargs
) + 1);
791 intcpy (args
.argv
, p
->xargs
);
792 Enter_virtual_function (&args
);
794 if (S
->less
) enter_virtuals (r
, S
->less
);
795 if (S
->more
) enter_virtuals (r
, S
->more
);
798 bool do_alias_class (recID r
)
801 ancestor
*a
= structs
[r
].ancestors
;
803 if (structs
[r
].firstmember
|| structs
[r
].vt_inthis
|| !a
|| structs
[r
].anonunions
)
806 for (; a
->rec
!= -1; a
++)
807 if (direct_ancest (a
)) {
808 rr
= structs
[a
->rec
].alias_class
;
809 if (alias
&& rr
!= alias
)
813 structs
[r
].alias_class
= alias
;
817 recID
is_aliasclass (recID r
)
819 if (structs
[r
].incomplete
&& structs
[r
].class) {
820 structs
[r
].deftype
= true;
823 return structs
[r
].alias_class
== r
? 0 : structs
[r
].alias_class
;
826 recID
aliasclass (recID r
)
828 return structs
[r
].alias_class
;
831 static void undo_paths (recID
);
833 recID
complete_structure (OUTSTREAM o
, recID r
)
835 structs
[r
].incomplete
= false;
836 study_destruction (r
);
837 if (do_alias_class (r
)) {
839 adjust_protos (structs
[r
].Funcs
, r
);
840 structs
[r
].has_vbase
= 0;
841 structs
[r
].has_vbase2
= 0;
843 if (structs
[r
].class) {
844 if (structs
[r
].deftype
) outprintf (GLOBAL
, RESERVED_typedef
,
845 RESERVED_struct
, name_of_struct (r
), name_of_struct (r
), ';', -1);
846 //else outprintf (GLOBAL, RESERVED_struct, name_of_struct (r), ';', -1);
848 if (structs
[r
].ancestors
) make_rtti (r
);
850 if (structs
[r
].Funcs
)
851 enter_virtuals (r
, structs
[r
].Funcs
);
852 //**+*+*+*+*+*+*+*+*+*+*+*+*
853 close_inits (&structs
[r
]);
855 if (can_instantiate (r
)) {
856 if (structs
[r
].has_vbase
)
857 decl_vballoc_rec (o
, r
);
859 commit_auto_functions (r
);
861 if (structs
[r
].need_recalc_offsets
)
864 if (debugflag
.VIRTUALTABLES
)
867 return is_aliasclass (r
);
871 void produce_dtorables (OUTSTREAM o
, recID r
)
874 for (m
= structs
[r
].firstmember
; m
; m
= m
->next
)
875 if (isstructure (m
->t
) && has_dtor (base_of (m
->t
)))
876 outprintf (o
, structs
[base_of (m
->t
)].dtor_name
,
877 '(', '&', RESERVED_this
, POINTSAT
, m
->m
, ')', ';', -1);
881 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
883 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
885 static Token
*best_path (Token
*p1
, Token
*p2
)
892 for (i
= c1
= 0; p1
[i
] != -1; i
++)
893 if (p1
[i
] == POINTSAT
) c1
++;
894 for (i
= c2
= 0; p2
[i
] != -1; i
++)
895 if (p2
[i
] == POINTSAT
) c2
++;
898 return c1
< c2
? p1
: p2
;
900 for (i
= c1
= 0; p1
[i
] != -1; i
++)
901 if (p1
[i
] == '.') c1
++;
902 for (i
= c2
= 0; p2
[i
] != -1; i
++)
903 if (p2
[i
] == '.') c2
++;
906 return c1
< c2
? p1
: p2
;
909 do if (p1
[i
] != p2
[i
])
910 return strcmp (expand (p1
[i
]), expand (p2
[i
])) < 0 ? p1
: p2
;
911 while (p1
[i
++] != -1);
917 /* sort the ancestors from closest to oldest */
918 /* do we really need this? */
919 static void sort_ancestors (recID r
)
924 a
= structs
[r
].ancestors
;
925 for (i
= 0; a
[i
].rec
!= -1; i
++)
926 for (j
= i
+ 1; a
[j
].rec
!= -1; j
++)
927 if (intlen (a
[i
].path
) > intlen (a
[j
].path
)) {
935 static Token
*ext_path (Token nn
, Token
*p
, bool v
)
937 return p
? p
[0] == -1 ? sintprintf (mallocint (2), nn
, -1) :
938 sintprintf (mallocint (intlen (p
)+3), nn
, v
? POINTSAT
:'.', ISTR (p
), -1) : 0;
941 static bool make_ancestors (recID r
, recID ps
[], recID cvb
[])
943 int i
, j
, t
, k
, l
, c
= 0;
946 bool hv
= false, *vr
= (bool*) alloca (sizeof (bool) * intlen (ps
));
948 for (i
= 0; ps
[i
] != -1; i
++) {
949 if ((vr
[i
] = ps
[i
] >= VIRTUALPAR_BOOST
)) {
950 ps
[i
] -= VIRTUALPAR_BOOST
;
953 if (!structs
[ps
[i
]].notunion
)
954 parse_error_ll ("cannot inherit a union");
955 if (structs
[ps
[i
]].incomplete
)
956 parse_error (0, "You cannot inherit from something unborn");
957 if (structs
[ps
[i
]].constd
)
958 structs
[r
].constd
= true;
959 set_depend (r
, ps
[i
]);
962 for (i
= 0, t
= 1; ps
[i
] != -1; i
++, t
++)
963 if ((s
= &structs
[ps
[i
]])->ancestors
)
964 for (j
= 0; s
->ancestors
[j
].rec
!= -1; j
++)
967 a
= structs
[r
].ancestors
= (ancestor
*) malloc (sizeof (ancestor
) * t
);
969 /* Somethings like mutliple non-virtual inheritace
970 * of common base class, really ought to be forbidden.
971 * we can parse_error on ASTATUS_FSCKD for that...
973 for (i
= t
= 0; ps
[i
] != -1; i
++) {
975 Token nn
= name_inherited (name_of_struct (rr
));
977 bool zero_offset
= i
== 0 && !(V
&& vt_only (rr
));
981 for (k
= 0; k
< t
; k
++)
985 // new ancestor or existing ?
990 V2
= vparent (a
[k
].status
);
993 a
[k
].zero_displace
= false;
994 if (a
[k
].vbase
!= aliasclass (rr
))
997 a
[k
].path
= sintprintf (mallocint (2), nn
, -1);
998 if (a
[k
].status
== ASTATUS_VIRT2
) {
1000 sintprintf (a
[k
].cpath
= mallocint (2), nn
, -1);
1002 for (l
= 0; l
< c
; l
++)
1003 if (cvb
[l
] == rr
) break;
1004 if (l
== c
) cvb
[c
++] = rr
;
1005 } else really_fsckd1
: {
1006 a
[k
].status
= ASTATUS_FSCKD
;
1008 a
[k
].path
= sintprintf (mallocint (2), nn
, -1);
1012 a
[t
].status
= V
? vt_only (rr
) ? ASTATUS_VIRT
: ASTATUS_VIRT2
: ASTATUS_NORM
;
1013 a
[t
].zero_displace
= zero_offset
;
1014 a
[t
].direct
= true;
1015 a
[t
].path
= sintprintf (mallocint (2), nn
, -1);
1017 if (V
) a
[t
].vbase
= aliasclass (rr
);
1018 a
[t
].cpath
= a
[t
].status
!= ASTATUS_VIRT2
? 0 : sintprintf (mallocint (2), nn
, -1);
1020 if (s
->ctorables
|| s
->ancestors_have_ctors
)
1021 structs
[r
].ancestors_have_ctors
= true;
1024 // add ancestors of ancestor
1025 if ((a2
= s
->ancestors
))
1026 for (j
= 0; a2
[j
].rec
!= -1; j
++) {
1029 for (k
= 0; k
< t
; k
++)
1030 if (a
[k
].rec
== a2
[j
].rec
)
1034 if (vparent (a
[k
].status
)) {
1035 a
[k
].zero_displace
= false;
1036 if (a2
[j
].status
== a
[k
].status
) {
1037 if (a
[k
].vbase
!= a2
[j
].vbase
)
1040 if (a
[k
].vbase
!= aliasclass (rr
))
1042 } else goto really_fsckd2
;
1044 for (l
= 0; l
< c
; l
++)
1045 if (cvb
[l
] == a
[k
].vbase
) break;
1046 if (l
== c
) cvb
[c
++] = a
[k
].vbase
;
1048 Token
*path
= ext_path (nn
, a2
[j
].path
, V
);
1049 Token
*cpath
= ext_path (nn
, a2
[j
].cpath
, V
);
1051 if (best_path (a
[k
].path
, path
) == path
) {
1057 if (best_path (a
[k
].cpath
, cpath
) == cpath
) {
1058 if (a
[k
].cpath
) free (a
[k
].cpath
);
1059 a
[k
].cpath
= cpath
;
1060 } else free (cpath
); else;
1061 } else really_fsckd2
:
1062 a
[k
].status
= ASTATUS_FSCKD
;
1064 a
[t
].rec
= a2
[j
].rec
;
1065 a
[t
].status
= a2
[j
].status
;
1066 a
[t
].path
= ext_path (nn
, a2
[j
].path
, V
);
1067 a
[t
].vbase
= a2
[j
].vbase
;
1068 a
[t
].zero_displace
= a2
[j
].zero_displace
&& zero_offset
;
1069 a
[t
].depth
= a2
[j
].depth
+ 1;
1070 a
[t
].direct
= false;
1071 if (V
&& !vparent (a2
[j
].status
)) {
1072 a
[t
].status
= ASTATUS_VIRT
;
1073 a
[t
].vbase
= aliasclass (rr
);
1075 a
[t
++].cpath
= ext_path (nn
, a2
[j
].cpath
, V
);
1081 // sort_ancestors (r);
1083 for (i
= 0; i
< t
; i
++)
1084 if (a
[i
].status
== ASTATUS_VIRT
)
1085 structs
[r
].has_vbase
= true;
1086 else if (a
[i
].status
== ASTATUS_VIRT2
)
1087 structs
[r
].has_vbase2
= true;
1089 if (debugflag
.VIRTUALTABLES
) show_ancest (r
);
1094 /* If something is an alias class (typedef), undo the path extensions */
1095 static void undo_path (Token
*path
)
1097 if (path
[1] == -1) path
[0] = -1;
1098 else intcpy (path
, path
+ 2); // overlap but works
1101 static void undo_paths (recID r
)
1103 ancestor
*a
= structs
[r
].ancestors
;
1106 for (; a
->rec
!= -1; a
++) {
1107 if (a
->path
) undo_path (a
->path
);
1108 if (a
->cpath
) undo_path (a
->cpath
);
1112 bool zero_offset (recID rder
, recID rbase
)
1116 for (a
= structs
[rder
].ancestors
; a
; a
++)
1117 if (a
->rec
== rbase
)
1118 return a
->zero_displace
;
1122 static void inherit_auto_functions (recID
);
1124 void set_parents (recID r
, recID ps
[])
1126 /*bool have_virtual_inh;*/
1127 recID collapsed
[16];
1129 if (ps
[0] != -1 && !structs
[r
].notunion
)
1130 parse_error_ll ("union cannot be part of a hierarchy");
1132 /*have_virtual_inh =*/ make_ancestors (r
, ps
, collapsed
);
1133 inherit_all_virtuales (r
);
1134 inherit_auto_functions (r
);
1135 inherit_class_consts (r
);
1136 // if (have_virtual_inh) // this is leftover from surgery while implementing
1137 // make_rtti (r); // aliasclasses. hmmmmmmmmmmmmmmm. who knows?
1138 if (collapsed
[0] != -1)
1139 update_dcasts (r
, collapsed
);
1142 void output_parents (OUTSTREAM o
, recID r
)
1149 if (!(a
= structs
[r
].ancestors
))
1152 for (i
= 0; a
[i
].rec
!= -1; i
++)
1153 if (direct_ancest (&a
[i
])) {
1154 if (is_aliasclass (a
[i
].rec
)) {
1155 rec
= is_aliasclass (a
[i
].rec
);
1156 for (j
= 0; a
[j
].rec
!= rec
; ++j
);;;
1157 virt
= a
[j
].status
== ASTATUS_VIRT
;
1159 for (j
= 0; a
[j
].rec
!= -1; j
++) {
1160 if (a
[j
].path
[0] == a
[i
].path
[0] && a
[j
].path
[1] == '.')
1161 a
[j
].path
[1] = POINTSAT
;
1163 if (a
[j
].cpath
[0] == a
[i
].path
[0] && a
[j
].cpath
[1] == '.')
1164 a
[j
].path
[1] = POINTSAT
;
1168 virt
= a
[i
].status
== ASTATUS_VIRT
;
1170 for (j
= 0; j
< ri
; j
++)
1171 if (rp
[j
] == rec
) break;
1172 if (j
< ri
) continue;
1174 outprintf (o
, RESERVED_struct
, name_of_struct (rec
),
1175 STAR_IF (virt
), a
[i
].path
[0], ';', -1);
1178 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1180 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1182 int lookup_struct (Token e
)
1184 intnode
*n
= intfind (structtree
, e
);
1185 return n
? n
->v
.i
: 0;
1188 int is_struct (Token e
)
1190 intnode
*n
= intfind (structtree
, e
);
1191 return n
== NULL
? 0 : structs
[n
->v
.i
].notunion
;
1194 Token
name_of_struct (recID r
)
1196 return structs
[r
].name
;
1199 typeID
pthis_of_struct (recID r
)
1201 return structs
[r
].type_pthis
;
1204 fspace
FSP (recID r
)
1206 return r
? structs
[r
].Funcs
: Global
;
1209 bool has_const_members (recID r
)
1211 return structs
[r
].constd
|| structs
[r
].vt_inthis
;
1213 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1215 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1217 static Token
ancest_ptr (ancestor
*a
)
1219 return a
->status
== ASTATUS_VIRT
&& a
->vbase
== a
->rec
? POINTSAT
: '.';
1222 static typeID
has_member (recID r
, Token m
, Token path
[], Token
*glob_name
)
1226 for (M
= structs
[r
].firstmember
; M
; M
= M
->next
)
1230 if (glob_name
) *glob_name
= M
->gn
;
1237 for (a
= structs
[r
].anonunions
; a
; a
= a
->next
)
1238 if ((t
= has_member (a
->r
, m
, path
+ 2, glob_name
)) != -1) {
1247 typeID
lookup_variable_member (recID r
, Token m
, Token
*path
, bool const_path
, Token
*glob_name
)
1252 Token p
[64], nglob
= 0;
1253 bool vptrm
= m
== RESERVED__v_p_t_r_
;
1257 if ((t
= has_member (r
, m
, p
, glob_name
)) != -1) {
1259 if (path
) sintprintf (path
, ISTR (p
), -1);
1262 if ((a
= structs
[r
].ancestors
))
1263 for (i
= 0; a
[i
].rec
!= -1; i
++)
1264 if ((t
= has_member (a
[i
].rec
, m
, p
, &nglob
)) != -1) {
1265 if (rt
!= -1 || a
[i
].status
== ASTATUS_FSCKD
) {
1266 if (base_of (t
) == B_PURE
) {
1269 expr_errort ("Ambiguous vptr for class",
1270 name_of_struct (r
));
1272 expr_errort ("Ambigous member", m
);
1276 if (glob_name
) *glob_name
= nglob
;
1278 if (path
) sintprintf (path
,
1279 ISTR (const_path
&& a
[i
].cpath
? a
[i
].cpath
: a
[i
].path
),
1280 const_path
&& a
[i
].cpath
? '.' : ancest_ptr (&a
[i
]),
1287 static bool is_ctorable (typeID t
)
1289 return (isstructure (t
) && need_construction (base_of (t
)))
1290 || is_array_of_ctorable_objects (t
);
1293 void add_variable_member (recID r
, Token m
, typeID t
, Token gn
, bool constant
, bool ncto
)
1297 if (!structs
[r
].incomplete
)
1298 parse_error_ll ("structure closed");
1299 if (m
!= RESERVED__v_p_t_r_
&& (lt
= lookup_variable_member (r
, m
, 0, 0, 0)) != -1
1300 && base_of (lt
) != B_PURE
)
1301 parse_error_tok (m
, "member duplicate");
1302 if (!gn
&& !ncto
&& is_ctorable (t
)) {
1303 ctorable_t
*cc
= add_ctorable (r
);
1304 cc
->ot
= base_of (t
);
1305 cc
->array
= !isstructure (t
);
1308 if (!gn
&& !structs
[r
].constd
)
1309 if (constant
|| (isstructure (t
) && structs
[base_of (t
)].constd
))
1310 structs
[r
].constd
= true;
1311 member
*M
= (member
*) malloc (sizeof *M
);
1316 if (structs
[r
].firstmember
) {
1317 structs
[r
].lastmember
->next
= M
;
1318 structs
[r
].lastmember
= M
;
1320 structs
[r
].firstmember
= structs
[r
].lastmember
= M
;
1323 // #|#|#|#|#|#|#|#|#|#|#|#|#|#|#
1325 // #|#|#|#|#|#|#|#|#|#|#|#|#|#|#
1327 static bool have_exact_function_member (recID
, Token
, typeID
[], flookup
*);
1329 bool has_void_ctor (recID r
)
1331 typeID args
[] = { pthis_of_struct (r
), INTERNAL_ARGEND
};
1334 bool re
= have_exact_function_member (r
, RESERVED_ctor
, args
, &F
);
1335 if (re
) SET_MAYTHROW (F
);
1339 bool has_copy_ctor (recID r
)
1341 typeID args
[] = { pthis_of_struct (r
), pthis_of_struct (r
), INTERNAL_ARGEND
};
1344 bool re
= have_exact_function_member (r
, RESERVED_ctor
, args
, &F
);
1345 if (re
) SET_MAYTHROW (F
);
1349 void set_dfunc (recID r
, Token dn
, bool nothrow
, bool autodtor
)
1351 structs
[r
].dtor_nothrow
= nothrow
;
1352 structs
[r
].dtor_name
= dn
;
1353 structs
[r
].has_dtor
= true;
1354 structs
[r
].autodtor
|= autodtor
;
1357 bool isunion (recID r
)
1359 return !structs
[r
].notunion
;
1362 bool has_dtor (recID r
)
1364 return structs
[r
].has_dtor
;
1367 bool always_unwind (recID r
)
1369 return structs
[r
].unwind
;
1372 Token
dtor_name (recID r
)
1374 if (!structs
[r
].dtor_nothrow
)
1376 return structs
[r
].dtor_name
;
1379 void set_dtor_nothrow (recID r
)
1381 structs
[r
].dtor_nothrow
= true;
1384 Token
idtor (recID r
)
1386 return structs
[r
].idtor
;
1389 Token
vdtor (recID r
)
1391 return structs
[r
].vdtor
;
1394 void set_declaration (recID r
, Token
*code
)
1396 structs
[r
].code
= code
;
1399 static bool has_named_func (recID r
, Token f
)
1401 if (have_function (structs
[r
].Funcs
, f
)) return true;
1403 if ((a
= structs
[r
].ancestors
))
1404 for (; a
->rec
!= -1; a
++)
1405 if (have_function (structs
[a
->rec
].Funcs
, f
))
1410 bool has_ctors (recID r
)
1412 return has_named_func (r
, RESERVED_ctor
);
1415 bool has_oper_fcall (recID r
)
1417 return has_named_func (r
, RESERVED_oper_fcall
);
1419 // #+#+#+#+#+#+#+#+#+#+#+#+#
1421 // #+#+#+#+#+#+#+#+#+#+#+#+#
1423 // lookup a function in parent classes and inherit the useful
1424 // flags: AUTO, VIRTUAL, MODULAR
1425 int inherited_flagz (recID r
, Token f
, typeID t
)
1427 ancestor
*a
= structs
[r
].ancestors
;
1433 typeID
*pargl
= promoted_arglist_t (t
);
1434 typeID
*cargv
= (typeID
*) allocaint (intlen (pargl
) + 3);
1435 intcpy (cargv
, pargl
);
1438 for (; a
->rec
!= -1; a
++) {
1439 cargv
[0] = structs
[a
->rec
].type_pthis
;
1440 if ((p
= xlookup_function_dcl (structs
[a
->rec
].Funcs
, f
, cargv
)))
1444 return flagz
& (FUNCP_AUTO
| FUNCP_VIRTUAL
| FUNCP_MODULAR
);
1447 // lookup function flagz in declarations in class
1448 // useful flags: CONST-THIS, MODULAR, AUTO
1449 int exported_flagz (recID r
, Token f
, typeID t
)
1451 typeID
*argv
= promoted_arglist_t (t
);
1453 int ret
= FUNCP_UNDEF
;
1455 if ((p
= xlookup_function_dcl (structs
[r
].Funcs
, f
, argv
)))
1456 ret
= p
->flagz
& (FUNCP_CTHIS
| FUNCP_MODULAR
| FUNCP_AUTO
);
1461 static int looking_for
;
1463 static int has_fmember (recID r
, Token f
, typeID argv
[], flookup
*F
)
1465 if (!structs
[r
].Funcs
) return 0;
1466 argv
[0] = structs
[r
].type_pthis
;
1467 return xlookup_function (structs
[r
].Funcs
, f
, argv
, F
) == looking_for
;
1470 static bool _lookup_function_member (recID r
, Token f
, typeID argv
[], flookup
*F
)
1477 if ((lt
= has_fmember (r
, f
, argv
, F
)))
1480 if ((a
= structs
[r
].ancestors
))
1481 for (i
= 0; a
[i
].rec
!= -1; i
++)
1482 if ((lt
= has_fmember (a
[i
].rec
, f
, argv
, &tmp
))) {
1483 if (rt
== -1 || isancestor (a
[i
].rec
, rt
)) {
1484 if (a
[i
].status
== ASTATUS_FSCKD
)
1486 rt
= lt
== 1 ? a
[i
].rec
: -2;
1488 } else if (!isancestor (rt
, a
[i
].rec
)) really_fsckd
:
1489 expr_errort ("Ambigous member function", f
);
1494 argv
[0] = rt
>= 0 ? structs
[rt
].type_pthis
: -1;
1498 int lookup_function_member (recID r
, Token f
, typeID argv
[], flookup
*F
, bool definite
)
1501 if (_lookup_function_member (r
, f
, argv
, F
))
1504 // global function exact match > member function overload promotion
1505 if (!definite
&& xlookup_function (Global
, f
, &argv
[1], F
) == 3)
1509 if (_lookup_function_member (r
, f
, argv
, F
))
1513 return _lookup_function_member (r
, f
, argv
, F
);
1516 static Token
has_fmember_uname (recID r
, Token f
)
1518 if (!structs
[r
].Funcs
) return 0;
1519 return xlookup_function_uname (structs
[r
].Funcs
, f
);
1522 Token
lookup_function_member_uname (recID
*r
, Token f
)
1528 if ((lt
= has_fmember_uname (*r
, f
)))
1531 if ((a
= structs
[*r
].ancestors
))
1532 for (i
= 0; a
[i
].rec
!= -1; i
++)
1533 if ((rr
= has_fmember_uname (a
[i
].rec
, f
))) {
1534 if (rt
== -1 || isancestor (a
[i
].rec
, rt
)) {
1535 if (a
[i
].status
== ASTATUS_FSCKD
)
1539 } else if (!isancestor (rt
, a
[i
].rec
)) really_fsckd
:
1540 parse_error_tok (f
, "Ambigous member function");
1546 static bool have_exact_function_member (recID r
, Token f
, typeID argv
[], flookup
*F
)
1549 return _lookup_function_member (r
, f
, argv
, F
)
1550 || (looking_for
= 3, _lookup_function_member (r
, f
, argv
, F
));
1553 Token
declare_function_member (recID r
, Token f
, typeID t
, Token
*p
, Token
*a
, int fl
,
1554 Token
**d
, Token section
)
1556 if (!structs
[r
].notunion
)
1557 parse_error_ll ("unions may not be have member functions");
1558 funcp
*fp
= xdeclare_function (&structs
[r
].Funcs
, f
,
1559 name_member_function (r
, f
), t
, p
, a
, fl
, d
, section
);
1560 fp
->used
= !(fl
& FUNCP_AUTO
);
1563 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1565 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1567 bool Can_instantiate (recID r
)
1569 switch (structs
[r
].caninst
) {
1571 expr_errort ("Can't instantiate incomplete class", name_of_struct (r
));
1573 expr_errort ("Can't instantiate class. Pure virtual functions still in there",
1574 name_of_struct (r
));
1576 expr_errort ("Can't instantiate class."
1577 " No unique final overrider for virtual function", name_of_struct (r
));
1584 recID
ancest_named (recID r
, Token t
)
1586 ancestor
*a
= structs
[r
].ancestors
;
1588 while (a
->path
[0] != t
|| a
->path
[1] != -1)
1593 bool isancestor (recID rder
, recID rbase
)
1595 ancestor
*a
= structs
[rder
].ancestors
;
1597 if (a
) while (a
->rec
!= -1)
1598 if (a
++->rec
== rbase
) return true;
1600 return rder
== rbase
;
1603 int is_ancestor (recID rder
, recID rbase
, Token
**path
, bool const_path
)
1605 ancestor
*a
= structs
[rder
].ancestors
;
1609 for (; a
->rec
!= -1; a
++)
1610 if (a
->rec
== rbase
) {
1611 if (path
) *path
= const_path
&& a
->cpath
? a
->cpath
: a
->path
;
1612 if (a
->status
== ASTATUS_FSCKD
)
1613 expr_errort ("Ambigouus relationship", name_of_struct (rbase
));
1614 return a
->status
== ASTATUS_VIRT
&& a
->vbase
== a
->rec
&& !const_path
? 2:1;
1619 /* HOWTO: anestor status flags.
1621 ASTATUS_NORM ASTATUS_VIRT ASTATUS_VIRT2
1622 ---------------------------------------------
1623 ! -> for members No Yes No
1624 ! collapse vtis No Yes Yes
1625 ! declare vbase No Yes No
1626 ! const path No Yes Yes
1627 ! vtable good Yes No No
1628 ! downcast rtti No Yes Yes
1630 ***************************************************************/
1632 /* this here returns true if downcast rtti is needed to go from rbase to rder */
1633 bool is_ancestor_runtime (recID rder
, recID rbase
, Token
**path
)
1635 if (is_ancestor (rder
, rbase
, path
, false) == 2 || intchr (*path
, POINTSAT
))
1637 ancestor
*a
= structs
[rder
].ancestors
;
1638 while (a
->rec
!= rbase
) a
++;
1639 return a
->status
== ASTATUS_VIRT2
;
1642 // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1646 // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1648 bool PARENT_AUTOFUNCS
;
1650 void add_auto_f (Token ifn
, Token fn
, recID r
, typeID t
, bool virtual, bool pure
, NormPtr dclPtr
,
1651 Token
*proto
, Token
*argv
)
1654 typeID
*va
= promoted_arglist_t (t
);
1656 for (a
= structs
[r
].autofuncs
; a
; a
= a
->next
)
1657 if (a
->name
== fn
&& (arglist_compare (va
, a
->arglist
)
1658 || (PARENT_AUTOFUNCS
&& dclPtr
== a
->dclPtr
)))
1662 a
= add_autofunc (r
);
1665 a
->virtual = virtual;
1666 a
->status
= pure
? AU_STATUS_PV
: AU_STATUS_DD
;
1667 a
->dname
= a
->fname
= ifn
;
1672 //* commented out. does not allow to redefine an auto function
1673 //* with pure typedefs in its arguments in a class that they
1674 //* have been specialized... We only miss report of a rare error
1675 //if (a->status == AU_STATUS_DD)
1676 // parse_error_tok (fn, "auto-function redefined");
1678 if (virtual && !a
->virtual)
1679 parse_error_tok (fn
, "auto-function was not declared virtual");
1682 // PEND means it's inherited and we expect redef
1683 // !PEND means that user has supplied new definition
1684 // and we undo what we did the first time where PEND was true
1685 if (a
->status
!= AU_STATUS_PEND
)
1686 a
->dname
= ifn
, a
->pname
= -1;
1687 a
->status
= pure
? AU_STATUS_PV
: AU_STATUS_DD
;
1690 a
->proto
= intdup (proto
);
1691 a
->argv
= intdup (argv
);
1695 int borrow_auto_decls (recID r
, NormPtr ret
[])
1700 for (i
= 0, a
= structs
[r
].autofuncs
; a
; a
= a
->next
)
1701 if (a
->status
== AU_STATUS_ND
) {
1702 a
->status
= AU_STATUS_PEND
;
1703 ret
[i
++] = a
->dclPtr
;
1709 void repl__CLASS_ (Token
**proto
, recID r
)
1711 if (is_aliasclass (r
))
1712 intsubst (*proto
, RESERVED__CLASS_
, name_of_struct (r
));
1717 if ((*proto
) [i
] == RESERVED__CLASS_
) {
1718 tmp
[j
++] = RESERVED_struct
;
1719 tmp
[j
++] = name_of_struct (r
);
1721 } else if ((tmp
[j
++] = (*proto
) [i
++]) == -1) break;
1723 *proto
= intdup (tmp
);
1727 /* commit all the auto functions to require definition/instantiation */
1728 static void commit_auto_functions (recID r
)
1732 for (a
= structs
[r
].autofuncs
; a
; a
= a
->next
)
1733 if (a
->status
!= AU_STATUS_NU
) {
1734 if (is_aliasclass (r
))
1735 remove_struct_from_this (a
->proto
, r
);
1736 if (intchr (a
->proto
, RESERVED__CLASS_
))
1737 repl__CLASS_ (&a
->proto
, r
);
1738 commit_auto_define (a
->dname
, r
, a
->fname
, a
->pname
, a
->virtual,
1739 a
->proto
, a
->argv
, a
->type
);
1740 } else warning_tok ("No unique final overrider for auto function of",
1741 name_of_struct (r
));
1744 /* inherit auto functions and change DD to ND (not declared) */
1745 static void inherit_auto_functions (recID r
)
1751 a
= structs
[r
].ancestors
;
1753 for (i
= 0; a
[i
].rec
!= -1; i
++)
1754 if (direct_ancest (&a
[i
])) {
1755 for (af
= structs
[a
[i
].rec
].autofuncs
; af
; af
= af
->next
) {
1756 for (hf
= structs
[r
].autofuncs
; hf
; hf
= hf
->next
)
1757 if (hf
->name
== af
->name
&& arglist_compare (hf
->arglist
, af
->arglist
))
1760 if (af
->status
== AU_STATUS_PV
) continue;
1761 if (hf
->status
== AU_STATUS_PV
) goto wins
;
1762 if (hf
->status
== AU_STATUS_ND
&& af
->status
== AU_STATUS_DD
1763 && hf
->dclPtr
== af
->dclPtr
) continue;
1764 hf
->status
= AU_STATUS_NU
;
1766 hf
= add_autofunc (r
);
1768 hf
->name
= af
->name
;
1769 hf
->dname
= af
->dname
;
1770 hf
->pname
= hf
->fname
= af
->fname
;
1771 hf
->virtual = af
->virtual;
1772 hf
->status
= af
->status
;
1773 hf
->arglist
= intdup (af
->arglist
);
1774 hf
->dclPtr
= af
->dclPtr
;
1775 hf
->proto
= af
->proto
;
1776 hf
->argv
= af
->argv
;
1777 hf
->type
= af
->type
;
1778 if (hf
->status
== AU_STATUS_DD
)
1779 hf
->status
= AU_STATUS_ND
;
1782 if (structs
[a
[i
].rec
].autodtor
)
1783 structs
[r
].autodtor
= 1;
1787 /* upcast from this to a direct parent using constant path if avail */
1788 Token
*upcast1_this (recID rder
, recID rbase
)
1790 static Token retp
[15];
1791 ancestor
*a
= structs
[rder
].ancestors
;
1793 if (aliasclass (rder
) == aliasclass (rbase
))
1794 sintprintf (retp
, RESERVED_this
, -1);
1796 while (a
->rec
!= rbase
) a
++;
1798 if (a
->status
== ASTATUS_NORM
)
1799 sintprintf (retp
, '&', RESERVED_this
, POINTSAT
, a
->path
[0], -1);
1801 sintprintf (retp
, '&', RESERVED_this
, POINTSAT
, ISTR (a
->cpath
), -1);
1802 else sintprintf (retp
, RESERVED_this
, POINTSAT
, a
->path
[0], -1);
1808 // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1810 // pure data members
1812 // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1814 void add_pure_dm (recID r
, Token bt
, NormPtr dcl
)
1818 for (p
= structs
[r
].pm
; p
; p
= p
->next
)
1820 if (!intchr (p
->dcls
, dcl
))
1821 intcatc (p
->dcls
, dcl
);
1824 p
= (puredm
*) malloc (sizeof *p
);
1825 p
->next
= structs
[r
].pm
;
1828 sintprintf (p
->dcls
, dcl
, -1);
1831 void gen_pure_dm (recID r
, OUTSTREAM O
)
1834 ancestor
*a
= structs
[r
].ancestors
;
1838 if (a
) for (i
= 0; a
[i
].rec
!= -1; i
++)
1839 if (direct_ancest (&a
[i
]))
1840 for (p
= structs
[a
[i
].rec
].pm
; p
; p
= p
->next
) {
1841 if ((t
= lookup_local_typedef (r
, p
->bt
))
1842 && base_of (lookup_typedef (t
)) != B_PURE
)
1843 for (j
= 0; p
->dcls
[j
] != -1; j
++)
1844 struct_declaration (r
, O
, p
->dcls
[j
]);
1845 else for (j
= 0; p
->dcls
[j
] != -1; j
++)
1846 add_pure_dm (r
, p
->bt
, p
->dcls
[j
]);
1850 //************************************************************
1851 // renaming functions due to overload adds complexity
1852 //************************************************************
1854 void rename_hier (Token on
, Token nn
)
1859 for (i
= 0; i
< nstructs
; i
++)
1860 if (structs
[i
].incomplete
) {
1861 for (a
= structs
[i
].autofuncs
; a
; a
= a
->next
) {
1862 // one of the two is redundant
1863 if (a
->dname
== on
) a
->dname
= nn
;
1864 if (a
->fname
== on
) {
1866 if (intchr (a
->proto
, on
))
1867 intsubst1 (a
->proto
, on
, nn
);
1870 if (structs
[i
].keyfunc
== on
)
1871 structs
[i
].keyfunc
= nn
;