Studying note of GCC-3.4.6 source (116)

5.12.4.1.1.2.1.1.2.            Lookup in specified class

If the specified scope is a class, then it should lookup class member except non-static data member. But here this contravention won’t be checked, which will be done by the caller (build_offset_ref ).

Searching in specific class is taken by lookup_member . In this function notice that argument want_type if is true means we should only return TYPE_DECLs, argument xbasetype refers to the type of the class, and argument protect is passed in with 0 which means do not check access and for an ambiguous lookup, we return NULL.

 

1275 tree

1276 lookup_member (tree xbasetype, tree name, int protect, bool want_type)        in search.c

1277 {

1278    tree rval, rval_binfo = NULL_TREE;

1279    tree type = NULL_TREE, basetype_path = NULL_TREE;

1280    struct lookup_field_info lfi;

1281

1282    /* rval_binfo is the binfo associated with the found member, note,

1283      this can be set with useful information, even when rval is not

1284      set, because it must deal with ALL members, not just non-function

1285      members. It is used for ambiguity checking and the hidden

1286      checks. Whereas rval is only set if a proper (not hidden)

1287      non-function member is found.  */

1288

1289    const char *errstr = 0;

1290

1291    my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030624);

1292

1293    if (TREE_CODE (xbasetype) == TREE_VEC)

1294    {

1295      type = BINFO_TYPE (xbasetype);

1296      basetype_path = xbasetype;

1297    }

1298    else

1299    {

1300      my_friendly_assert(IS_AGGR_TYPE_CODE(TREE_CODE(xbasetype)), 20030624);

1301      type = xbasetype;

1302      basetype_path = TYPE_BINFO (type);

1303      my_friendly_assert (!BINFO_INHERITANCE_CHAIN (basetype_path), 980827);

1304    }

1305

1306    if (type == current_class_type && TYPE_BEING_DEFINED (type)

1307        && IDENTIFIER_CLASS_VALUE (name))

1308    {

1309      tree field = IDENTIFIER_CLASS_VALUE (name);

1310      if (! is_overloaded_fn (field)

1311          && ! (want_type && TREE_CODE (field) != TYPE_DECL))

1312        /* We're in the scope of this class, and the value has already

1313          been looked up. Just return the cached value.  */

1314        return field;

1315    }

 

Refers to figure relation of binfos , clearly type above points to the RECORD_TYPE node associated with the binfo. For name , if IDENTIFIER_CLASS_VALUE at line 1307 is non-null, name is bound in the current class, and IDENTIFIER_CLASS_VALUE is the value binding.

If the enclosing class is being defined (must be current_class_type ), if the field returned by IDENTIFIER_CLASS_VALUE is function declaration, we need go forward as method/ function can be overloaded and maybe we just find out a previous declared ones. Besides, if TYPE_DECL is expected as returned value, but the field found is not of TYPE_DECL, we also need keep going (here consider following code:

struct F {

    int innerType;

};

 

struct G: public F {

    typedef int innerType;  // we are parsing this field, IDENTIFIER_CLASS_VALUE     

// (innerType) still points to F::innerType

};

Field “typedef int innerType” should be added in the class, so found “int innerType” must be abandoned; Again, for code:

struct F {

    typedef int innerType;

};

 

struct G: public F {

    void func(int innerType);       // we are parsing this field

};

We just need return innerType of F , compiler will find the error later.).

If we can’t take adavantage of quick searching by aid of IDENTIFIER_CLASS_VALUE (as long as type is not being defined, we can’t take the risk, as IDENTIFIER_CLASS_VALUE just keeps the last found link). We have to do the search in tough way.

 

1008 struct lookup_field_info {                                                                         in search.c

1009   /* The type in which we're looking.  */

1010   tree type;

1011   /* The name of the field for which we're looking.  */

1012   tree name;

1013   /* If non-NULL, the current result of the lookup.  */

1014   tree rval;

1015   /* The path to RVAL.  */

1016   tree rval_binfo;

1017   /* If non-NULL, the lookup was ambiguous, and this is a list of the

1018     candidates.  */

1019   tree ambiguous;

1020   /* If nonzero, we are looking for types, not data members.  */

1021   int want_type;

1022   /* If something went wrong, a message indicating what.  */

1023   const char *errstr;

1024 };

 

Above struct will be used to pass information to guide the searching process throughout the searched set. And it will take back the result too.

 

lookup_member (continue)

 

1317    complete_type (type);

1318

1319 #ifdef GATHER_STATISTICS

1320    n_calls_lookup_field ++;

1321 #endif /* GATHER_STATISTICS */

1322

1323    memset (&lfi, 0, sizeof (lfi));

1324    lfi.type = type;

1325    lfi.name = name;

1326    lfi.want_type = want_type;

1327    bfs_walk (basetype_path, &lookup_field_r , &lookup_field_queue_p , &lfi);

 

Routine bfs_walk walks the class hierarchy dominated by basetype_path . Then routine lookup_field_r is called for each type in the hierarchy, in a breadth-first preorder traversal. If it returns a non-null value, that value is immediately returned and the walk is terminated, which means we have found what we want, and the findout lies in the most derived base.

 

1607 static tree

1608 bfs_walk (tree binfo,                                                                                 in search.c

1609           tree (*fn) (tree, void *),

1610           tree (*qfn) (tree, int, void *),

1611           void *data)

1612 {

1613    tree rval = NULL_TREE;

1614

1615    tree bases_initial[BFS_WALK_INITIAL_QUEUE_SIZE];

1616    /* A circular queue of the base classes of BINFO. These will be

1617      built up in breadth-first order, except where QFN prunes the

1618      search.  */

1619    size_t head, tail;

1620    size_t base_buffer_size = BFS_WALK_INITIAL_QUEUE_SIZE;

1621    tree *base_buffer = bases_initial;

1622

1623    head = tail = 0;

1624    base_buffer[tail++] = binfo;

1625

1626    while (head != tail)

1627    {

1628      int n_bases, ix;

1629      tree binfo = base_buffer[head++];

1630      if (head == base_buffer_size)

1631        head = 0;

1632

1633      /* Is this the one we're looking for? If so, we're done.  */

1634      rval = fn (binfo, data);

1635      if (rval)

1636        goto done;

1637

1638      n_bases = BINFO_N_BASETYPES (binfo);

1639      for (ix = 0; ix != n_bases; ix++)

1640      {

1641        tree base_binfo;

1642     

1643        if (qfn)

1644          base_binfo = (*qfn) (binfo, ix, data);

1645        else

1646          base_binfo = BINFO_BASETYPE (binfo, ix);

1647     

1648        if (base_binfo)

1649        {

1650           base_buffer[tail++] = base_binfo;

1651          if (tail == base_buffer_size)

1652            tail = 0;

1653          if (tail == head)

1654          {

1655            tree *new_buffer = xmalloc (2 * base_buffer_size

1656                                    * sizeof (tree));

1657            memcpy (&new_buffer[0], &base_buffer[0],

1658                    tail * sizeof (tree));

1659            memcpy (&new_buffer[head + base_buffer_size],

1660                    &base_buffer[head],

1661                    (base_buffer_size - head) * sizeof (tree));

1662            if (base_buffer_size != BFS_WALK_INITIAL_QUEUE_SIZE)

1663              free (base_buffer);

1664            base_buffer = new_buffer;

1665            head += base_buffer_size;

1666            base_buffer_size *= 2;

1667          }

1668        }

1669      }

1670    }

1671

1672   done:

1673    if (base_buffer_size != BFS_WALK_INITIAL_QUEUE_SIZE)

1674      free (base_buffer);

1675    return rval;

1676 }

 

Above buffer bases_initial helps this traversal by expanding the tree into an array with nodes in preorder. It expects class hierarchy tree within a translation-unit normally is quite simple (BFS_WALK_INITIAL_QUEUE_SIZE is 10).

In each invocation, lookup_field_r is passed a binfo indicating the path from the currently visited base-class to basetype_path . While lookup_field_queue_p selects the qualified candidate for lookup_field_r .

 

1136 static tree

1137 lookup_field_r (tree binfo, void *data)                                                        in search.c

1138 {

1139    struct lookup_field_info *lfi = (struct lookup_field_info *) data;

1140    tree type = BINFO_TYPE (binfo);

1141    tree nval = NULL_TREE;

1142

1143    /* First, look for a function. There can't be a function and a data

1144      member with the same name, and if there's a function and a type

1145      with the same name, the type is hidden by the function.  */

1146    if (!lfi->want_type)

1147    {

1148      int idx = lookup_fnfields_1 (type, lfi->name);

1149      if (idx >= 0)

1150        nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);

1151    }

1152

1153    if (!nval)

1154      /* Look for a data member or type.  */

1155      nval = lookup_field_1 (type, lfi->name, lfi->want_type);

1156

1157    /* If there is no declaration with the indicated name in this type,

1158      then there's nothing to do.  */

1159    if (!nval)

1160      return NULL_TREE;

 

In the node of class, its methods are recorded within a vector; lookup_fnfields_1 returns the index within the vector for method specified by name . Below CLASSTYPE_METHOD_VEC is the vector.

 

1458 int

1459 lookup_fnfields_1 (tree type, tree name)                                                      in search.c

1460 {

1461    tree method_vec;

1462    tree *methods;

1463    tree tmp;

1464    int i;

1465    int len;

1466

1467    if (!CLASS_TYPE_P (type))

1468      return -1;

1469

1470    method_vec = CLASSTYPE_METHOD_VEC (type);

1471

1472    if (!method_vec)

1473      return -1;

1474

1475    methods = &TREE_VEC_ELT (method_vec, 0);

1476    len = TREE_VEC_LENGTH (method_vec);

1477

1478 #ifdef GATHER_STATISTICS

1479    n_calls_lookup_fnfields_1 ++;

1480 #endif /* GATHER_STATISTICS */

1481

1482    /* Constructors are first...  */

1483    if (name == ctor_identifier)

1484      return (methods[CLASSTYPE_CONSTRUCTOR_SLOT]

1485             ? CLASSTYPE_CONSTRUCTOR_SLOT : -1);

1486    /* and destructors are second.  */

1487    if (name == dtor_identifier)

1488      return (methods[CLASSTYPE_DESTRUCTOR_SLOT]

1489            ? CLASSTYPE_DESTRUCTOR_SLOT : -1);

1490    if (IDENTIFIER_TYPENAME_P (name))

1491      return lookup_conversion_operator (type, TREE_TYPE (name));

 

Constructor and destructor if defined, they are kept at fixed position as they are the most frequently invoked methods. Following constructors are conversoin operators if they present. The searching for conversion operator is a little trouble-some, as required by ISO-IEC-14882-2003, for conversion operators of the same name, non-template version is superiorer than template version.

 

1404 static int

1405 lookup_conversion_operator (tree class_type, tree type)                                in search.c

1406 {

1407    int pass;

1408    int i;

1409

1410    tree methods = CLASSTYPE_METHOD_VEC (class_type);

1411

1412    for (pass = 0; pass < 2; ++pass)

1413      for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;

1414          i < TREE_VEC_LENGTH (methods);

1415          ++i)

1416      {

1417        tree fn = TREE_VEC_ELT (methods, i);

1418        /* The size of the vector may have some unused slots at the

1419          end.  */

1420        if (!fn)

1421          break ;

1422

1423        /* All the conversion operators come near the beginning of the

1424          class. Therefore, if FN is not a conversion operator, there

1425          is no matching conversion operator in CLASS_TYPE.  * /

1426         fn = OVL_CURRENT (fn);

1427        if (!DECL_CONV_FN_P (fn))

1428          break ;

1429       

1430        if (pass == 0)

1431        {

1432          /* On the first pass we only consider exact matches. If

1433            the types match, this slot is the one where the right

1434            conversion operators can be found.  */

1435          if (TREE_CODE (fn) != TEMPLATE_DECL

1436            && same_type_p (DECL_CONV_FN_TYPE (fn), type))

1437            return i;

1438        }

1439        else

1440        {

1441          /* On the second pass we look for template conversion

1442            operators. It may be possible to instantiate the

1443            template to get the type desired. All of the template

1444            conversion operators share a slot. By looking for

1445             templates second we ensure that specializations are

1446            preferred over templates.  */

1447          if (TREE_CODE (fn) == TEMPLATE_DECL)

1448            return i;

1449        }

1450      }

1451

1452    return -1;

1453 }

 

For other methods, it needs do the hard searching across the vector. For parsed class, the methods are sorted by the addresses of the identifier of the name so can use binrary search; while for class under parsing, methods are not sorted yet, it has to find one after one.

 

lookup_fnfields_1 (continue)

 

1493    /* Skip the conversion operators.  */

1494    i = CLASSTYPE_FIRST_CONVERSION_SLOT;

1495    while (i < len && methods[i] && DECL_CONV_FN_P (OVL_CURRENT (methods[i])))

1496      i++;

1497

1498    /* If the type is complete, use binary search.  */

1499    if (COMPLETE_TYPE_P (type))

1500    {

1501      int lo = i;

1502      int hi = len;

1503

1504      while (lo < hi)

1505      {

1506        i = (lo + hi) / 2;

1507

1508 #ifdef GATHER_STATISTICS

1509        n_outer_fields_searched ++;

1510 #endif /* GATHER_STATISTICS */

1511

1512        tmp = methods[i];

1513        /* This slot may be empty; we allocate more slots than we

1514          need. In that case, the entry we're looking for is

1515           closer to the beginning of the list.  */

1516        if (tmp)

1517          tmp = DECL_NAME (OVL_CURRENT (tmp));

1518        if (!tmp || tmp > name)

1519          hi = i;

1520        else if (tmp < name)

1521          lo = i + 1;

1522        else

1523          return i;

1524      }

1525    }

1526    else

1527      for (; i < len && methods[i]; ++i)

1528      {

1529 #ifdef GATHER_STATISTICS

1530        n_outer_fields_searched ++;

1531 #endif /* GATHER_STATISTICS */

1532       

1533        tmp = OVL_CURRENT (methods[i]);

1534        if (DECL_NAME (tmp) == name)

1535          return i;

1536      }

1537

1538    return -1;

1539 }

 

Looking up conversion operator is finished with above code, however lookup_field _r can also be used to searching data member or type within class, we just have a look at this functionality here too.

Looking up data member or type is done by lookup_field_1 , and see that if not strictly require TYPE_DECL, method will hide type of the same name.

 

427  tree

428  lookup_field_1 (tree type, tree name, bool want_type)                                   in search.c

429  {

430    tree field;

431 

432    if (TREE_CODE (type) == TEMPLATE_TYPE_PARM

433        || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM

434        || TREE_CODE (type) == TYPENAME_TYPE)

435      /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM and

436        BOUND_TEMPLATE_TEMPLATE_PARM are not fields at all;

437        instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX. (Miraculously,

438        the code often worked even when we treated the index as a list

439        of fields!)

440        The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME. */

441      return NULL_TREE;

442 

443    if (TYPE_NAME (type)

444        && DECL_LANG_SPECIFIC (TYPE_NAME (type))

445        && DECL_SORTED_FIELDS (TYPE_NAME (type)))

446    {

447      tree *fields = &DECL_SORTED_FIELDS (TYPE_NAME (type))->elts[0];

448       int lo = 0, hi = DECL_SORTED_FIELDS (TYPE_NAME (type))->len;

449      int i;

450 

451      while (lo < hi)

452      {

453        i = (lo + hi) / 2;

454 

455    #ifdef GATHER_STATISTICS

456        n_fields_searched ++;

457    #endif /* GATHER_STATISTICS */

458 

459        if (DECL_NAME (fields[i]) > name)

460          hi = i;

461        else if (DECL_NAME (fields[i]) < name)

462          lo = i + 1;

463        else

464        {

465          field = NULL_TREE;

466 

467           /* We might have a nested class and a field with the

468            same name; we sorted them appropriately via

469            field_decl_cmp, so just look for the first or last

470            field with this name.  */

471          if (want_type)

472          {

473            do

474              field = fields[i--];

475            while (i >= lo && DECL_NAME (fields[i]) == name);

476            if (TREE_CODE (field) != TYPE_DECL

477               && !DECL_CLASS_TEMPLATE_P (field))

478              field = NULL_TREE;

479          }

480          else

481          {

482            do

483              field = fields[i++];

484            while (i < hi && DECL_NAME (fields[i]) == name);

485          }

486          return field;

487        }

488      }

489      return NULL_TREE;

490    }

491 

492    field = TYPE_FIELDS (type);

493 

494  #ifdef GATHER_STATISTICS

495    n_calls_lookup_field_1 ++;

496  #endif /* GATHER_STATISTICS */

497    for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))

498    {

499  #ifdef GATHER_STATISTICS

500      n_fields_searched ++;

501  #endif /* GATHER_STATISTICS */

502      my_friendly_assert (DECL_P (field), 0);

503      if (DECL_NAME (field) == NULL_TREE

504        && ANON_AGGR_TYPE_P (TREE_TYPE (field)))

505      {

506        tree temp = lookup_field_1 (TREE_TYPE (field), name, want_type);

507        if (temp)

508          return temp;

509      }

510      if (TREE_CODE (field) == USING_DECL)

511         /* For now, we're just treating member using declarations as

512          old ARM-style access declarations. Thus, there's no reason

513          to return a USING_DECL, and the rest of the compiler can't

514          handle it. Once the class is defined, these are purged

515          from TYPE_FIELDS anyhow; see handle_using_decl.  */

516        continue ;

517 

518      if (DECL_NAME (field) == name

519        && (!want_type

520            || TREE_CODE (field) == TYPE_DECL

521            || DECL_CLASS_TEMPLATE_P (field)))

522        return field;

523    }

524    /* Not found.  */

525    if (name == vptr_identifier )

526    {

527      /* Give the user what s/he thinks s/he wants.  */

528      if (TYPE_POLYMORPHIC_P (type))

529        return TYPE_VFIELD (type);

530    }

531    return NULL_TREE;

532  }

 

The function is similar with the rear part of lookup_fnfields_1 . And note that at line 444, DECL_LANG_SPECIFIC is present in *_DECL nodes in C++ front-end. For class, vtable is linked at head of TYPE_FIELDS, and it is referred by vptr_identifier. And remember only class defining virutal function or deriving from virtual base would have vtable and vptr_identifier.

If we are looking up a type, and what’s found out (nval ) is not TYPE_DECL and has the same name as the class in interesting; for which case, nval must not be method (lookup_fnfields_1 at line 1148 is skipped), but a field. Just as comment at line 1169 below tells, nval can be a field of the same name of the type. And recall that for class, it has TYPE_DECL generated and also linked in TYPE_FIELDS, so FOR loop at line 1173 finds for this TYPE_DECL.

 

lookup_field_r (continue)

 

1162    /* If we're looking up a type (as with an elaborated type specifier)

1163      we ignore all non-types we find.  */

1164    if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL

1165        && !DECL_CLASS_TEMPLATE_P (nval))

1166    {

1167      if (lfi->name == TYPE_IDENTIFIER (type))

1168      {

1169        /* If the aggregate has no user defined constructors, we allow

1170          it to have fields with the same name as the enclosing type.

1171          If we are looking for that name, find the corresponding

1172          TYPE_DECL.  */

1173        for (nval = TREE_CHAIN (nval); nval; nval = TREE_CHAIN (nval))

1174          if (DECL_NAME (nval) == lfi->name

1175                && TREE_CODE (nval) == TYPE_DECL)

1176            break ;

1177      }

1178      else

1179         nval = NULL_TREE;

1180      if (!nval && CLASSTYPE_NESTED_UTDS (type) != NULL)

1181      {

1182        binding_entry e = binding_table_find (CLASSTYPE_NESTED_UTDS (type),

1183                                       lfi->name);

1184        if (e != NULL)

1185          nval = TYPE_MAIN_DECL (e->type);

1186        else

1187          return NULL_TREE;

1188      }

1189    }

1190

1191    /* You must name a template base class with a template-id.  */

1192    if (!same_type_p (type, lfi->type)

1193        && template_self_reference_p (type, nval))

1194      return NULL_TREE;

 

Above, at line 1180, CLASSTYPE_NESTED_UTDS is a dictionary of the nested user-defined-types (class-types, or enums) found within the class. We enter IF block at line 1180, if nval not of TYPE_DECL and not of the same name as the class; for which case, nval may hides the type declared within the class. For example:

class A {

public :

    class a { public : int i; };

    int a;

};

 

int main () {

    class A::a a;     // class A::a is the elaborated-type-specifier

    return 0;

}

To make IF block finds out the type ‘a’ hidden by field ‘a’, it must use elaborated-type-specifier to explicitly select the type (see that it will force want_type into true in above).

[3], clause 3.3.7 “Name hiding” systematically describes the rule of name hiding as below.

1.  A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2).

2.  A class name (9.1) or enumeration name (7.2) can be hidden by the name of an object, function, or enumerator declared in the same scope. If a class or enumeration name and an object, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the object, function, or enumerator name is visible.

3.  In a member function definition, the declaration of a local name hides the declaration of a member of the class with the same name; see 3.3.6. The declaration of a member in a derived class (clause 10) hides the declaration of a member of a base class of the same name; see 10.2.

4.  During the lookup of a name qualified by a namespace name, declarations that would otherwise be made visible by a using-directive can be hidden by declarations with the same name in the namespace containing the using-directive ; see (3.4.3.2).

5.  If a name is in scope and is not hidden it is said to be visible .

 

lookup_field_r (continue)

 

1196    /* If the lookup already found a match, and the new value doesn't

1197      hide the old one, we might have an ambiguity.  */

1198    if (lfi->rval_binfo

1199         && !is_subobject_of_p (lfi->rval_binfo, binfo))

1200     

1201    {

1202      if (nval == lfi->rval && shared_member_p (nval))

1203         /* The two things are really the same.  */

1204         ;

1205      else if (is_subobject_of_p (binfo, lfi->rval_binfo))

1206          /* The previous value hides the new one.  */

1207         ;

1208      else

1209      {

1210          /* We have a real ambiguity. We keep a chain of all the

1211          candidates.  */

1212          if (!lfi->ambiguous && lfi->rval)

1213        {

1214          /* This is the first time we noticed an ambiguity. Add

1215             what we previously thought was a reasonable candidate

1216             to the list.  */

1217          lfi->ambiguous = tree_cons (NULL_TREE, lfi->rval, NULL_TREE);

1218          TREE_TYPE (lfi->ambiguous) = error_mark_node;

1219        }

1220

1221         /* Add the new value.  */

1222        lfi->ambiguous = tree_cons (NULL_TREE, nval, lfi->ambiguous);

1223         TREE_TYPE (lfi->ambiguous) = error_mark_node;

1224        lfi->errstr = "request for member `%D' is ambiguous";

1225      }

1226    }

1227    else

1228    {

1229      lfi->rval = nval;

1230      lfi->rval_binfo = binfo;

1231    }

1232

1233    return NULL_TREE;

1234 }

 

In lfi above, slot rval records the last result of the lookup, and rval_binfo is the corresponding binfo. As lfi lives for the whole traversal, these slots if not NULL, indicates the possibility of amibguity, unless rval_binfo and binfo (type under searched now) has derivation relationship. Another exception is the two entities found are the same one.

 

1114 static int

1115 is_subobject_of_p (tree parent, tree binfo)                                                   in search.c

1116 {

1117    tree probe;

1118   

1119    for (probe = parent; probe; probe = BINFO_INHERITANCE_CHAIN (probe))

1120    {

1121      if (probe == binfo)

1122       return 1;

1123      if (TREE_VIA_VIRTUAL (probe))

1124       return (purpose_member (BINFO_TYPE (probe),

1125                       CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))

1126             != NULL_TREE);

1127    }

1128    return 0;

1129 }

 

Routine is_subobject_of_p tells if two given types have derivation relation or not. It is straight-forward and simple.

After the traversal, rval and rval_binfo in lfi records the searching result if something found. Also if amibgity is found, it is recorded in ambiguous field.

 

lookup_member (continue)

 

1328    rval = lfi.rval;

1329    rval_binfo = lfi.rval_binfo;

1330    if (rval_binfo)

1331      type = BINFO_TYPE (rval_binfo);

1332    errstr = lfi.errstr;

1333

1334    /* If we are not interested in ambiguities, don't report them;

1335      just return NULL_TREE.  */

1336    if (!protect && lfi.ambiguous)

1337      return NULL_TREE;

1338   

1339    if (protect == 2)

1340    {

1341      if (lfi.ambiguous)

1342       return lfi.ambiguous;

1343      else

1344       protect = 0;

1345    }

1346

1347    /* [class.access]

1348

1349      In the case of overloaded function names, access control is

1350      applied to the function selected by overloaded resolution.  */

1351    if (rval && protect && !is_overloaded_fn (rval))

1352      perform_or_defer_access_check (basetype_path, rval);

1353

1354    if (errstr && protect)

1355     {

1356      error (errstr, name, type);

1357      if (lfi.ambiguous)

1358        print_candidates (lfi.ambiguous);

1359      rval = error_mark_node;

1360    }

1361

1362    if (rval && is_overloaded_fn (rval))

1363      rval = build_baselink (rval_binfo, basetype_path, rval,

1364                        (IDENTIFIER_TYPENAME_P (name)

1365                         ? TREE_TYPE (name): NULL_TREE));

1366    return rval;

1367 }

 

Note that is_overloaded_fn above returns true if rval can be overloaded. For those can be overloaded and accessed, it builds a BASELINK, which would be a reference to a member function or member functions from a base class. Note that the class can serves as base of itself

 

1240 tree

1241 build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)

1242 {

1243    tree baselink;

1244

1245    my_friendly_assert (TREE_CODE (functions) == FUNCTION_DECL

1246                     || TREE_CODE (functions) == TEMPLATE_DECL

1247                     || TREE_CODE (functions) == TEMPLATE_ID_EXPR

1248                     || TREE_CODE (functions) == OVERLOAD,

1249                     20020730);

1250    my_friendly_assert (!optype || TYPE_P (optype), 20020730);

1251    my_friendly_assert (TREE_TYPE (functions), 20020805);

1252

1253    baselink = make_node (BASELINK);

1254    TREE_TYPE (baselink) = TREE_TYPE (functions);

1255    BASELINK_BINFO (baselink) = binfo;

1256    BASELINK_ACCESS_BINFO (baselink) = access_binfo;

1257    BASELINK_FUNCTIONS (baselink) = functions;

1258    BASELINK_OPTYPE (baselink) = optype;

1259

1260    return baselink;

1261 }

 

BASELINK_FUNCTIONS gives the FUNCTION_DECL, TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the functions. BASELINK_BINFO gives the base from which the functions come, i.e., the base to which the `this' pointer must be converted before the functions are called (The BINFO indicating the base from which the BASELINK_FUNCTIONS came). BASELINK_ACCESS_BINFO gives the base used to name the functions (The BINFO in which the search for the functions indicated by this baselink began. This base is used to determine the accessibility of functions selected by overload resolution). BASELINK_BINFO and BASELINK_ACCESS_BINFO may be adjusted by adjust_result_of_qualified_name_lookup .

A BASELINK is an expression; the TREE_TYPE of the BASELINK gives the type of the expression. This type is either a FUNCTION_TYPE, METHOD_TYPE, or unknown_type_node indicating that the function is overloaded.

Before closing this section, let’s how to select qualified binfo in bfs_walk at line 1327 in lookup_member . It is the routine lookup_field_queue_p .

 

1041 static tree

1042 lookup_field_queue_p (tree derived, int ix, void *data)

1043 {

1044    tree binfo = BINFO_BASETYPE (derived, ix);

1045    struct lookup_field_info *lfi = (struct lookup_field_info *) data;

1046

1047    /* Don't look for constructors or destructors in base classes.  */

1048    if (IDENTIFIER_CTOR_OR_DTOR_P (lfi->name))

1049      return NULL_TREE;

1050

1051    /* If this base class is hidden by the best-known value so far, we

1052      don't need to look.  */

1053    if (lfi->rval_binfo && original_binfo (binfo, lfi->rval_binfo))

1054      return NULL_TREE;

1055

1056    /* If this is a dependent base, don't look in it.  */

1057    if (BINFO_DEPENDENT_BASE_P (binfo))

1058      return NULL_TREE;

1059   

1060    return binfo;

1061 }

 

Above at line 1053, binfo may the original binfo in the hierarchy tree dominated by lfi->rval_binfo or a copied binfo. If binfo is copied one original_binfo returns NULL, otherwise, it returns the original binfo in the hierarchy tree.

Then if original_binfo returns something, it means lfi->rval_binfo (remember this slot stores binfo in which the name has been found out) contains binfo as base which needesn’t be looked into.

5.12.4.1.1.2.1.2.    Lookup in specified object

While for expression like: “a->b” or “a.b”, scope of ‘a’ is recorded within “parser->context-> object_type”, which is referred by object_type below. According to [3]:

If the id-expression in a class member access is a qualified-id of the form:

class-name-or-namespace-name::...

the class-name-or-namespace-name following the . or -> operator is looked up both in the context of the entire postfix-expression and in the scope of the class of the object expression. If the name is found only in the scope of the class of the object expression, the name shall refer to a class-name. If the name is found only in the context of the entire postfix-expression, the name shall refer to a class-name or namespace-name. If the name is found in both contexts, the class-name-or-namespace-name shall refer to the same entity. [Note: the result of looking up the class-name-or-namespace-name is not required to be a unique base class of the class type of the object expression, as long as the entity or entities named by the qualified id are members of the class type of the object expression and are not ambiguous according to 10.2.

struct A {

int a;

};

struct B: virtual A { };

struct C: B { };

struct D: B { };

struct E: public C, public D { };

struct F: public A { };

void f() {

E e;

e.B::a = 0; // OK, only one A::a in E

F f;

f.A::a = 1; // OK, A::a is a member of F

}

But I still have idea about how class-name-or-namespace-name can be a namespace name L . For example:

namespace NA {

int i;

struct A { };

void func () {

   A a;

   a.NA::i = 5;

}

}

 

int main () {

    return 1;

}

According to the rule, NA in “a.NA::I” should be searched within context of func, and would be found out as namespace name, but next in finish_class_member_access_expr , this expression will be determined as an error.

 

cp_parser_lookup_name (continue)

 

13811    else if (object_type)

13812    {

13813      tree object_decl = NULL_TREE;

13814      /* Look up the name in the scope of the OBJECT_TYPE, unless the

13815         OBJECT_TYPE is not a class.  */

13816      if (CLASS_TYPE_P (object_type))

13817         /* If the OBJECT_TYPE is a template specialization, it may

13818           be instantiated during name lookup. In that case, errors

13819          may be issued. Even if we rollback the current tentative

13820          parse, those errors are valid.  */

13821           object_decl = lookup_member (object_type,

13822                                      name,

13823                                      /*protect=*/ 0, is_type);

13824       /* Look it up in the enclosing context, too.  */

13825      decl = lookup_name_real (name, is_type, /*nonclass=*/ 0,

13826                             is_namespace, flags);

13827      parser->object_scope = object_type;

13828      parser->qualifying_scope = NULL_TREE;

13829      if (object_decl)

13830         decl = object_decl;

13831    }

 

[3] doesn’t stipulate to use which when name is found in both contexts. GCC uses that found in scope of the class type of the object expression. Note, lookup_member and lookup_name_real can guarantee the result free from ambiguity.

Above at line 13827, object_scope and qualifying_scope of parser saves the scopes in which the last lookup took place. And object_scope is used if an expression like "x->y" or "x.y" was used; it gives the type of "*x" or "x", respectively; qualifying_scope is used for an expression of the form "X::Y"; it refers to X.

 

你可能感兴趣的:(object,tree,Class,buffer,statistics,methods)