5.12.5.2.2.2.1.3.10. Finish the RECORD_TYPE – build vtable
Remember in determine_primary_base , if we find a primary base we just remember its vtable (recall that it must contain vtable, else we wouldn’t have primary base), now we need our own. Note the assertions from line 5057 to 5064, they can help us to find out inconsistency as early as posssible.
finish_struct_1 (continue)
5051 /* Make sure that we get our own copy of the vfield FIELD_DECL. */
5052 vfield = TYPE_VFIELD (t);
5053 if (vfield && CLASSTYPE_HAS_PRIMARY_BASE_P (t))
5054 {
5055 tree primary = CLASSTYPE_PRIMARY_BINFO (t);
5056
5057 my_friendly_assert (same_type_p (DECL_FIELD_CONTEXT (vfield),
5058 BINFO_TYPE (primary)),
5059 20010726);
5060 /* The vtable better be at the start. */
5061 my_friendly_assert (integer_zerop (DECL_FIELD_OFFSET (vfield)),
5062 20010726);
5063 my_friendly_assert (integer_zerop (BINFO_OFFSET (primary)),
5064 20010726);
5065
5066 vfield = copy_decl (vfield);
5067 DECL_FIELD_CONTEXT (vfield) = t;
5068 TYPE_VFIELD (t) = vfield;
5069 }
5070 else
5071 my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726);
5072
5073 virtuals = modify_all_vtables (t, nreverse (virtuals));
5074
5075 /* If we created a new vtbl pointer for this class, add it to the
5076 list. */
5077 if (TYPE_VFIELD (t) && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
5078 CLASSTYPE_VFIELDS (t)
5079 = chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
Remember virtuals above records the virtual functions in t if there is any. But it is in reverse order, so first uses nreverse to restore it. Note that t is the current class type, and it is passed as data for dfs_walk . And virtuals gets its content via transving TYPE_METHOD chain and selects out virtuals (see create_vtable_ptr ), then what is in BINFO_VIRTUAL of the binfo of current type? In set_primary_base , at determining primary base, TYPE_BINFO_VIRTUALS of current type is set as TYPE_BINFO_VIRTUALS of the primary base (TYPE_BINFO_VIRTUALS (t) is defined as BINFO_VIRTUALS (TYPE_BINFO (t)) ). So what is TYPE_BINFO_VIRTUALS of B1 (the primary base)? In turn, originally it gets its content from TYPE_BINFO_VIRTUALS of A (see example 1 & 2 at beginning of the section).
Let’s go back to early time, at which class A being finished. No doubt, at first, A has empty TYPE_BINFO_VIRTUALS. Below dfs_modify_vtables does nothing for the type, and modify_all_vtables in turn returns A::f as virtuals . Next back finish_struct_1 in below, primary vtable is created for A at line 5086 via build_primary_vtable ; and its TYPE_BINFO_VIRTUALS contains A::f by line 5106.
So, when finishing B1, its TYPE_BINFO_VIRTUALS also contains that of A, i.e. A::f. Then in dfs_modify_vtables below, at line 2314, the secondary vtable is prepared for A. Note that dfs_modify_vtables visits binfo of bases in the hierarchy tree from bottom up (B1 is the root), so first under processing is A within B1. It is discovered in later that A::f would be replaced by B1::f with a thunk. Next is B1 itself, its A::f is also replaced by B1::f with thunk (these 2 replacements occur in different places, the former is in base A’s secondary vtable, the rear is in B1’s primary vtable). Then in modify_all_vtables below, as DECL_VINDEX of B1::f in vrituals is not error_mark_node (see check_for_override , if it is error_mark_node , it means the function is not an overrider), and now BINFO_VIRTUALS (B1) contains B1::f with thunk, and since value_member returns true only if fn has the same address with any entity in the chain, so B1::f in virutals is kept and appended to TYPE_BINFO_VIRTUALS at line 5106. So this list contains B1::f with thunk, followed by B1::f.
Now comes to handle C, we know in TYPE_BINFO_VIRTUALS of C, it contains B1::f with result adjustment thunk, followed by B1::f; also C holds the copied binfo of B1. Following we will see the procedure in detail now.
2344 static tree
2345 modify_all_vtables (tree t, tree virtuals) in class.c
2346 {
2347 tree binfo = TYPE_BINFO (t);
2348 tree *fnsp;
2349
2350 /* Update all of the vtables. */
2351 dfs_walk (binfo, dfs_modify_vtables , unmarkedp , t);
2352 dfs_walk (binfo, dfs_unmark, markedp, t);
2353
2354 /* Add virtual functions not already in our primary vtable. These
2355 will be both those introduced by this class, and those overridden
2356 from secondary bases. It does not include virtuals merely
2357 inherited from secondary bases. */
2358 for (fnsp = &virtuals; *fnsp; )
2359 {
2360 tree fn = TREE_VALUE (*fnsp);
2361
2362 if (!value_member (fn, BINFO_VIRTUALS (binfo))
2363 || DECL_VINDEX (fn) == error_mark_node)
2364 {
2365 /* We don't need to adjust the `this' pointer when
2366 calling this function. */
2367 BV_DELTA (*fnsp) = integer_zero_node;
2368 BV_VCALL_INDEX (*fnsp) = NULL_TREE;
2369
2370 /* This is a function not already in our vtable. Keep it. */
2371 fnsp = &TREE_CHAIN (*fnsp);
2372 }
2373 else
2374 /* We've already got an entry for this function. Skip it. */
2375 *fnsp = TREE_CHAIN (*fnsp);
2376 }
2377
2378 return virtuals;
2379 }
Routine dfs_modfiy_vtables is executed in post-order during traversing the inherient tree by dfs_walk . Note that the function returns NULL to force the full walk, and during the walk bases get handled are those virtual bases or non-primary bases, and not include current type itself if it contains no vtable (in CLASSTYPE_VFIELDS which may be set in determine_primary_base ). For example 1 and 2, class C, B2 and A would be processed here by order A, B2, and C. Also needs to point out that, when handling A, all changes are made in copied binfo of A in C; and when handling B2, the changes confined in copied binfo of B2 in C; both handling in fact are very similar with B1. Below we just see the processing for C, remember BINFO_VIRTUALS of C at line 2319 contains B::f with thunk (this-adjustment and result-adjustment for A to B1).
2298 static tree
2299 dfs_modify_vtables (tree binfo, void* data) in class.c
2300 {
2301 if (/* There's no need to modify the vtable for a non-virtual
2302 primary base; we're not going to use that vtable anyhow.
2303 We do still need to do this for virtual primary bases, as they
2304 could become non-primary in a construction vtable. */
2305 (!BINFO_PRIMARY_P (binfo) || TREE_VIA_VIRTUAL (binfo))
2306 /* Similarly, a base without a vtable needs no modification. */
2307 && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
2308 {
2309 tree t = (tree) data;
2310 tree virtuals;
2311 tree old_virtuals;
2312 unsigned ix;
2313
2314 make_new_vtable (t, binfo);
2315
2316 /* Now, go through each of the virtual functions in the virtual
2317 function table for BINFO. Find the final overrider, and
2318 update the BINFO_VIRTUALS list appropriately. */
2319 for (ix = 0, virtuals = BINFO_VIRTUALS (binfo),
2320 old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
2321 virtuals;
2322 ix++, virtuals = TREE_CHAIN (virtuals),
2323 old_virtuals = TREE_CHAIN (old_virtuals))
2324 update_vtable_entry_for_fn (t,
2325 binfo,
2326 BV_FN (old_virtuals),
2327 &virtuals, ix);
2328 }
2329
2330 BINFO_MARKED (binfo) = 1;
2331
2332 return NULL_TREE;
2333 }
Note that argument t is unchanged during this procedure, and always refers to the current class type being finished. And binfo is of base that visited currently. First, it creates vtable if it is needed. Here it will create vtable for A, B2, and C.
658 static int
659 make_new_vtable (tree t, tree binfo) in class.c
660 {
661 if (binfo == TYPE_BINFO (t))
662 /* In this case, it is *type*'s vtable we are modifying. We start
663 with the approximation that its vtable is that of the
664 immediate base class. */
665 /* ??? This actually passes TYPE_BINFO (t), not the primary base binfo,
666 since we've updated DECL_CONTEXT (TYPE_VFIELD (t)) by now. */
667 return build_primary_vtable (TYPE_BINFO (DECL_CONTEXT (TYPE_VFIELD (t))),
668 t);
669 else
670 /* This is our very own copy of `basetype' to play with. Later,
671 we will fill in all the virtual functions that override the
672 virtual functions in these base classes which are not defined
673 by the current type. */
674 return build_secondary_vtable (binfo);
675 }
For A and B2, as their binfo is different from TYPE_BINFO (C), build_secondary_vtable is invoked. And because virtuals of these binfos are borrowed from binfos of the types (see copy_base_binfos in xref_basetypes ). Now it is time to have own copy.
634 static int
635 build_secondary_vtable (tree binfo) in class.c
636 {
637 if (BINFO_NEW_VTABLE_MARKED (binfo))
638 /* We already created a vtable for this base. There's no need to
639 do it again. */
640 return 0;
641
642 /* Remember that we've created a vtable for this BINFO, so that we
643 don't try to do so again. */
644 SET_BINFO_NEW_VTABLE_MARKED (binfo);
645
646 /* Make fresh virtual list, so we can smash it later. */
647 BINFO_VIRTUALS (binfo) = copy_virtuals (binfo);
648
649 /* Secondary vtables are laid out as part of the same structure as
650 the primary vtable. */
651 BINFO_VTABLE (binfo) = NULL_TREE;
652 return 1;
653 }
BV_VCALL_INDEX if non-NULL, holds the vtable index at which to find the vcall offset when calling this virtual function (by adding the value to the this pointer). It must be cleaned to be reindexed.
562 static tree
563 copy_virtuals (tree binfo) in class.c
564 {
565 tree copies;
566 tree t;
567
568 copies = copy_list (BINFO_VIRTUALS (binfo));
569 for (t = copies; t; t = TREE_CHAIN (t))
570 BV_VCALL_INDEX (t) = NULL_TREE;
571
572 return copies;
573 }
But for class C, build_primary_vtable is invoked as argument binfo here is the binfo of class C. Remember C now still uses TYPE_BINFO_VTABLE and TYPE_BINFO_VIRTUALS from its primary base, the class now needs its own copy.
581 static int
582 build_primary_vtable (tree binfo, tree type) in class.c
583 {
584 tree decl;
585 tree virtuals;
586
587 decl = get_vtable_decl (type, /*complete=*/ 0);
588
589 if (binfo)
590 {
591 if (BINFO_NEW_VTABLE_MARKED (binfo))
592 /* We have already created a vtable for this base, so there's
593 no need to do it again. */
594 return 0;
595
596 virtuals = copy_virtuals (binfo);
597 TREE_TYPE (decl) = TREE_TYPE (get_vtbl_decl_for_binfo (binfo));
598 DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl));
599 DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
600 }
601 else
602 {
603 my_friendly_assert (TREE_TYPE (decl) == vtbl_type_node, 20000118);
604 virtuals = NULL_TREE;
605 }
606
607 #ifdef GATHER_STATISTICS
608 n_vtables += 1;
609 n_vtable_elems += list_length (virtuals);
610 #endif
611
612 /* Initialize the association list for this type, based
613 on our first approximation. */
614 TYPE_BINFO_VTABLE (type) = decl;
615 TYPE_BINFO_VIRTUALS (type) = virtuals;
616 SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type));
617 return 1;
618 }
If vtable has been created, CLASSTYPE_VTABLES field holds it; otherwise this field should be empty. Argument complete if nonzero means completing the definition of the vtable created in the function – by invoking cp_finish_decl which we are currently within to finish the variable of instantiation of class template “SmallObject”.
539 tree
540 get_vtable_decl (tree type, int complete) in class.c
541 {
542 tree decl;
543
544 if (CLASSTYPE_VTABLES (type))
545 return CLASSTYPE_VTABLES (type);
546
547 decl = build_vtable (type, get_vtable_name (type), vtbl_type_node );
548 CLASSTYPE_VTABLES (type) = decl;
549
550 if (complete)
551 {
552 DECL_EXTERNAL (decl) = 1;
553 cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
554 }
555
556 return decl;
557 }
Vtable should be shared by all instances of the type (base is the exception, see BINFO_VTABLE is created in build_secondary_vtable ), so it should be created as static data member. Above get_vtable_name gets the mangled name for the vtable (GCC output of example 1 and 2 gives some examples of the mangled name), and vtbl_type_node is the type of constant array of vtable_entry_type (built in cxx_init_decl_processing ).
506 static tree
507 build_vtable (tree class_type, tree name, tree vtable_type) in class.c
508 {
509 tree decl;
510
511 decl = build_lang_decl (VAR_DECL, name, vtable_type);
512 /* vtable names are already mangled; give them their DECL_ASSEMBLER_NAME
513 now to avoid confusion in mangle_decl. */
514 SET_DECL_ASSEMBLER_NAME (decl, name);
515 DECL_CONTEXT (decl) = class_type;
516 DECL_ARTIFICIAL (decl) = 1;
517 TREE_STATIC (decl) = 1;
518 TREE_READONLY (decl) = 1;
519 DECL_VIRTUAL_P (decl) = 1;
520 DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
521 DECL_VTABLE_OR_VTT_P (decl) = 1;
522
523 /* At one time the vtable info was grabbed 2 words at a time. This
524 fails on sparc unless you have 8-byte alignment. (tiemann) */
525 DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
526 DECL_ALIGN (decl));
527
528 import_export_vtable (decl, class_type, 0);
529
530 return decl;
531 }
At line 528, import_export_vtable sets TREE_PUBLIC and DECL_EXTERNAL for the VARL_DECL created. Note that at line 614 in build_primary_vtable , TYPE_BINFO_VIRTUALS accesses BINFO_VIRTUALS of binfo of the type passed as its argument.
At line 597 in build_primary_vtabl , get_vtbl_decl_for_binfo fetches the VAR_DECL of vtable of binfo .
6446 tree
6447 get_vtbl_decl_for_binfo (tree binfo) in class.c
6448 {
6449 tree decl;
6450
6451 decl = BINFO_VTABLE (binfo);
6452 if (decl && TREE_CODE (decl) == PLUS_EXPR)
6453 {
6454 my_friendly_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR,
6455 2000403);
6456 decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
6457 }
6458 if (decl)
6459 my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 20000403);
6460 return decl;
6461 }
Now back to dfs_modify_vtables , pay attention to virtuals and orig_virtuals ; virtuals comes from binfo in current class hierarhcy tree, while orig_virtuals comes from binfo in the type of the base. They are different now, as corresponding BINFO_VIRTUALS has been copied above.
Then for every virtual function that defined in the type, necessary thunks and adjustments they carry would be worked out and recorded in update_vtable_entry_for_fn .
2071 static void
2072 update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, in class.c
2073 unsigned ix)
2074 {
2075 tree b;
2076 tree overrider;
2077 tree delta;
2078 tree virtual_base;
2079 tree first_defn;
2080 tree overrider_fn, overrider_target;
2081 tree target_fn = DECL_THUNK_P (fn) ? THUNK_TARGET (fn) : fn;
2082 tree over_return, base_return;
2083 bool lost = false;
2084
2085 /* Find the nearest primary base (possibly binfo itself) which defines
2086 this function; this is the class the caller will convert to when
2087 calling FN through BINFO. */
2088 for (b = binfo; ; b = get_primary_binfo (b))
2089 {
2090 my_friendly_assert (b, 20021227);
2091 if (look_for_overrides_here (BINFO_TYPE (b), target_fn))
2092 break ;
2093
2094 /* The nearest definition is from a lost primary. */
2095 if (BINFO_LOST_PRIMARY_P (b))
2096 lost = true;
2097 }
2098 first_defn = b;
2099
2100 /* Find the final overrider. */
2101 overrider = find_final_overrider (TYPE_BINFO (t), b, target_fn);
2102 if (overrider == error_mark_node)
2103 {
2104 error ("no unique final overrider for `%D' in `%T'", target_fn, t);
2105 return ;
2106 }
2107 overrider_target = overrider_fn = TREE_PURPOSE (overrider);
As dfs_modify_vtables is used as postfn of dfs_walk_real , it handles the bases from bottom up in the hierarhcy tree with the non-derived base first. This order is important for virtual primary base (but not required by non-vitural primary base, as every derived class own its copy of base’s info).
So for class C, dfs_modify_vtables first processes binfo of A in C. In FOR loop at line 2088 above, for specified function (i.e, B1::f with thunk), it steps down the primary bases chain of the specified base, and selects out the nearest primary base that defines the function. For B1::f with thunk in our example, b found out is B1, and lost is false.
When invoking find_final_overrider , note that if the function being processed is a thunk, the real function should be retrieved and referred by fn below. Here fn holds B1::f for A in C.
1194 static tree
1195 find_final_overrider (tree derived, tree binfo, tree fn) in class.c
1196 {
1197 find_final_overrider_data ffod;
1198 count_depth_data cd;
1199
1200 /* Getting this right is a little tricky. This is valid:
1201
1202 struct S { virtual void f (); };
1203 struct T { virtual void f (); };
1204 struct U : public S, public T { };
1205
1206 even though calling `f' in `U' is ambiguous. But,
1207
1208 struct R { virtual void f(); };
1209 struct S : virtual public R { virtual void f (); };
1210 struct T : virtual public R { virtual void f (); };
1211 struct U : public S, public T { };
1212
1213 is not -- there's no way to decide whether to put `S::f' or
1214 `T::f' in the vtable for `R'.
1215
1216 The solution is to look at all paths to BINFO. If we find
1217 different overriders along any two, then there is a problem. */
1218 if (DECL_THUNK_P (fn))
1219 fn = THUNK_TARGET (fn);
1220
1221 /* Determine the depth of the hierarchy. */
1222 cd.depth = 0;
1223 cd.max_depth = 0;
1224 dfs_walk (derived, dfs_depth_post , dfs_depth_q , &cd);
1225
1226 ffod.fn = fn;
1227 ffod.declaring_base = binfo;
1228 ffod.most_derived_type = BINFO_TYPE (derived);
1229 ffod.candidates = NULL_TREE;
1230 ffod.vpath_list = (tree *) xcalloc (cd.max_depth, sizeof (tree));
1231 ffod.vpath = ffod.vpath_list;
1232
1233 dfs_walk_real (derived,
1234 dfs_find_final_overrider ,
1235 dfs_find_final_overrider_post ,
1236 dfs_find_final_overrider_q ,
1237 &ffod);
1238
1239 free (ffod.vpath_list);
1240
1241 /* If there was no winner, issue an error message. */
1242 if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
1243 return error_mark_node;
1244
1245 return ffod.candidates;
1246 }
Variable cd of type count_depth_data having following definition is used in the traversal of the hierachy tree.
1856 typedef struct count_depth_data { in class.c
1857 /* The depth of the current subobject, with "1" as the depth of the
1858 most derived object in the hierarchy. */
1859 size_t depth;
1860 /* The maximum depth found so far. */
1861 size_t max_depth;
1862 } count_depth_data ;
Routine dfs_depth_q used as argument of qfn in dfs_walk_real , is executed top down and counts the level of derivation of the class (argument derived of find_final_overrider is current class type here, i.e. C).
1886 static tree
1887 dfs_depth_q (tree derived, int i, void *data) in class.c
1888 {
1889 count_depth_data *cd = (count_depth_data *) data;
1890 cd->depth++;
1891 return BINFO_BASETYPE (derived, i);
1892 }
While dfs_depth_post used as argument of postfn in dfs_walk_real , is executed buttom up towards the most derived class. It finds the max level of derivation among the record made during visiting the tree down from the most derived class.
1886 static tree
1887 dfs_depth_post (tree binfo ATTRIBUTE_UNUSED, void *data) in class.c
1888 {
1889 count_depth_data *cd = (count_depth_data *) data;
1890 if (cd->depth > cd->max_depth)
1891 cd->max_depth = cd->depth;
1892 cd->depth--;
1893 return NULL_TREE;
1894 }
See at line 1230, this max_depth slot of cd is used as the dimension of vpath_list in ffod which is of type find_final_overrider_data below.
1893 typedef struct find_final_overrider_data_s { in class.c
1894 /* The function for which we are trying to find a final overrider. */
1895 tree fn;
1896 /* The base class in which the function was declared. */
1897 tree declaring_base;
1898 /* The most derived class in the hierarchy. */
1899 tree most_derived_type;
1900 /* The candidate overriders. */
1901 tree candidates;
1902 /* Each entry in this array is the next-most-derived class for a
1903 virtual base class along the current path. */
1904 tree *vpath_list;
1905 /* A pointer one past the top of the VPATH_LIST. */
1906 tree *vpath;
1907 } find_final_overrider_data ;
In inner traversal, dfs_find_final_overrider is used as prefn in dfs_walk_real , which will be executed in pre-order and drop out the walk if it return nonzero value. Notice that the argument binfo is the variable derived in find_final_overrider , and original declaring_base slot of ffod passed as data is the binfo of the base visited by dfs_modify_vtables in post-order now, and most_derived_type slot refers to the most derived type (current class type).
1955 static tree
1956 dfs_find_final_overrider (tree binfo, void* data) in class.c
1957 {
1958 find_final_overrider_data *ffod = (find_final_overrider_data *) data;
1959
1960 if (binfo == ffod->declaring_base)
1961 dfs_find_final_overrider_1 (binfo, ffod->vpath, ffod);
1962
1963 return NULL_TREE;
1964 }
Notice that dfs_find_final_overrider is executed in pre-order in the inner walk, while dfs_modify_vtables is executed in post-order in the outer walk, and binfo is of base being visited by the inner walk, and data records the snapshot of outer walk at point of running the inner walk. So dfs_find_final_overrider_1 is executed when inner pre-order walk finally arrives at the point it was triggered.
But before condition at line 1960 finally is met, dfs_find_final_overrider_q is executed for every base stepping into.
1966 static tree
1967 dfs_find_final_overrider_q (tree derived, int ix, void *data) in class.c
1968 {
1969 tree binfo = BINFO_BASETYPE (derived, ix);
1970 find_final_overrider_data *ffod = (find_final_overrider_data *) data;
1971
1972 if (TREE_VIA_VIRTUAL (binfo))
1973 *ffod->vpath++ = derived;
1974
1975 return binfo;
1976 }
As we expecting, the virutal base being probed is recorded as their appearing order within vpath of ffod . So when leaving the base, it should be removed by dfs_find_final_overrider_post .
1978 static tree
1979 dfs_find_final_overrider_post (tree binfo, void *data) in class.c
1980 {
1981 find_final_overrider_data *ffod = (find_final_overrider_data *) data;
1982
1983 if (TREE_VIA_VIRTUAL (binfo))
1984 ffod->vpath--;
1985
1986 return NULL_TREE;
1987 }
In dfs_find_final_overrider_1, argument binfo is the base we are visiting in this inner walk, and declaring_base of ffod is the binfo we are visiting in the outer walk, in which we are determining the right override of the virutal fucntion specified by fn slot of ffod . And binfo and declaring_base are the same now.
1905 static bool
1906 dfs_find_final_overrider_1 (tree binfo, in class.c
1907 tree *vpath,
1908 find_final_overrider_data *ffod)
1909 {
1910 tree method;
1911
1912 /* If BINFO is not the most derived type, try a more derived class.
1913 A definition there will overrider a definition here. */
1914 if (!same_type_p (BINFO_TYPE (binfo), ffod->most_derived_type))
1915 {
1916 tree derived;
1917
1918 if (TREE_VIA_VIRTUAL (binfo))
1919 derived = *--vpath;
1920 else
1921 derived = BINFO_INHERITANCE_CHAIN (binfo);
1922 if (dfs_find_final_overrider_1 (derived, vpath, ffod))
1923 return true;
1924 }
1925
1926 method = look_for_overrides_here (BINFO_TYPE (binfo), ffod->fn);
1927 if (method)
1928 {
1929 tree *candidate = &ffod->candidates;
1930
1931 /* Remove any candidates overridden by this new function. */
1932 while (*candidate)
1933 {
1934 /* If *CANDIDATE overrides METHOD, then METHOD
1935 cannot override anything else on the list. */
1936 if (base_derived_from (TREE_VALUE (*candidate), binfo))
1937 return true;
1938 /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
1939 if (base_derived_from (binfo, TREE_VALUE (*candidate)))
1940 *candidate = TREE_CHAIN (*candidate);
1941 else
1942 candidate = &TREE_CHAIN (*candidate);
1943 }
1944
1945 /* Add the new function. */
1946 ffod->candidates = tree_cons (method, binfo, ffod->candidates);
1947 return true;
1948 }
1949
1950 return false;
1951 }
Pay attention to the recursion at line 1922 above, the routine gives the most derived class the priority over bases. So it can search out the most derived base that last overrides the function with the help of base_derived_from to determine from which it derives.
1836 static bool
1837 base_derived_from (tree derived, tree base) in class.c
1838 {
1839 tree probe;
1840
1841 for (probe = base; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
1842 {
1843 if (probe == derived)
1844 return true;
1845 else if (TREE_VIA_VIRTUAL (probe))
1846 /* If we meet a virtual base, we can't follow the inheritance
1847 any more. See if the complete type of DERIVED contains
1848 such a virtual base. */
1849 return purpose_member (BINFO_TYPE (probe),
1850 CLASSTYPE_VBASECLASSES (BINFO_TYPE (derived)))
1851 != NULL_TREE;
1852 }
1853 return false;
1854 }
This specified virtual function of most derived base is assigned to overrider_target below. For our example of B::f with thunk of A, overrider_target gets C::f. Now for the example, we get, target_fn : B* B::f(), and overrider_target : C* C::f(). Remember this B::f in A has a result-adjutment thunk with virutal-offset: A in B1, fix-offset: 0 (A -> B1).
See if the thunk contains virtual-offset, it should get it from the hierarchy class tree rooted by over_return at line 2140. So we can get the correct virtual offset.
update_vtable_entry_for_fn (continue)
2109 /* Check for adjusting covariant return types. */
2110 over_return = TREE_TYPE (TREE_TYPE (overrider_target));
2111 base_return = TREE_TYPE (TREE_TYPE (target_fn));
2112
2113 if (POINTER_TYPE_P (over_return)
2114 && TREE_CODE (over_return) == TREE_CODE (base_return)
2115 && CLASS_TYPE_P (TREE_TYPE (over_return))
2116 && CLASS_TYPE_P (TREE_TYPE (base_return)))
2117 {
2118 /* If FN is a covariant thunk, we must figure out the adjustment
2119 to the final base FN was converting to. As OVERRIDER_TARGET might
2120 also be converting to the return type of FN, we have to
2121 combine the two conversions here. */
2122 tree fixed_offset, virtual_offset;
2123
2124 over_return = TREE_TYPE (over_return);
2125 base_return = TREE_TYPE (base_return);
2126
2127 if (DECL_THUNK_P (fn))
2128 {
2129 my_friendly_assert (DECL_RESULT_THUNK_P (fn), 20031211);
2130 fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn));
2131 virtual_offset = THUNK_VIRTUAL_OFFSET (fn);
2132 }
2133 else
2134 fixed_offset = virtual_offset = NULL_TREE;
2135
2136 if (virtual_offset)
2137 /* Find the equivalent binfo within the return type of the
2138 overriding function. We will want the vbase offset from
2139 there. */
2140 virtual_offset =
2141 TREE_VALUE (purpose_member
2142 (BINFO_TYPE (virtual_offset),
2143 CLASSTYPE_VBASECLASSES (over_return)));
2144 else if (!same_type_ignoring_top_level_qualifiers_p
2145 (over_return, base_return))
2146 {
2147 /* There was no existing virtual thunk (which takes
2148 precedence). So find the binfo of the base function's
2149 return type within the overriding function's return type.
2150 We cannot call lookup base here, because we're inside a
2151 dfs_walk, and will therefore clobber the BINFO_MARKED
2152 flags. Fortunately we know the covariancy is valid (it
2153 has already been checked), so we can just iterate along
2154 the binfos, which have been chained in inheritance graph
2155 order. Of course it is lame that we have to repeat the
2156 search here anyway -- we should really be caching pieces
2157 of the vtable and avoiding this repeated work. */
2158 tree thunk_binfo, base_binfo;
2159
2160 /* Find the base binfo within the overriding function's
2161 return type. We will always find a thunk_binfo, except
2162 when the covariancy is invalid (which we will have
2163 already diagnosed). */
2164 for (base_binfo = TYPE_BINFO (base_return),
2165 thunk_binfo = TYPE_BINFO (over_return);
2166 thunk_binfo;
2167 thunk_binfo = TREE_CHAIN (thunk_binfo))
2168 if (same_type_p (BINFO_TYPE (thunk_binfo),
2169 BINFO_TYPE (base_binfo)))
2170 break ;
2171
2172 /* See if virtual inheritance is involved. */
2173 for (virtual_offset = thunk_binfo;
2174 virtual_offset;
2175 virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
2176 if (TREE_VIA_VIRTUAL (virtual_offset))
2177 break ;
2178
2179 if (virtual_offset
2180 || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
2181 {
2182 tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
2183
2184 if (virtual_offset)
2185 {
2186 /* We convert via virtual base. Adjust the fixed
2187 offset to be from there. */
2188 offset = size_diffop
2189 (offset, convert
2190 (ssizetype, BINFO_OFFSET (virtual_offset)));
2191 }
2192 if (fixed_offset)
2193 /* There was an existing fixed offset, this must be
2194 from the base just converted to, and the base the
2195 FN was thunking to. */
2196 fixed_offset = size_binop (PLUS_EXPR, fixed_offset, offset);
2197 else
2198 fixed_offset = offset;
2199 }
2200 }
2201
2202 if (fixed_offset || virtual_offset)
2203 /* Replace the overriding function with a covariant thunk. We
2204 will emit the overriding function in its own slot as
2205 well. */
2206 overrider_fn = make_thunk (overrider_target, /*this_adjusting=*/ 0,
2207 fixed_offset, virtual_offset);
2208 }
2209 else
2210 my_friendly_assert (!DECL_THUNK_P (fn), 20021231);