Notice that argument base refers to the BOUND_TEMPLATE_TEMPLATE_PARM node for our example, and access is access_public_node .
2242 tree
2243 finish_base_specifier (tree base, tree access, bool virtual_p) in semantics.c
2244 {
2245 tree result;
2246
2247 if (base == error_mark_node)
2248 {
2249 error ("invalid base-class specification");
2250 result = NULL_TREE;
2251 }
2252 else if (! is_aggr_type (base, 1))
2253 result = NULL_TREE;
2254 else
2255 {
2256 if (cp_type_quals (base) != 0)
2257 {
2258 error ("base class `%T' has cv qualifiers", base);
2259 base = TYPE_MAIN_VARIANT (base);
2260 }
2261 result = build_tree_list (access, base);
2262 TREE_VIA_VIRTUAL (result) = virtual_p;
2263 }
2264
2265 return result;
2266 }
After creating the node for the base, these bases are chained tegother to stand for the base-clause in the front-end.
5.12.4.2.3.2.1. Fill up binfo
Back from cp_parser_base_clause , in cp_parser_class_head at line 12339, now bases refers to the node of BOUND_TEMPLATE_TEMPLATE_PARM just created, and type is the RECORD_TYPE for “SmallObject”. Remember when creating this RECORD_TYPE, an empty binfo node is created too. Now this node should be filled up according to the base-clause parsed.
9615 void
9616 xref_basetypes (tree ref, tree base_list) in decl.c
9617 {
9618 /* In the declaration `A : X, Y, ... Z' we mark all the types
9619 (A, X, Y, ..., Z) so we can check for duplicates. */
9620 tree *basep;
9621
9622 int i;
9623 enum tag_types tag_code;
9624
9625 if (ref == error_mark_node)
9626 return ;
9627
9628 if (TREE_CODE (ref) == UNION_TYPE)
9629 {
9630 error ("derived union `%T' invalid", ref);
9631 return ;
9632 }
9633
9634 tag_code = (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type);
9635
9636 /* First, make sure that any templates in base-classes are
9637 instantiated. This ensures that if we call ourselves recursively
9638 we do not get confused about which classes are marked and which
9639 are not. */
9640 basep = &base_list;
9641 while (*basep)
9642 {
9643 tree basetype = TREE_VALUE (*basep);
9644 if (!(processing_template_decl && uses_template_parms (basetype))
9645 && !complete_type_or_else (basetype, NULL))
9646 /* An incomplete type. Remove it from the list. */
9647 *basep = TREE_CHAIN (*basep);
9648 else
9649 basep = &TREE_CHAIN (*basep);
9650 }
9651
9652 SET_CLASSTYPE_MARKED (ref);
9653 i = list_length (base_list);
9654 if (i)
9655 {
9656 tree binfo = TYPE_BINFO (ref);
9657 tree binfos = make_tree_vec (i);
9658 tree accesses = make_tree_vec (i);
9659
9660 BINFO_BASETYPES (binfo) = binfos;
9661 BINFO_BASEACCESSES (binfo) = accesses;
9662
9663 for (i = 0; base_list; base_list = TREE_CHAIN (base_list))
9664 {
9665 tree access = TREE_PURPOSE (base_list);
9666 int via_virtual = TREE_VIA_VIRTUAL (base_list);
9667 tree basetype = TREE_VALUE (base_list);
9668 tree base_binfo;
9669
9670 if (access == access_default_node)
9671 /* The base of a derived struct is public by default. */
9672 access = (tag_code == class_type
9673 ? access_private_node : access_public_node);
9674
9675 if (basetype && TREE_CODE (basetype) == TYPE_DECL)
9676 basetype = TREE_TYPE (basetype);
9677 if (!basetype
9678 || (TREE_CODE (basetype) != RECORD_TYPE
9679 && TREE_CODE (basetype) != TYPENAME_TYPE
9680 && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
9681 && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))
9682 {
9683 error ("base type `%T' fails to be a struct or class type",
9684 basetype);
9685 continue ;
9686 }
9687
9688 if (CLASSTYPE_MARKED (basetype))
9689 {
9690 if (basetype == ref)
9691 error ("recursive type `%T' undefined", basetype);
9692 else
9693 error ("duplicate base type `%T' invalid", basetype);
9694 continue ;
9695 }
9696
9697 if (TYPE_FOR_JAVA (basetype)
9698 && (current_lang_depth () == 0))
9699 TYPE_FOR_JAVA (ref) = 1;
9700
9701 if (CLASS_TYPE_P (basetype))
9702 {
9703 base_binfo = TYPE_BINFO (basetype);
9704 /* This flag will be in the binfo of the base type, we must
9705 clear it after copying the base binfos. */
9706 BINFO_DEPENDENT_BASE_P (base_binfo)
9707 = dependent_type_p (basetype);
9708 }
9709 else
9710 base_binfo = make_binfo (size_zero_node, basetype,
9711 NULL_TREE, NULL_TREE);
9712
9713 TREE_VEC_ELT (binfos, i) = base_binfo;
9714 TREE_VEC_ELT (accesses, i) = access;
9715 /* This flag will be in the binfo of the base type, we must
9716 clear it after copying the base binfos. */
9717 TREE_VIA_VIRTUAL (base_binfo) = via_virtual;
9718
9719 SET_CLASSTYPE_MARKED (basetype);
9720
9721 /* We are free to modify these bits because they are meaningless
9722 at top level, and BASETYPE is a top-level type. */
9723 if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype))
9724 {
9725 TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1;
9726 /* Converting to a virtual base class requires looking
9727 up the offset of the virtual base. */
9728 TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
9729 }
9730
9731 if (CLASS_TYPE_P (basetype))
9732 {
9733 TYPE_HAS_NEW_OPERATOR (ref)
9734 |= TYPE_HAS_NEW_OPERATOR (basetype);
9735 TYPE_HAS_ARRAY_NEW_OPERATOR (ref)
9736 |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);
9737 TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
9738 /* If the base-class uses multiple inheritance, so do we. */
9739 TYPE_USES_MULTIPLE_INHERITANCE (ref)
9740 |= TYPE_USES_MULTIPLE_INHERITANCE (basetype);
9741 /* Likewise, if converting to a base of the base may require
9742 code, then we may need to generate code to convert to a
9743 base as well. */
9744 TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref)
9745 |= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype);
9746 }
9747 i++;
9748 }
9749 if (i)
9750 TREE_VEC_LENGTH (accesses) = TREE_VEC_LENGTH (binfos) = i;
9751 else
9752 BINFO_BASEACCESSES (binfo) = BINFO_BASETYPES (binfo) = NULL_TREE;
9753
9754 if (i > 1)
9755 {
9756 TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
9757 /* If there is more than one non-empty they cannot be at the same
9758 address. */
9759 TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
9760 }
9761 }
9762
9763 /* Copy the base binfos, collect the virtual bases and set the
9764 inheritance order chain. */
9765 copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE);
9766 CLASSTYPE_VBASECLASSES (ref) = nreverse (CLASSTYPE_VBASECLASSES (ref));
9767
9768 if (TYPE_FOR_JAVA (ref))
9769 {
9770 if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
9771 error ("Java class '%T' cannot have multiple bases", ref);
9772 if (CLASSTYPE_VBASECLASSES (ref))
9773 error ("Java class '%T' cannot have virtual bases", ref);
9774 }
9775
9776 /* Unmark all the types. */
9777 while (i--)
9778 {
9779 tree basetype = BINFO_TYPE (BINFO_BASETYPE (TYPE_BINFO (ref), i));
9780
9781 CLEAR_CLASSTYPE_MARKED (basetype);
9782 if (CLASS_TYPE_P (basetype))
9783 {
9784 TREE_VIA_VIRTUAL (TYPE_BINFO (basetype)) = 0;
9785 BINFO_DEPENDENT_BASE_P (TYPE_BINFO (basetype)) = 0;
9786 }
9787 }
9788 CLEAR_CLASSTYPE_MARKED (ref);
9789 }
Notice that at line 9645, incomplete type can’t appear in base-clause. And at line 9765, the bases themselves may also inherit from other classes, so it needs deep copy to get all related binfos. See that for specified class, the binfos form a list with deep-first, left-to-right order.
577 tree
578 copy_base_binfos (tree binfo, tree t, tree prev) in tree.c
579 {
580 tree binfos = BINFO_BASETYPES (binfo);
581 int n, ix;
582
583 if (prev)
584 TREE_CHAIN (prev) = binfo;
585 prev = binfo;
586
587 if (binfos == NULL_TREE)
588 return prev;
589
590 n = TREE_VEC_LENGTH (binfos);
591
592 /* Now copy the structure beneath BINFO. */
593 for (ix = 0; ix != n; ix++)
594 {
595 tree base_binfo = TREE_VEC_ELT (binfos, ix);
596 tree new_binfo = NULL_TREE;
597
598 if (!CLASS_TYPE_P (BINFO_TYPE (base_binfo)))
599 {
600 my_friendly_assert (binfo == TYPE_BINFO (t), 20030204);
601
602 new_binfo = base_binfo;
603 TREE_CHAIN (prev) = new_binfo;
604 prev = new_binfo;
605 BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
606 BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
607 }
608 else if (TREE_VIA_VIRTUAL (base_binfo))
609 {
610 new_binfo = purpose_member (BINFO_TYPE (base_binfo),
611 CLASSTYPE_VBASECLASSES (t));
612 if (new_binfo)
613 new_binfo = TREE_VALUE (new_binfo);
614 }
615
616 if (!new_binfo)
617 {
618 new_binfo = make_binfo (BINFO_OFFSET (base_binfo),
619 base_binfo, NULL_TREE,
620 BINFO_VIRTUALS (base_binfo));
621 prev = copy_base_binfos (new_binfo, t, prev);
622 if (TREE_VIA_VIRTUAL (base_binfo))
623 {
624 CLASSTYPE_VBASECLASSES (t)
625 = tree_cons (BINFO_TYPE (new_binfo), new_binfo,
626 CLASSTYPE_VBASECLASSES (t));
627 TREE_VIA_VIRTUAL (new_binfo) = 1;
628 BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t);
629 }
630 else
631 BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
632 }
633 TREE_VEC_ELT (binfos, ix) = new_binfo;
634 }
635
636 return prev;
637 }
The execption is the virtual inheritage, for which only one instance of virtual inherited base should be present in the tree. So a reference instead of copy is created if the instance already exists (note that every class has its own inheritent tree). For example:
class A { … };
class B: virtual public A { … };
class C: virtual public A { … };
class D: public B, C { … };
In class D, only one binfo of A exists. And in class B and C there are also single binfo of A (class D, C, B have different inheritent tree, in inheritent tree of D there is copy binfo of C and B).
Note that CLASS_TYPE_P returns false for BOUND_TEMPLATE_TEMPLATE_PARM. This is the implicit created aggregate type, no needs real copy. As result, the binfo of “SmallObject” and “ThreadingModel” are filled as following.
(Click here for open )
Figure 114 : fill up binfo
Then following, the parser will take up the class-definition. It is the procedure mostly the same as we have seen in previous section. We just skip it.