X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree.c;h=f00f82e99956ef404bdd13bf82ff5b6de703087d;hb=c91dfc830a35947a012716256f568429021f26f1;hp=8c0ed4e0e15661891f69e924553b50462b95437f;hpb=19387b11ddf1e6d3a00e07958e4d135d58f53ad3;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree.c b/gcc/tree.c index 8c0ed4e0e15..f00f82e9995 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10779,4 +10779,60 @@ lhd_gcc_personality (void) return gcc_eh_personality_decl; } +/* Try to find a base info of BINFO that would have its field decl at offset + OFFSET within the BINFO type and which is of EXPECTED_TYPE. If it can be + found, return, otherwise return NULL_TREE. */ + +tree +get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type) +{ + tree type; + + if (offset == 0) + return binfo; + + type = TREE_TYPE (binfo); + while (offset > 0) + { + tree base_binfo, found_binfo; + HOST_WIDE_INT pos, size; + tree fld; + int i; + + if (TREE_CODE (type) != RECORD_TYPE) + return NULL_TREE; + + for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld)) + { + if (TREE_CODE (fld) != FIELD_DECL) + continue; + + pos = int_bit_position (fld); + size = tree_low_cst (DECL_SIZE (fld), 1); + if (pos <= offset && (pos + size) > offset) + break; + } + if (!fld) + return NULL_TREE; + + found_binfo = NULL_TREE; + for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + if (TREE_TYPE (base_binfo) == TREE_TYPE (fld)) + { + found_binfo = base_binfo; + break; + } + + if (!found_binfo) + return NULL_TREE; + + type = TREE_TYPE (fld); + binfo = found_binfo; + offset -= pos; + } + if (type != expected_type) + return NULL_TREE; + return binfo; +} + #include "gt-tree.h"