GCC-3.4.6源代码学习笔记(127)
2010-11-05 10:00
465 查看
5.12.4.2.3.2.
为
base-clause
构建节点
注意参数
base
在我们的例子中指向的
BOUND_TEMPLATE_TEMPLATE_PARM
节点,
access
是
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
}
在为基类构建了节点后,在前端中这些基类被串接在一起来代表
base-clause
。
5.12.4.2.3.2.1.
填充
binfo
从
cp_parser_base_clause
返回,在
cp_parser_class_head
的
12339
行,由
bases
指向先前所构建的节点
BOUND_TEMPLATE_TEMPLATE_PARM
,而
type
则是代表“
SmallObject
”的
RECORD_TYPE
。记得在构建这个
RECORD_TYPE
时,还构建了一个空的
binfo
节点。现在这个节点将根据刚才解析的
base-clause
来填充。
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
}
注意在
9645
行,在
base-clause
不能出现未完成的类。而在
9765
行,基类本身有可能从其他类派生,因此需要深拷贝所有相关的
binfo
。看到对于指定的类,
binfo
节点,以深度优先、由左至右为序,形成了一个链表。
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
}
虚拟继承是例外,在这个情形下,被虚拟继承的基类只能有一个实例出现在派生树中。因此如果该实例已经存在,创建一个引用而不是拷贝(注意每个类都有自己的派生树)。例如:
class
A { … };
class
B: virtual
public
A { …
};
class
C: virtual
public
A { …
};
class
D: public
B, C { … };
在类
D
中,仅含有一个
A
的
binfo
。而在类
B
和
C
中,同样都有一个
A
的
binfo
(类
D
,
C
,
B
具有不同的派生树,在
D
的派生树中,有
C
和
B
的
binfo
的拷贝)。
注意到对于
BOUND_TEMPLATE_TEMPLATE_PARM.
节点,
CLASS_TYPE_P
返回
false
。这是隐含构建的聚合类型,不需要真正的拷贝。那么“
SmallObject
”和“
ThreadingModel
”的
binfo
填充如下。
(
点此打开
)
图
114
:填充
binfo
5.12.4.3.
那么接下来,解析器将处理
class-definition
部分。它与我们在前面章节所看到处理过程几乎一样。这里我们跳过它。
为
base-clause
构建节点
注意参数
base
在我们的例子中指向的
BOUND_TEMPLATE_TEMPLATE_PARM
节点,
access
是
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
}
在为基类构建了节点后,在前端中这些基类被串接在一起来代表
base-clause
。
5.12.4.2.3.2.1.
填充
binfo
从
cp_parser_base_clause
返回,在
cp_parser_class_head
的
12339
行,由
bases
指向先前所构建的节点
BOUND_TEMPLATE_TEMPLATE_PARM
,而
type
则是代表“
SmallObject
”的
RECORD_TYPE
。记得在构建这个
RECORD_TYPE
时,还构建了一个空的
binfo
节点。现在这个节点将根据刚才解析的
base-clause
来填充。
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
}
注意在
9645
行,在
base-clause
不能出现未完成的类。而在
9765
行,基类本身有可能从其他类派生,因此需要深拷贝所有相关的
binfo
。看到对于指定的类,
binfo
节点,以深度优先、由左至右为序,形成了一个链表。
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
}
虚拟继承是例外,在这个情形下,被虚拟继承的基类只能有一个实例出现在派生树中。因此如果该实例已经存在,创建一个引用而不是拷贝(注意每个类都有自己的派生树)。例如:
class
A { … };
class
B: virtual
public
A { …
};
class
C: virtual
public
A { …
};
class
D: public
B, C { … };
在类
D
中,仅含有一个
A
的
binfo
。而在类
B
和
C
中,同样都有一个
A
的
binfo
(类
D
,
C
,
B
具有不同的派生树,在
D
的派生树中,有
C
和
B
的
binfo
的拷贝)。
注意到对于
BOUND_TEMPLATE_TEMPLATE_PARM.
节点,
CLASS_TYPE_P
返回
false
。这是隐含构建的聚合类型,不需要真正的拷贝。那么“
SmallObject
”和“
ThreadingModel
”的
binfo
填充如下。
(
点此打开
)
图
114
:填充
binfo
5.12.4.3.
解析
class-definition
那么接下来,解析器将处理class-definition
部分。它与我们在前面章节所看到处理过程几乎一样。这里我们跳过它。
相关文章推荐
- GCC-3.4.6源代码学习笔记(111)
- GCC-3.4.6源代码学习笔记(28)
- GCC-3.4.6源代码学习笔记(167)
- GCC-3.4.6源代码学习笔记(12)
- GCC-3.4.6源代码学习笔记(116)
- GCC-3.4.6源代码学习笔记(34)
- GCC-3.4.6源代码学习笔记(68)
- GCC-3.4.6源代码学习笔记(174)
- GCC-3.4.6源代码学习笔记(20)
- GCC-3.4.6源代码学习笔记(151)
- GCC-3.4.6源代码学习笔记 (105)
- GCC-3.4.6源代码学习笔记(177)
- GCC-3.4.6源代码学习笔记(156)
- GCC-3.4.6源代码学习笔记(135)
- GCC-3.4.6源代码学习笔记(44)
- GCC-3.4.6源代码学习笔记(56)
- GCC-3.4.6源代码学习笔记(129)
- GCC-3.4.6源代码学习笔记(142-续1)
- GCC-3.4.6源代码学习笔记(69)
- GCC-3.4.6源代码学习笔记(99)