Studying note of GCC-3.4.6 source (127)
来源:互联网 发布:视频剪辑软件下载 编辑:程序博客网 时间:2024/06/07 02:24
5.12.4.2.3.2. Buildnodes for base-clause
Notice that argument base refers to the BOUND_TEMPLATE_TEMPLATE_PARMnode for our example, and access is access_public_node.
2242 tree
2243 finish_base_specifier (tree base, treeaccess, bool virtual_p) in semantics.c
2244 {
2245 tree result;
2246
2247 if (base == error_mark_node)
2248 {
2249 error ("invalid base-classspecification");
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 cvqualifiers", 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 returnresult;
2266 }
After creating the node for the base, these bases are chainedtegother 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_headat line 12339, now bases refers to the node of BOUND_TEMPLATE_TEMPLATE_PARMjust created, and type is the RECORD_TYPE for “SmallObject”. Remember whencreating this RECORD_TYPE, an empty binfo node is created too. Now this nodeshould 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 thedeclaration `A : X, Y, ... Z' we mark all the types
9619 (A, X, Y, ..., Z) so we cancheck for duplicates. */
9620 tree *basep;
9621
9622 int i;
9623 enumtag_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 surethat any templates in base-classes are
9637 instantiated. This ensuresthat if we call ourselves recursively
9638 we do not get confused aboutwhich 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 incompletetype. 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 bydefault. */
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 bea 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 flagwill be in the binfo of the base type, we must
9705 clear it after copyingthe 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 flagwill be in the binfo of the base type, we must
9716 clear it after copying thebase binfos. */
9717 TREE_VIA_VIRTUAL (base_binfo) = via_virtual;
9718
9719 SET_CLASSTYPE_MARKED (basetype);
9720
9721 /* We are free to modify these bits becausethey are meaningless
9722 at top level, and BASETYPEis 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 thevirtual 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 thebase-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 needto 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 ismore 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 basebinfos, 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 havemultiple bases", ref);
9772 if (CLASSTYPE_VBASECLASSES (ref))
9773 error ("Java class '%T' cannot havevirtual bases", ref);
9774 }
9775
9776 /* Unmark all thetypes. */
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 inbase-clause. And at line 9765, the bases themselves may also inherit from otherclasses, so it needs deep copy to get all related binfos. See that for specifiedclass, 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 returnprev;
589
590 n = TREE_VEC_LENGTH (binfos);
591
592 /* Now copy thestructure 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 execptionis the virtual inheritage, for which only one instance of virtual inheritedbase should be present in the tree. So a reference instead of copy is createdif the instance already exists (note that every class has its own inheritenttree). For example:
class A { … };
class B: virtual public A { …};
class C: virtual public A { …};
class D: public B, C { … };
In class D, only one binfoof 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 binfoof C and B).
Note thatCLASS_TYPE_P returns false for BOUND_TEMPLATE_TEMPLATE_PARM. This is theimplicit created aggregate type, no needs real copy. As result, the binfo of“SmallObject” and “ThreadingModel” are filled as following.
(Clickhere for open)
Figure 114:fill up binfo
5.12.4.3. Parse class-definition
Then following, the parser will take up the class-definition. It isthe procedure mostly the same as we have seen in previous section. We just skipit.
- Studying note of GCC-3.4.6 source (127)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (1)
- Studying note of GCC-3.4.6 source (2)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (5)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (8)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (10 cont1)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (10 cont4)
- Studying note of GCC-3.4.6 source (11)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (13)
- GCC-3.4.6源代码学习笔记(127)
- 笔试题目
- Java方法 signature
- linux c程序中获取shell脚本输出
- 脚本:时间轴的实现
- Studying note of GCC-3.4.6 source (127)
- 实战exe4j将jar文件生成exe文件
- hdu 1018 Big Number
- eclipse插件——spket安装妹篇(原创)
- 静—软件开发指导文章
- 计数器与定时器
- 26 个 JQuery 使用小技巧(jQuery tips, tricks & solutions)
- 支持QQ
- 图:航大之星礼仪大赛圆满结束.