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 inline bool direct_ancest (ancestor
*);
206 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
))
354 if (e
) expr_errort ("Ambiguous local typedef", tn
);
356 if (ret
&& objective
.recording
)
357 usage_typeID (lookup_typedef (ret
));
362 static Token
direct_vparent (recID rd
, recID rb
)
366 if (rd
== rb
) return 0;
368 if ((a
= structs
[rd
].ancestors
))
369 for (; a
->rec
!= -1; a
++)
370 if (a
->rec
== rb
&& a
->status
== ASTATUS_VIRT
371 && a
->path
[1] == -1) return a
->path
[0];
375 /* generate the code which sets the address of the common shared
376 base class instance to the pointers that are supposed to point to it */
377 static void gen_construction_code_vb (OUTSTREAM o
, recID r
, Token obj
)
381 ancestor
*a
= structs
[r
].ancestors
;
384 for (i
= 0; a
[i
].rec
!= -1; i
++)
385 if (a
[i
].status
== ASTATUS_VIRT
&& a
[i
].vbase
== a
[i
].rec
) {
386 recID vr
= a
[i
].vbase
, r2
;
387 for (j
= 0; a
[j
].rec
!= -1; j
++)
388 if (!is_aliasclass (a
[j
].rec
))
389 if ((m
= direct_vparent (r2
= aliasclass (a
[j
].rec
), vr
))) {
390 is_ancestor (r
, r2
, &p
, true);
391 outprintf (o
, obj
, POINTSAT
, ISTR (p
),
394 if (direct_vparent (r
, vr
)) {
395 outprintf (o
, obj
, POINTSAT
, a
[i
].path
[0], '=', -1);
397 is_ancestor (r
, vr
, &p
, true);
398 outprintf (o
, '&', obj
, POINTSAT
, ISTR (p
), ';', -1);
402 /* construction code in case base obj is just a vtable */
403 static void gen_construction_code_vb2 (OUTSTREAM o
, recID r
, Token obj
)
407 ancestor
*a
= structs
[r
].ancestors
;
410 for (i
= 0; a
[i
].rec
!= -1; i
++)
411 if (a
[i
].status
== ASTATUS_VIRT2
) {
415 for (j
= 0; a
[j
].rec
!= -1; j
++)
416 if (a
[j
].rec
!= a
[i
].rec
&& direct_ancest (&a
[j
])
417 && is_ancestor (aliasclass (a
[j
].rec
), a
[i
].rec
, &p
, 1)) {
418 p2
= a
[j
].cpath
?: a
[j
].path
;
419 if (p1
[0] == p2
[0]) continue;
420 outprintf (o
, obj
, POINTSAT
, ISTR (p2
), '.',
421 ISTR (p
), '.', RESERVED__v_p_t_r_
, '=', -1);
425 if (hp
) outprintf (o
, obj
, POINTSAT
, ISTR (a
[i
].cpath
), '.',
426 RESERVED__v_p_t_r_
, ';', -1);
430 /* generate the code that calls the init function for a ctorable */
431 static void call_init_func (OUTSTREAM o
, Token obj
, ctorable_t
*c
, Token
*path
)
433 if (c
->array
) outprintf (o
, i_call_initialization (c
->ot
), '(',
434 obj
, POINTSAT
, ISTR (path
), DOT_IF (path
[0] != -1), c
->obn
, ',',
435 RESERVED_sizeof
, obj
, POINTSAT
, ISTR (path
),
436 DOT_IF (path
[0] != -1), c
->obn
, '/',
437 RESERVED_sizeof
, '(', iRESERVED_struct (c
->ot
),
438 name_of_struct (c
->ot
), ')', ')', ';', -1);
439 else outprintf (o
, i_call_initialization (c
->ot
), '(',
440 '&', obj
, POINTSAT
, ISTR (path
), DOT_IF (path
[0] != -1),
441 c
->obn
, ',', RESERVED_1
, ')', ';', -1);
444 /* Construct all members that need construction indeed yes */
445 static void gen_member_construction (OUTSTREAM o
, recID r
, Token obj
)
448 ctorable_t
*c
= structs
[r
].ctorables
;
449 Token nopath
[] = { -1 };
452 if (c
) for (i
= 0; c
[i
].ot
!= -1; i
++)
453 call_init_func (o
, obj
, &c
[i
], nopath
);
455 if (structs
[r
].ancestors_have_ctors
)
456 for (a
= structs
[r
].ancestors
; a
->rec
!= -1; a
++)
457 if ((c
= structs
[a
->rec
].ctorables
))
458 for (i
= 0; c
[i
].ot
!= -1; i
++)
459 call_init_func (o
, obj
, &c
[i
], a
->cpath
?: a
->path
);
462 void gen_construction_code (OUTSTREAM o
, recID r
, Token obj
)
464 if (structs
[r
].has_vbase
)
465 gen_construction_code_vb (o
, r
, obj
);
466 if (structs
[r
].vtis
)
467 gen_vt_init (o
, r
, obj
, true);
468 if (structs
[r
].has_vbase2
)
469 gen_construction_code_vb2 (o
, r
, obj
);
470 if (structs
[r
].ctorables
|| structs
[r
].ancestors_have_ctors
)
471 gen_member_construction (o
, r
, obj
);
473 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
475 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
477 static intnode
*structtree
;
478 static int nstructs
, nallocstructs
;
480 recID
enter_struct (Token e
, Token tag
, bool unwind
, bool noctor
, bool evt
, bool sclass
)
482 intnode
*in
= intfind (structtree
, e
);
483 int pt
[3] = { nstructs
, '*', -1 };
487 if (unwind
&& !always_unwind (r
))
488 structs
[r
].unwind
= true;
490 structs
[r
].noctor
= true;
494 if (nstructs
== nallocstructs
)
495 structs
= (structure
*) realloc (structs
, (nallocstructs
+=96) * sizeof (structure
));
496 structs
[nstructs
].name
= e
;
497 structs
[nstructs
].notunion
= tag
!= RESERVED_union
;
498 structs
[nstructs
].deftype
= false;
499 structs
[nstructs
].class = tag
== RESERVED_class
;
500 structs
[nstructs
].incomplete
= true;
501 structs
[nstructs
].has_dtor
= false;
502 structs
[nstructs
].idtor
= 0;
503 structs
[nstructs
].vdtor
= 0;
504 structs
[nstructs
].dtor_name
= 0;
505 structs
[nstructs
].dtor_nothrow
= false;
506 structs
[nstructs
].Funcs
= 0;
507 structs
[nstructs
].has_dtorable
= false;
508 structs
[nstructs
].firstmember
= 0;
509 structs
[nstructs
].printed
= false;
510 structs
[nstructs
].unwind
= unwind
;
511 structs
[nstructs
].noctor
= noctor
;
512 structs
[nstructs
].evt
= evt
;
513 structs
[nstructs
].has_vbase
= 0;
514 structs
[nstructs
].has_vbase2
= 0;
515 structs
[nstructs
].rtti
= 0;
516 structs
[nstructs
].vtis
= 0;
517 structs
[nstructs
].ancestors
= 0;
518 structs
[nstructs
].ctorables
= 0;
519 structs
[nstructs
].autofuncs
= 0;
520 structs
[nstructs
].anonunions
= 0;
521 structs
[nstructs
].ltdef
= 0;
522 structs
[nstructs
].nanons
= 0;
523 structs
[nstructs
].consts
= 0;
524 structs
[nstructs
].caninst
= CANT_INCOMPL
;
525 structs
[nstructs
].type_pthis
= enter_type (pt
);
526 structs
[nstructs
].used
= false;
527 structs
[nstructs
].code
= 0;
528 structs
[nstructs
].depends
= 0;
529 structs
[nstructs
].ancestors_have_ctors
= 0;
530 structs
[nstructs
].need_recalc_offsets
= 0;
531 structs
[nstructs
].have_vi_decls
= 0;
532 structs
[nstructs
].vt_inthis
= false;
533 structs
[nstructs
].alias_class
= nstructs
;
534 structs
[nstructs
].constd
= 0;
535 structs
[nstructs
].pm
= 0;
536 structs
[nstructs
].keyfunc
= sclass
? -1 : 0;
537 structs
[nstructs
].havekey
= 0;
538 structs
[nstructs
].autodtor
= 0;
539 union ival i
= { i
: nstructs
};
540 intadd (&structtree
, e
, i
);
544 void keyfunc_candidate (recID o
, Token k
)
546 if (!structs
[o
].keyfunc
)
547 //{PRINTF ("Setting keyfunc of "COLS"%s"COLE":%s\n", SNM(o), expand (k));
548 structs
[o
].keyfunc
= k
;
552 void possible_keyfunc (recID o
, Token k
)
554 //PRINTF ("possible %s:%s ", SNM(o), expand(k));
555 if (structs
[o
].keyfunc
== k
)
556 //{PRINTF ("-ok-\n");
557 structs
[o
].havekey
= 1;
558 //}else PRINTF ("\n");
561 void set_depend (recID o
, recID i
)
564 if (structs
[o
].depends
) {
565 for (j
= 0; structs
[o
].depends
[j
] != -1; j
++);
569 structs
[o
].depends
= (recID
*) realloc (structs
[o
].depends
, j
* sizeof (recID
));
570 structs
[o
].depends
[j
- 2] = i
;
571 structs
[o
].depends
[j
- 1] = -1;
574 static void export_struct (recID r
)
578 if (structs
[r
].printed
) return;
580 if (structs
[r
].depends
)
581 for (i
= 0; structs
[r
].depends
[i
] != -1; i
++)
582 export_struct (structs
[r
].depends
[i
]);
584 if (structs
[r
].vtis
)
585 export_virtual_table_declaration (r
);
587 if (structs
[r
].Funcs
)
588 export_fspace_lwc (structs
[r
].Funcs
);
590 structs
[r
].printed
= true;
591 if (structs
[r
].code
)
592 outprintf (STRUCTS
, ISTR (structs
[r
].code
), -1);
595 void export_structs ()
598 for (r
= 0; r
< nstructs
; r
++)
602 static void commit_auto_functions (recID
);
604 /////////////////////////////////////////////////
605 // some things when declaration completes
606 /////////////////////////////////////////////////
608 void remove_struct_from_this (Token
*p
, recID r
)
611 if (intchr (p
, RESERVED_this
)) {
612 for (i
= 0; p
[i
] != RESERVED_this
; i
++);
613 while (p
[i
] != RESERVED_struct
&& p
[i
] != '(') i
--;
615 intcpy (p
+ i
, p
+ i
+ 1);
617 Token sn
= name_of_struct (r
);
618 for (i
= 0; p
[i
] != -1; p
++)
619 if (p
[i
] == RESERVED_struct
&& p
[i
+ 1] == sn
)
620 for (j
= i
; p
[j
] != -1; j
++)
624 static void adjust_protos (fspace S
, recID r
)
628 funcp
*p
= (funcp
*) S
->v
.p
;
629 for (; p
; p
= p
->next
)
630 if (p
->prototype
&& !(p
->flagz
& FUNCP_MODULAR
)) {
631 remove_struct_from_this (p
->prototype
, r
);
632 remove_struct_from_def (p
->name
);
634 adjust_protos (S
->less
, r
);
635 adjust_protos (S
->more
, r
);
638 static void make_empty_dtor (recID r
)
640 Token proto
[] = { RESERVED_static
, RESERVED_inline
, RESERVED_dtor
, '(', ')', ';', -1 };
641 SAVE_VAR (CODE
, proto
);
642 bool haskey
= structs
[r
].keyfunc
!= 0;
643 struct_declaration (r
, 0, 0);
644 if (!haskey
&& structs
[r
].keyfunc
)
645 structs
[r
].keyfunc
= 0;
647 store_define_dtor (structs
[r
].dtor_name
, r
);
650 static void study_destruction (recID r
)
652 bool b
= false, v
= false;
655 ancestor
*a
= structs
[r
].ancestors
;
657 for (m
= structs
[r
].firstmember
; m
; m
= m
->next
)
658 if (isstructure (m
->t
) && has_dtor (base_of (m
->t
))) {
663 if (a
) for (i
= 0; a
[i
].rec
!= -1; i
++)
664 if (vparent (a
[i
].status
)) v
= true;
665 else if (direct_ancest (&a
[i
]) && has_dtor (a
[i
].rec
))
668 // - vdtor is the destructor that doesn't call the dtors
669 // of the virtual base classes
670 // - idtor calls dtors of dtorable members and vdtors (or normal
671 // dtors in not exist) of direct non virtual parents.
672 // - the real dtor calls vdtor and then calls the dtors
673 // of virtual parents
676 if (!structs
[r
].has_dtor
)
678 structs
[r
].idtor
= name_intern_dtor (r
);
680 if (v
) structs
[r
].vdtor
= name_intern_vdtor (r
);
683 OUTSTREAM
dispatch_vdtor (recID r
, OUTSTREAM o
)
686 Token
*vd
= combine_output (o
);
687 OUTSTREAM n
= new_stream ();
688 ancestor
*a
= structs
[r
].ancestors
;
690 for (i
= 0; vd
[i
] != '{'; i
++)
691 output_itoken (n
, vd
[i
]);
692 outprintf (n
, '{', structs
[r
].vdtor
, '(', RESERVED_this
, ')', ';', -1);
693 for (i
= 0; a
[i
].rec
!= -1; i
++)
694 if (vparent (a
[i
].status
))
695 outprintf (n
, structs
[a
[i
].rec
].vdtor
?:
696 structs
[a
[i
].rec
].dtor_name
, '(',
697 ADDR_IF (a
[i
].cpath
&& a
[i
].cpath
[0] != -1), RESERVED_this
,
698 POINTSAT_IF ((a
[i
].cpath
?: a
[i
].path
) [0] != -1),
699 ISTR (a
[i
].cpath
?: a
[i
].path
), ')', ';', -1);
700 outprintf (n
, RESERVED_return
, RESERVED_this
, ';', '}', -1);
702 intsubst1 (vd
, structs
[r
].dtor_name
, structs
[r
].vdtor
);
703 outprintf (INTERNAL_CODE
, ISTR (vd
), -1);
709 void make_intern_dtor (recID r
)
713 ancestor
*a
= structs
[r
].ancestors
;
714 Token do_alias
= HaveAliases
? 0 : -1;
715 #ifdef BROKEN_ALIASES
719 OUTSTREAM O
= new_stream ();
721 outprintf (O
, R(static), R(inline), R(void), structs
[r
].idtor
, '(',
722 iRESERVED_struct (r
), name_of_struct (r
), '*', R(this), ')', '{', -1);
724 /* call dtors of dtorable data members */
725 for (m
= structs
[r
].firstmember
; m
; m
= m
->next
)
726 if (isstructure (m
->t
) && has_dtor (base_of (m
->t
))) {
727 outprintf (O
, dtor_name (base_of (m
->t
)),
728 '(', '&', RESERVED_this
, POINTSAT
, m
->m
, ')', ';', -1);
732 /* call vdtors of parents (non virtual parents that is) */
733 if (a
) for (i
= 0; a
[i
].rec
!= -1; i
++)
734 if (direct_ancest (&a
[i
]) && has_dtor (a
[i
].rec
) && !vparent (a
[i
].status
)
735 && !(structs
[a
[i
].rec
].autodtor
&& !idtor (a
[i
].rec
))) {
736 bool dointernal
= structs
[a
[i
].rec
].autodtor
;
738 /* If this is an auto function call only idtor of parent.
739 else if parent has vbases, call vdtor of parent.
740 else call dtor of parent */
741 dointernal
? idtor (a
[i
].rec
) :
742 structs
[a
[i
].rec
].vdtor
?:
743 dtor_name (a
[i
].rec
), '(',
744 ISTR (upcast1_this (r
, a
[i
].rec
)), ')', ';', -1);
745 if (do_alias
) do_alias
= -1;
746 else do_alias
= zero_offset (r
, a
[i
].rec
) && !dointernal
?
747 dtor_name (afcls
= a
[i
].rec
) : -1;
749 output_itoken (O
, '}');
751 /* do it with alias if all that has to be done is call the dtor of one parent
752 which is at offset 0 */
755 outprintf (O
= new_stream (), R(static), R(inline), R(void), structs
[r
].idtor
, '(',
756 iRESERVED_struct (r
), name_of_struct (r
), '*', R(this), ')',
757 alias_func (afcls
, do_alias
), ';', -1);
759 concate_streams (INTERNAL_CODE
, O
);
762 static void enter_virtuals (recID r
, fspace S
)
766 for (p
= S
->v
.p
; p
; p
= p
->next
)
767 if ((p
->flagz
& FUNCP_VIRTUAL
) && p
->prototype
) {
773 args
.ftype
= p
->type
;
774 args
.fmemb
= p
->flagz
& FUNCP_PURE
? 0 : p
->name
;
775 args
.flagz
= p
->flagz
;
776 // pass prototype to make fptr from
777 for (pr
= p
->prototype
; ISDCLFLAG (*pr
); pr
++);
778 args
.prototype
= allocaint (intlen (pr
) + 1);
779 intcpy (args
.prototype
, pr
);
780 intsubst1 (args
.prototype
, p
->name
, MARKER
);
781 args
.argv
= allocaint (intlen (p
->xargs
) + 1);
782 intcpy (args
.argv
, p
->xargs
);
783 Enter_virtual_function (&args
);
785 if (S
->less
) enter_virtuals (r
, S
->less
);
786 if (S
->more
) enter_virtuals (r
, S
->more
);
789 bool do_alias_class (recID r
)
792 ancestor
*a
= structs
[r
].ancestors
;
794 if (structs
[r
].firstmember
|| structs
[r
].vt_inthis
|| !a
|| structs
[r
].anonunions
)
797 for (; a
->rec
!= -1; a
++)
798 if (direct_ancest (a
)) {
799 rr
= structs
[a
->rec
].alias_class
;
800 if (alias
&& rr
!= alias
)
804 structs
[r
].alias_class
= alias
;
808 recID
is_aliasclass (recID r
)
810 if (structs
[r
].incomplete
&& structs
[r
].class) {
811 structs
[r
].deftype
= true;
814 return structs
[r
].alias_class
== r
? 0 : structs
[r
].alias_class
;
817 recID
aliasclass (recID r
)
819 return structs
[r
].alias_class
;
822 static void undo_paths (recID
);
824 recID
complete_structure (OUTSTREAM o
, recID r
)
826 structs
[r
].incomplete
= false;
827 study_destruction (r
);
828 if (do_alias_class (r
)) {
830 adjust_protos (structs
[r
].Funcs
, r
);
831 structs
[r
].has_vbase
= 0;
832 structs
[r
].has_vbase2
= 0;
834 if (structs
[r
].class) {
835 if (structs
[r
].deftype
) outprintf (GLOBAL
, RESERVED_typedef
,
836 RESERVED_struct
, name_of_struct (r
), name_of_struct (r
), ';', -1);
837 //else outprintf (GLOBAL, RESERVED_struct, name_of_struct (r), ';', -1);
839 if (structs
[r
].ancestors
) make_rtti (r
);
841 if (structs
[r
].Funcs
)
842 enter_virtuals (r
, structs
[r
].Funcs
);
843 //**+*+*+*+*+*+*+*+*+*+*+*+*
844 close_inits (&structs
[r
]);
846 if (can_instantiate (r
)) {
847 if (structs
[r
].has_vbase
)
848 decl_vballoc_rec (o
, r
);
850 commit_auto_functions (r
);
852 if (structs
[r
].need_recalc_offsets
)
855 if (debugflag
.VIRTUALTABLES
)
858 return is_aliasclass (r
);
862 void produce_dtorables (OUTSTREAM o
, recID r
)
865 for (m
= structs
[r
].firstmember
; m
; m
= m
->next
)
866 if (isstructure (m
->t
) && has_dtor (base_of (m
->t
)))
867 outprintf (o
, structs
[base_of (m
->t
)].dtor_name
,
868 '(', '&', RESERVED_this
, POINTSAT
, m
->m
, ')', ';', -1);
872 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
874 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
876 static Token
*best_path (Token
*p1
, Token
*p2
)
883 for (i
= c1
= 0; p1
[i
] != -1; i
++)
884 if (p1
[i
] == POINTSAT
) c1
++;
885 for (i
= c2
= 0; p2
[i
] != -1; i
++)
886 if (p2
[i
] == POINTSAT
) c2
++;
889 return c1
< c2
? p1
: p2
;
891 for (i
= c1
= 0; p1
[i
] != -1; i
++)
892 if (p1
[i
] == '.') c1
++;
893 for (i
= c2
= 0; p2
[i
] != -1; i
++)
894 if (p2
[i
] == '.') c2
++;
897 return c1
< c2
? p1
: p2
;
900 do if (p1
[i
] != p2
[i
])
901 return strcmp (expand (p1
[i
]), expand (p2
[i
])) < 0 ? p1
: p2
;
902 while (p1
[i
++] != -1);
908 /* sort the ancestors from closest to oldest */
909 /* do we really need this? */
910 static void sort_ancestors (recID r
)
915 a
= structs
[r
].ancestors
;
916 for (i
= 0; a
[i
].rec
!= -1; i
++)
917 for (j
= i
+ 1; a
[j
].rec
!= -1; j
++)
918 if (intlen (a
[i
].path
) > intlen (a
[j
].path
)) {
926 static Token
*ext_path (Token nn
, Token
*p
, bool v
)
928 return p
? p
[0] == -1 ? sintprintf (mallocint (2), nn
, -1) :
929 sintprintf (mallocint (intlen (p
)+3), nn
, v
? POINTSAT
:'.', ISTR (p
), -1) : 0;
932 static bool make_ancestors (recID r
, recID ps
[], recID cvb
[])
934 int i
, j
, t
, k
, l
, c
= 0;
937 bool hv
= false, *vr
= (bool*) alloca (sizeof (bool) * intlen (ps
));
939 for (i
= 0; ps
[i
] != -1; i
++) {
940 if ((vr
[i
] = ps
[i
] >= VIRTUALPAR_BOOST
)) {
941 ps
[i
] -= VIRTUALPAR_BOOST
;
944 if (!structs
[ps
[i
]].notunion
)
945 parse_error_ll ("cannot inherit a union");
946 if (structs
[ps
[i
]].incomplete
)
947 parse_error (0, "You cannot inherit from something unborn");
948 if (structs
[ps
[i
]].constd
)
949 structs
[r
].constd
= true;
950 set_depend (r
, ps
[i
]);
953 for (i
= 0, t
= 1; ps
[i
] != -1; i
++, t
++)
954 if ((s
= &structs
[ps
[i
]])->ancestors
)
955 for (j
= 0; s
->ancestors
[j
].rec
!= -1; j
++)
958 a
= structs
[r
].ancestors
= (ancestor
*) malloc (sizeof (ancestor
) * t
);
960 /* Somethings like mutliple non-virtual inheritace
961 * of common base class, really ought to be forbidden.
962 * we can parse_error on ASTATUS_FSCKD for that...
964 for (i
= t
= 0; ps
[i
] != -1; i
++) {
966 Token nn
= name_inherited (name_of_struct (rr
));
968 bool zero_offset
= i
== 0 && !(V
&& vt_only (rr
));
972 for (k
= 0; k
< t
; k
++)
976 // new ancestor or existing ?
981 V2
= vparent (a
[k
].status
);
984 a
[k
].zero_displace
= false;
985 if (a
[k
].vbase
!= aliasclass (rr
))
988 a
[k
].path
= sintprintf (mallocint (2), nn
, -1);
989 if (a
[k
].status
== ASTATUS_VIRT2
) {
991 sintprintf (a
[k
].cpath
= mallocint (2), nn
, -1);
993 for (l
= 0; l
< c
; l
++)
994 if (cvb
[l
] == rr
) break;
995 if (l
== c
) cvb
[c
++] = rr
;
996 } else really_fsckd1
: {
997 a
[k
].status
= ASTATUS_FSCKD
;
999 a
[k
].path
= sintprintf (mallocint (2), nn
, -1);
1003 a
[t
].status
= V
? vt_only (rr
) ? ASTATUS_VIRT
: ASTATUS_VIRT2
: ASTATUS_NORM
;
1004 a
[t
].zero_displace
= zero_offset
;
1005 a
[t
].direct
= true;
1006 a
[t
].path
= sintprintf (mallocint (2), nn
, -1);
1008 if (V
) a
[t
].vbase
= aliasclass (rr
);
1009 a
[t
].cpath
= a
[t
].status
!= ASTATUS_VIRT2
? 0 : sintprintf (mallocint (2), nn
, -1);
1011 if (s
->ctorables
|| s
->ancestors_have_ctors
)
1012 structs
[r
].ancestors_have_ctors
= true;
1015 // add ancestors of ancestor
1016 if ((a2
= s
->ancestors
))
1017 for (j
= 0; a2
[j
].rec
!= -1; j
++) {
1020 for (k
= 0; k
< t
; k
++)
1021 if (a
[k
].rec
== a2
[j
].rec
)
1025 if (vparent (a
[k
].status
)) {
1026 a
[k
].zero_displace
= false;
1027 if (a2
[j
].status
== a
[k
].status
) {
1028 if (a
[k
].vbase
!= a2
[j
].vbase
)
1031 if (a
[k
].vbase
!= aliasclass (rr
))
1033 } else goto really_fsckd2
;
1035 for (l
= 0; l
< c
; l
++)
1036 if (cvb
[l
] == a
[k
].vbase
) break;
1037 if (l
== c
) cvb
[c
++] = a
[k
].vbase
;
1039 Token
*path
= ext_path (nn
, a2
[j
].path
, V
);
1040 Token
*cpath
= ext_path (nn
, a2
[j
].cpath
, V
);
1042 if (best_path (a
[k
].path
, path
) == path
) {
1048 if (best_path (a
[k
].cpath
, cpath
) == cpath
) {
1049 if (a
[k
].cpath
) free (a
[k
].cpath
);
1050 a
[k
].cpath
= cpath
;
1051 } else free (cpath
); else;
1052 } else really_fsckd2
:
1053 a
[k
].status
= ASTATUS_FSCKD
;
1055 a
[t
].rec
= a2
[j
].rec
;
1056 a
[t
].status
= a2
[j
].status
;
1057 a
[t
].path
= ext_path (nn
, a2
[j
].path
, V
);
1058 a
[t
].vbase
= a2
[j
].vbase
;
1059 a
[t
].zero_displace
= a2
[j
].zero_displace
&& zero_offset
;
1060 a
[t
].depth
= a2
[j
].depth
+ 1;
1061 a
[t
].direct
= false;
1062 if (V
&& !vparent (a2
[j
].status
)) {
1063 a
[t
].status
= ASTATUS_VIRT
;
1064 a
[t
].vbase
= aliasclass (rr
);
1066 a
[t
++].cpath
= ext_path (nn
, a2
[j
].cpath
, V
);
1072 // sort_ancestors (r);
1074 for (i
= 0; i
< t
; i
++)
1075 if (a
[i
].status
== ASTATUS_VIRT
)
1076 structs
[r
].has_vbase
= true;
1077 else if (a
[i
].status
== ASTATUS_VIRT2
)
1078 structs
[r
].has_vbase2
= true;
1080 if (debugflag
.VIRTUALTABLES
) show_ancest (r
);
1085 /* If something is an alias class (typedef), undo the path extensions */
1086 static void undo_path (Token
*path
)
1088 if (path
[1] == -1) path
[0] = -1;
1089 else intcpy (path
, path
+ 2); // overlap but works
1092 static void undo_paths (recID r
)
1094 ancestor
*a
= structs
[r
].ancestors
;
1097 for (; a
->rec
!= -1; a
++) {
1098 if (a
->path
) undo_path (a
->path
);
1099 if (a
->cpath
) undo_path (a
->cpath
);
1103 bool zero_offset (recID rder
, recID rbase
)
1107 for (a
= structs
[rder
].ancestors
; a
; a
++)
1108 if (a
->rec
== rbase
)
1109 return a
->zero_displace
;
1113 static void inherit_auto_functions (recID
);
1115 void set_parents (recID r
, recID ps
[])
1117 bool have_virtual_inh
;
1118 recID collapsed
[16];
1120 if (ps
[0] != -1 && !structs
[r
].notunion
)
1121 parse_error_ll ("union cannot be part of a hierarchy");
1123 have_virtual_inh
= make_ancestors (r
, ps
, collapsed
);
1124 inherit_all_virtuales (r
);
1125 inherit_auto_functions (r
);
1126 inherit_class_consts (r
);
1127 // if (have_virtual_inh) // this is leftover from surgery while implementing
1128 // make_rtti (r); // aliasclasses. hmmmmmmmmmmmmmmm. who knows?
1129 if (collapsed
[0] != -1)
1130 update_dcasts (r
, collapsed
);
1133 void output_parents (OUTSTREAM o
, recID r
)
1140 if (!(a
= structs
[r
].ancestors
))
1143 for (i
= 0; a
[i
].rec
!= -1; i
++)
1144 if (direct_ancest (&a
[i
])) {
1145 if (is_aliasclass (a
[i
].rec
)) {
1146 rec
= is_aliasclass (a
[i
].rec
);
1147 for (j
= 0; a
[j
].rec
!= rec
; ++j
);;;
1148 virt
= a
[j
].status
== ASTATUS_VIRT
;
1150 for (j
= 0; a
[j
].rec
!= -1; j
++) {
1151 if (a
[j
].path
[0] == a
[i
].path
[0] && a
[j
].path
[1] == '.')
1152 a
[j
].path
[1] = POINTSAT
;
1154 if (a
[j
].cpath
[0] == a
[i
].path
[0] && a
[j
].cpath
[1] == '.')
1155 a
[j
].path
[1] = POINTSAT
;
1159 virt
= a
[i
].status
== ASTATUS_VIRT
;
1161 for (j
= 0; j
< ri
; j
++)
1162 if (rp
[j
] == rec
) break;
1163 if (j
< ri
) continue;
1165 outprintf (o
, RESERVED_struct
, name_of_struct (rec
),
1166 STAR_IF (virt
), a
[i
].path
[0], ';', -1);
1169 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1171 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1173 int lookup_struct (Token e
)
1175 intnode
*n
= intfind (structtree
, e
);
1176 return n
? n
->v
.i
: 0;
1179 int is_struct (Token e
)
1181 intnode
*n
= intfind (structtree
, e
);
1182 return n
== NULL
? 0 : structs
[n
->v
.i
].notunion
;
1185 Token
name_of_struct (recID r
)
1187 return structs
[r
].name
;
1190 typeID
pthis_of_struct (recID r
)
1192 return structs
[r
].type_pthis
;
1195 fspace
FSP (recID r
)
1197 return r
? structs
[r
].Funcs
: Global
;
1200 bool has_const_members (recID r
)
1202 return structs
[r
].constd
|| structs
[r
].vt_inthis
;
1204 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1206 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1208 static Token
ancest_ptr (ancestor
*a
)
1210 return a
->status
== ASTATUS_VIRT
&& a
->vbase
== a
->rec
? POINTSAT
: '.';
1213 static typeID
has_member (recID r
, Token m
, Token path
[], Token
*glob_name
)
1217 for (M
= structs
[r
].firstmember
; M
; M
= M
->next
)
1221 if (glob_name
) *glob_name
= M
->gn
;
1228 for (a
= structs
[r
].anonunions
; a
; a
= a
->next
)
1229 if ((t
= has_member (a
->r
, m
, path
+ 2, glob_name
)) != -1) {
1238 typeID
lookup_variable_member (recID r
, Token m
, Token
*path
, bool const_path
, Token
*glob_name
)
1243 Token p
[64], nglob
= 0;
1244 bool vptrm
= m
== RESERVED__v_p_t_r_
;
1248 if ((t
= has_member (r
, m
, p
, glob_name
)) != -1) {
1250 if (path
) sintprintf (path
, ISTR (p
), -1);
1253 if ((a
= structs
[r
].ancestors
))
1254 for (i
= 0; a
[i
].rec
!= -1; i
++)
1255 if ((t
= has_member (a
[i
].rec
, m
, p
, &nglob
)) != -1) {
1256 if (rt
!= -1 || a
[i
].status
== ASTATUS_FSCKD
)
1257 if (base_of (t
) == B_PURE
) continue;
1259 expr_errort ("Ambiguous vptr for class",
1260 name_of_struct (r
));
1261 else expr_errort ("Ambigous member", m
);
1263 if (glob_name
) *glob_name
= nglob
;
1265 if (path
) sintprintf (path
,
1266 ISTR (const_path
&& a
[i
].cpath
? a
[i
].cpath
: a
[i
].path
),
1267 const_path
&& a
[i
].cpath
? '.' : ancest_ptr (&a
[i
]),
1274 static bool is_ctorable (typeID t
)
1276 return (isstructure (t
) && need_construction (base_of (t
)))
1277 || is_array_of_ctorable_objects (t
);
1280 void add_variable_member (recID r
, Token m
, typeID t
, Token gn
, bool constant
, bool ncto
)
1284 if (!structs
[r
].incomplete
)
1285 parse_error_ll ("structure closed");
1286 if (m
!= RESERVED__v_p_t_r_
&& (lt
= lookup_variable_member (r
, m
, 0, 0, 0)) != -1
1287 && base_of (lt
) != B_PURE
)
1288 parse_error_tok (m
, "member duplicate");
1289 if (!gn
&& !ncto
&& is_ctorable (t
)) {
1290 ctorable_t
*cc
= add_ctorable (r
);
1291 cc
->ot
= base_of (t
);
1292 cc
->array
= !isstructure (t
);
1295 if (!gn
&& !structs
[r
].constd
)
1296 if (constant
|| isstructure (t
) && structs
[base_of (t
)].constd
)
1297 structs
[r
].constd
= true;
1298 member
*M
= (member
*) malloc (sizeof *M
);
1303 if (structs
[r
].firstmember
) {
1304 structs
[r
].lastmember
->next
= M
;
1305 structs
[r
].lastmember
= M
;
1307 structs
[r
].firstmember
= structs
[r
].lastmember
= M
;
1310 // #|#|#|#|#|#|#|#|#|#|#|#|#|#|#
1312 // #|#|#|#|#|#|#|#|#|#|#|#|#|#|#
1314 static bool have_exact_function_member (recID
, Token
, typeID
[], flookup
*);
1316 bool has_void_ctor (recID r
)
1318 typeID args
[] = { pthis_of_struct (r
), INTERNAL_ARGEND
};
1321 bool re
= have_exact_function_member (r
, RESERVED_ctor
, args
, &F
);
1322 if (re
) SET_MAYTHROW (F
);
1326 bool has_copy_ctor (recID r
)
1328 typeID args
[] = { pthis_of_struct (r
), pthis_of_struct (r
), INTERNAL_ARGEND
};
1331 bool re
= have_exact_function_member (r
, RESERVED_ctor
, args
, &F
);
1332 if (re
) SET_MAYTHROW (F
);
1336 void set_dfunc (recID r
, Token dn
, bool nothrow
, bool autodtor
)
1338 structs
[r
].dtor_nothrow
= nothrow
;
1339 structs
[r
].dtor_name
= dn
;
1340 structs
[r
].has_dtor
= true;
1341 structs
[r
].autodtor
|= autodtor
;
1344 bool isunion (recID r
)
1346 return !structs
[r
].notunion
;
1349 bool has_dtor (recID r
)
1351 return structs
[r
].has_dtor
;
1354 bool always_unwind (recID r
)
1356 return structs
[r
].unwind
;
1359 Token
dtor_name (recID r
)
1361 if (!structs
[r
].dtor_nothrow
)
1363 return structs
[r
].dtor_name
;
1366 void set_dtor_nothrow (recID r
)
1368 structs
[r
].dtor_nothrow
= true;
1371 Token
idtor (recID r
)
1373 return structs
[r
].idtor
;
1376 Token
vdtor (recID r
)
1378 return structs
[r
].vdtor
;
1381 void set_declaration (recID r
, Token
*code
)
1383 structs
[r
].code
= code
;
1386 static bool has_named_func (recID r
, Token f
)
1388 if (have_function (structs
[r
].Funcs
, f
)) return true;
1390 if ((a
= structs
[r
].ancestors
))
1391 for (; a
->rec
!= -1; a
++)
1392 if (have_function (structs
[a
->rec
].Funcs
, f
))
1397 bool has_ctors (recID r
)
1399 return has_named_func (r
, RESERVED_ctor
);
1402 bool has_oper_fcall (recID r
)
1404 return has_named_func (r
, RESERVED_oper_fcall
);
1406 // #+#+#+#+#+#+#+#+#+#+#+#+#
1408 // #+#+#+#+#+#+#+#+#+#+#+#+#
1410 // lookup a function in parent classes and inherit the useful
1411 // flags: AUTO, VIRTUAL, MODULAR
1412 int inherited_flagz (recID r
, Token f
, typeID t
)
1414 ancestor
*a
= structs
[r
].ancestors
;
1420 typeID
*pargl
= promoted_arglist_t (t
);
1421 typeID
*cargv
= (typeID
*) allocaint (intlen (pargl
) + 3);
1422 intcpy (cargv
, pargl
);
1425 for (; a
->rec
!= -1; a
++) {
1426 cargv
[0] = structs
[a
->rec
].type_pthis
;
1427 if (p
= xlookup_function_dcl (structs
[a
->rec
].Funcs
, f
, cargv
))
1431 return flagz
& (FUNCP_AUTO
| FUNCP_VIRTUAL
| FUNCP_MODULAR
);
1434 // lookup function flagz in declarations in class
1435 // useful flags: CONST-THIS, MODULAR, AUTO
1436 int exported_flagz (recID r
, Token f
, typeID t
)
1438 typeID
*argv
= promoted_arglist_t (t
);
1440 int ret
= FUNCP_UNDEF
;
1442 if (p
= xlookup_function_dcl (structs
[r
].Funcs
, f
, argv
))
1443 ret
= p
->flagz
& (FUNCP_CTHIS
| FUNCP_MODULAR
| FUNCP_AUTO
);
1448 static int looking_for
;
1450 static int has_fmember (recID r
, Token f
, typeID argv
[], flookup
*F
)
1452 if (!structs
[r
].Funcs
) return 0;
1453 argv
[0] = structs
[r
].type_pthis
;
1454 return xlookup_function (structs
[r
].Funcs
, f
, argv
, F
) == looking_for
;
1457 static bool _lookup_function_member (recID r
, Token f
, typeID argv
[], flookup
*F
)
1464 if (lt
= has_fmember (r
, f
, argv
, F
))
1467 if ((a
= structs
[r
].ancestors
))
1468 for (i
= 0; a
[i
].rec
!= -1; i
++)
1469 if (lt
= has_fmember (a
[i
].rec
, f
, argv
, &tmp
)) {
1470 if (rt
== -1 || isancestor (a
[i
].rec
, rt
)) {
1471 if (a
[i
].status
== ASTATUS_FSCKD
)
1473 rt
= lt
== 1 ? a
[i
].rec
: -2;
1475 } else if (!isancestor (rt
, a
[i
].rec
)) really_fsckd
:
1476 expr_errort ("Ambigous member function", f
);
1481 argv
[0] = rt
>= 0 ? structs
[rt
].type_pthis
: -1;
1485 int lookup_function_member (recID r
, Token f
, typeID argv
[], flookup
*F
, bool definite
)
1488 if (_lookup_function_member (r
, f
, argv
, F
))
1491 // global function exact match > member function overload promotion
1492 if (!definite
&& xlookup_function (Global
, f
, &argv
[1], F
) == 3)
1496 if (_lookup_function_member (r
, f
, argv
, F
))
1500 return _lookup_function_member (r
, f
, argv
, F
);
1503 static Token
has_fmember_uname (recID r
, Token f
)
1505 if (!structs
[r
].Funcs
) return 0;
1506 return xlookup_function_uname (structs
[r
].Funcs
, f
);
1509 Token
lookup_function_member_uname (recID
*r
, Token f
)
1515 if (lt
= has_fmember_uname (*r
, f
))
1518 if (a
= structs
[*r
].ancestors
)
1519 for (i
= 0; a
[i
].rec
!= -1; i
++)
1520 if (rr
= has_fmember_uname (a
[i
].rec
, f
)) {
1521 if (rt
== -1 || isancestor (a
[i
].rec
, rt
)) {
1522 if (a
[i
].status
== ASTATUS_FSCKD
)
1526 } else if (!isancestor (rt
, a
[i
].rec
)) really_fsckd
:
1527 parse_error_tok (f
, "Ambigous member function");
1533 static bool have_exact_function_member (recID r
, Token f
, typeID argv
[], flookup
*F
)
1536 return _lookup_function_member (r
, f
, argv
, F
)
1537 || (looking_for
= 3, _lookup_function_member (r
, f
, argv
, F
));
1540 Token
declare_function_member (recID r
, Token f
, typeID t
, Token
*p
, Token
*a
, int fl
,
1541 Token
**d
, Token section
)
1543 if (!structs
[r
].notunion
)
1544 parse_error_ll ("unions may not be have member functions");
1545 funcp
*fp
= xdeclare_function (&structs
[r
].Funcs
, f
,
1546 name_member_function (r
, f
), t
, p
, a
, fl
, d
, section
);
1547 fp
->used
= !(fl
& FUNCP_AUTO
);
1550 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1552 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
1554 bool Can_instantiate (recID r
)
1556 switch (structs
[r
].caninst
) {
1558 expr_errort ("Can't instantiate incomplete class", name_of_struct (r
));
1560 expr_errort ("Can't instantiate class. Pure virtual functions still in there",
1561 name_of_struct (r
));
1563 expr_errort ("Can't instantiate class."
1564 " No unique final overrider for virtual function", name_of_struct (r
));
1571 recID
ancest_named (recID r
, Token t
)
1573 ancestor
*a
= structs
[r
].ancestors
;
1575 while (a
->path
[0] != t
|| a
->path
[1] != -1)
1580 bool isancestor (recID rder
, recID rbase
)
1582 ancestor
*a
= structs
[rder
].ancestors
;
1584 if (a
) while (a
->rec
!= -1)
1585 if (a
++->rec
== rbase
) return true;
1587 return rder
== rbase
;
1590 int is_ancestor (recID rder
, recID rbase
, Token
**path
, bool const_path
)
1592 ancestor
*a
= structs
[rder
].ancestors
;
1596 for (; a
->rec
!= -1; a
++)
1597 if (a
->rec
== rbase
) {
1598 if (path
) *path
= const_path
&& a
->cpath
? a
->cpath
: a
->path
;
1599 if (a
->status
== ASTATUS_FSCKD
)
1600 expr_errort ("Ambigouus relationship", name_of_struct (rbase
));
1601 return a
->status
== ASTATUS_VIRT
&& a
->vbase
== a
->rec
&& !const_path
? 2:1;
1606 /* HOWTO: anestor status flags.
1608 ASTATUS_NORM ASTATUS_VIRT ASTATUS_VIRT2
1609 ---------------------------------------------
1610 ! -> for members No Yes No
1611 ! collapse vtis No Yes Yes
1612 ! declare vbase No Yes No
1613 ! const path No Yes Yes
1614 ! vtable good Yes No No
1615 ! downcast rtti No Yes Yes
1617 ***************************************************************/
1619 /* this here returns true if downcast rtti is needed to go from rbase to rder */
1620 bool is_ancestor_runtime (recID rder
, recID rbase
, Token
**path
)
1622 if (is_ancestor (rder
, rbase
, path
, false) == 2 || intchr (*path
, POINTSAT
))
1624 ancestor
*a
= structs
[rder
].ancestors
;
1625 while (a
->rec
!= rbase
) a
++;
1626 return a
->status
== ASTATUS_VIRT2
;
1629 // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1633 // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1635 bool PARENT_AUTOFUNCS
;
1637 void add_auto_f (Token ifn
, Token fn
, recID r
, typeID t
, bool virtual, bool pure
, NormPtr dclPtr
,
1638 Token
*proto
, Token
*argv
)
1641 typeID
*va
= promoted_arglist_t (t
);
1643 for (a
= structs
[r
].autofuncs
; a
; a
= a
->next
)
1644 if (a
->name
== fn
&& (arglist_compare (va
, a
->arglist
)
1645 || (PARENT_AUTOFUNCS
&& dclPtr
== a
->dclPtr
)))
1649 a
= add_autofunc (r
);
1652 a
->virtual = virtual;
1653 a
->status
= pure
? AU_STATUS_PV
: AU_STATUS_DD
;
1654 a
->dname
= a
->fname
= ifn
;
1659 //* commented out. does not allow to redefine an auto function
1660 //* with pure typedefs in its arguments in a class that they
1661 //* have been specialized... We only miss report of a rare error
1662 //if (a->status == AU_STATUS_DD)
1663 // parse_error_tok (fn, "auto-function redefined");
1665 if (virtual && !a
->virtual)
1666 parse_error_tok (fn
, "auto-function was not declared virtual");
1669 // PEND means it's inherited and we expect redef
1670 // !PEND means that user has supplied new definition
1671 // and we undo what we did the first time where PEND was true
1672 if (a
->status
!= AU_STATUS_PEND
)
1673 a
->dname
= ifn
, a
->pname
= -1;
1674 a
->status
= pure
? AU_STATUS_PV
: AU_STATUS_DD
;
1677 a
->proto
= intdup (proto
);
1678 a
->argv
= intdup (argv
);
1682 int borrow_auto_decls (recID r
, NormPtr ret
[])
1687 for (i
= 0, a
= structs
[r
].autofuncs
; a
; a
= a
->next
)
1688 if (a
->status
== AU_STATUS_ND
) {
1689 a
->status
= AU_STATUS_PEND
;
1690 ret
[i
++] = a
->dclPtr
;
1696 void repl__CLASS_ (Token
**proto
, recID r
)
1698 if (is_aliasclass (r
))
1699 intsubst (*proto
, RESERVED__CLASS_
, name_of_struct (r
));
1704 if ((*proto
) [i
] == RESERVED__CLASS_
) {
1705 tmp
[j
++] = RESERVED_struct
;
1706 tmp
[j
++] = name_of_struct (r
);
1708 } else if ((tmp
[j
++] = (*proto
) [i
++]) == -1) break;
1710 *proto
= intdup (tmp
);
1714 /* commit all the auto functions to require definition/instantiation */
1715 static void commit_auto_functions (recID r
)
1719 for (a
= structs
[r
].autofuncs
; a
; a
= a
->next
)
1720 if (a
->status
!= AU_STATUS_NU
) {
1721 if (is_aliasclass (r
))
1722 remove_struct_from_this (a
->proto
, r
);
1723 if (intchr (a
->proto
, RESERVED__CLASS_
))
1724 repl__CLASS_ (&a
->proto
, r
);
1725 commit_auto_define (a
->dname
, r
, a
->fname
, a
->pname
, a
->virtual,
1726 a
->proto
, a
->argv
, a
->type
);
1727 } else warning_tok ("No unique final overrider for auto function of",
1728 name_of_struct (r
));
1731 /* inherit auto functions and change DD to ND (not declared) */
1732 static void inherit_auto_functions (recID r
)
1738 a
= structs
[r
].ancestors
;
1740 for (i
= 0; a
[i
].rec
!= -1; i
++)
1741 if (direct_ancest (&a
[i
])) {
1742 for (af
= structs
[a
[i
].rec
].autofuncs
; af
; af
= af
->next
) {
1743 for (hf
= structs
[r
].autofuncs
; hf
; hf
= hf
->next
)
1744 if (hf
->name
== af
->name
&& arglist_compare (hf
->arglist
, af
->arglist
))
1747 if (af
->status
== AU_STATUS_PV
) continue;
1748 if (hf
->status
== AU_STATUS_PV
) goto wins
;
1749 if (hf
->status
== AU_STATUS_ND
&& af
->status
== AU_STATUS_DD
1750 && hf
->dclPtr
== af
->dclPtr
) continue;
1751 hf
->status
= AU_STATUS_NU
;
1753 hf
= add_autofunc (r
);
1755 hf
->name
= af
->name
;
1756 hf
->dname
= af
->dname
;
1757 hf
->pname
= hf
->fname
= af
->fname
;
1758 hf
->virtual = af
->virtual;
1759 hf
->status
= af
->status
;
1760 hf
->arglist
= intdup (af
->arglist
);
1761 hf
->dclPtr
= af
->dclPtr
;
1762 hf
->proto
= af
->proto
;
1763 hf
->argv
= af
->argv
;
1764 hf
->type
= af
->type
;
1765 if (hf
->status
== AU_STATUS_DD
)
1766 hf
->status
= AU_STATUS_ND
;
1769 if (structs
[a
[i
].rec
].autodtor
)
1770 structs
[r
].autodtor
= 1;
1774 /* upcast from this to a direct parent using constant path if avail */
1775 Token
*upcast1_this (recID rder
, recID rbase
)
1777 static Token retp
[15];
1778 ancestor
*a
= structs
[rder
].ancestors
;
1780 if (aliasclass (rder
) == aliasclass (rbase
))
1781 sintprintf (retp
, RESERVED_this
, -1);
1783 while (a
->rec
!= rbase
) a
++;
1785 if (a
->status
== ASTATUS_NORM
)
1786 sintprintf (retp
, '&', RESERVED_this
, POINTSAT
, a
->path
[0], -1);
1788 sintprintf (retp
, '&', RESERVED_this
, POINTSAT
, ISTR (a
->cpath
), -1);
1789 else sintprintf (retp
, RESERVED_this
, POINTSAT
, a
->path
[0], -1);
1795 // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1797 // pure data members
1799 // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
1801 void add_pure_dm (recID r
, Token bt
, NormPtr dcl
)
1805 for (p
= structs
[r
].pm
; p
; p
= p
->next
)
1807 if (!intchr (p
->dcls
, dcl
))
1808 intcatc (p
->dcls
, dcl
);
1811 p
= (puredm
*) malloc (sizeof *p
);
1812 p
->next
= structs
[r
].pm
;
1815 sintprintf (p
->dcls
, dcl
, -1);
1818 void gen_pure_dm (recID r
, OUTSTREAM O
)
1821 ancestor
*a
= structs
[r
].ancestors
;
1825 if (a
) for (i
= 0; a
[i
].rec
!= -1; i
++)
1826 if (direct_ancest (&a
[i
]))
1827 for (p
= structs
[a
[i
].rec
].pm
; p
; p
= p
->next
) {
1828 if ((t
= lookup_local_typedef (r
, p
->bt
))
1829 && base_of (lookup_typedef (t
)) != B_PURE
)
1830 for (j
= 0; p
->dcls
[j
] != -1; j
++)
1831 struct_declaration (r
, O
, p
->dcls
[j
]);
1832 else for (j
= 0; p
->dcls
[j
] != -1; j
++)
1833 add_pure_dm (r
, p
->bt
, p
->dcls
[j
]);
1837 //************************************************************
1838 // renaming functions due to overload adds complexity
1839 //************************************************************
1841 void rename_hier (Token on
, Token nn
)
1846 for (i
= 0; i
< nstructs
; i
++)
1847 if (structs
[i
].incomplete
) {
1848 for (a
= structs
[i
].autofuncs
; a
; a
= a
->next
) {
1849 // one of the two is redundant
1850 if (a
->dname
== on
) a
->dname
= nn
;
1851 if (a
->fname
== on
) {
1853 if (intchr (a
->proto
, on
))
1854 intsubst1 (a
->proto
, on
, nn
);
1857 if (structs
[i
].keyfunc
== on
)
1858 structs
[i
].keyfunc
= nn
;