Studying note of GCC-3.4.6 source (146)

5.13.1.1.2.        Case of user defined conversion sequence

If standard conversion can’t work, conv at line 1107 in implicit_conversion would be NULL. It will see if there is any user-defined conversion applicable. It involves the procedure of resolving overload as [3], clause 13.3 “overload resolution” defines:

1.  Overload resolution is a mechanism for selecting the best function to call given a list of expressions that are to be the arguments of the call and a set of candidate functions that can be called based on the context of the call. The selection criteria for the best function are the number of arguments, how well the arguments match the types of the parameters of the candidate function, how well (for nonstatic member functions) the object matches the implied object parameter, and certain other properties of the candidate function. [Note: the function selected by overload resolution is not guaranteed to be appropriate for the context. Other restrictions, such as the accessibility of the function, can make its use in the calling context ill-formed. ]

2.  Overload resolution selects the function to call in seven distinct contexts within the language:

— invocation of a function named in the function call syntax (13.3.1.1.1);

— invocation of a function call operator, a pointer-to-function conversion function, a reference-to-pointerto-function conversion function, or a reference-to-function conversion function on a class object named in the function call syntax (13.3.1.1.2);

— invocation of the operator referenced in an expression (13.3.1.2);

— invocation of a constructor for direct-initialization (8.5) of a class object (13.3.1.3);

— invocation of a user-defined conversion for copy-initialization (8.5) of a class object (13.3.1.4);

— invocation of a conversion function for initialization of an object of a nonclass type from an expression of class type (13.3.1.5); and

— invocation of a conversion function for conversion to an lvalue to which a reference (8.5.3) will be directly bound (13.3.1.6).

3.  Each of these contexts defines the set of candidate functions and the list of arguments in its own unique way. But, once the candidate functions and argument lists have been identified, the selection of the best function is the same in all cases:

— First, a subset of the candidate functions—those that have the proper number of arguments and meet certain other conditions—is selected to form a set of viable functions (13.3.2).

— Then the best viable function is selected based on the implicit conversion sequences (13.3.3.1) needed to match each argument to the corresponding parameter of each viable function.

4.  If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. Otherwise overload resolution fails and the invocation is ill-formed. When overload resolution succeeds, and the best viable function is not accessible (clause 11) in the context in which it is used, the program is ill-formed.

Here we are within the context of “ invocation of a function call operator, a pointer-to-function conversion function, a reference-to-pointerto-function conversion function, or a reference-to-function conversion function on a class object named in the function call syntax (13.3.1.1.2); ”. Anyway, the resolving is the same for all the context.

5.13.1.1.2.1.  Collect candidates

C++ allows user to define conversion operators within class; further constructor having single argument without “explicit” at head can also be used as conversion from type of its argument to the class type.

[3], clause 13.3.3.1.2 “User-defined conversion sequences” gives the formal definition as below.

1.  A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user-defined conversion (12.3) followed by a second standard conversion sequence. If the user-defined conversion is specified by a constructor (12.3.1), the initial standard conversion sequence converts the source type to the type required by the argument of the constructor. If the user-defined conversion is specified by a conversion function (12.3.2), the initial standard conversion sequence converts the source type to the implicit object parameter of the conversion function.

2.  The second standard conversion sequence converts the result of the user-defined conversion to the target type for the sequence. Since an implicit conversion sequence is an initialization, the special rules for initialization by user-defined conversion apply when selecting the best user-defined conversion for a user-defined conversion sequence (see 13.3.3 and 13.3.3.1).

3.  If the user-defined conversion is specified by a template conversion function, the second standard conversion sequence must have exact match rank.

4.  A conversion of an expression of class type to the same class type is given Exact Match rank, and a conversion of an expression of class type to a base class of that type is given Conversion rank, in spite of the fact that a copy constructor (i.e., a user-defined conversion function) is called for those cases.

 

2355 static struct z_candidate *

2356 build_user_type_conversion_1 (tree totype, tree expr, int flags)                            in call.c

2357 {

2358    struct z_candidate *candidates, *cand;

2359    tree fromtype = TREE_TYPE (expr);

2360    tree ctors = NULL_TREE, convs = NULL_TREE;

2361    tree args = NULL_TREE;

2362    bool any_viable_p;

2363

2364    /* We represent conversion within a hierarchy using RVALUE_CONV and

2365      BASE_CONV, as specified by [over.best.ics]; these become plain

2366      constructor calls, as specified in [dcl.init].  */

2367    my_friendly_assert (!IS_AGGR_TYPE (fromtype) || !IS_AGGR_TYPE (totype)

2368                     || !DERIVED_FROM_P (totype, fromtype), 20011226);

2369

2370    if (IS_AGGR_TYPE (totype))

2371      ctors = lookup_fnfields (TYPE_BINFO (totype),

2372                          complete_ctor_identifier ,

2373                          0);

2374

2375    if (IS_AGGR_TYPE (fromtype))

2376      convs = lookup_conversions (fromtype);

 

So if the target type is class, it collects all constructors defined as constructor can be used as convertion function too. And if the source type is class, user-defined conversion operators are considered as candidates, which are collected by below function.

 

2421 tree

2422 lookup_conversions (tree type)                                                                   in search.c

2423 {

2424    tree t;

2425    tree conversions = NULL_TREE;

2426

2427    complete_type (type);

2428    bfs_walk (TYPE_BINFO (type), add_conversions , 0, &conversions);

2429

2430    for (t = conversions; t; t = TREE_CHAIN (t))

2431      IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (t)))) = 0;

2432

2433    return conversions;

2434 }

 

In lookup_conversions , fn in bfs_walk is add_conversions , which always returns NULL and forces the full traversal of the tree. See parameter data is used to hold all qualified candidates; and for conversion operators that converting to the same type, only the first found will be recorded.

 

2365 static tree

2366 add_conversions (tree binfo, void *data)                                                      in search.c

2367 {

2368    int i;

2369    tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));

2370    tree *conversions = (tree *) data;

2371

2372    /* Some builtin types have no method vector, not even an empty one.  */

2373    if (!method_vec)

2374      return NULL_TREE;

2375

2376    for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i)

2377    {

2378      tree tmp = TREE_VEC_ELT (method_vec, i);

2379      tree name;

2380

2381      if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))

2382        break ;

2383

2384      name = DECL_NAME (OVL_CURRENT (tmp));

2385

2386      /* Make sure we don't already have this conversion.  */

2387      if (! IDENTIFIER_MARKED (name))

2388      {

2389        tree t;

2390

2391        /* Make sure that we do not already have a conversion

2392           operator for this type. Merely checking the NAME is not

2393           enough because two conversion operators to the same type

2394            may not have the same NAME.  */

2395        for (t = *conversions; t; t = TREE_CHAIN (t))

2396        {

2397          tree fn;

2398          for (fn = TREE_VALUE (t); fn; fn = OVL_NEXT (fn))

2399            if (same_type_p (TREE_TYPE (name),

2400                           DECL_CONV_FN_TYPE (OVL_CURRENT (fn))))

2401              break ;

2402          if (fn)

2403            break ;

2404        }

2405        if (!t)

2406        {

2407          *conversions = tree_cons (binfo, tmp, *conversions);

2408          IDENTIFIER_MARKED (name) = 1;

2409        }

2410      }

2411    }

2412    return NULL_TREE;

2413 }

 

In section about member lookup, we see that method has been looked up would have BASELINK built. Remember for non-static method, the first argument should be the implicit ‘this’ pointer, and for constructor, ‘this’ pointer is not created yet which should only be ready after the constructor executing. So for constructor, it just builds a NULL ‘this’ pointer for this first implicit argument.

 

build_user_type_conversion_1 (continue)

 

2378    candidates = 0;

2379    flags |= LOOKUP_NO_CONVERSION;

2380

2381    if (ctors)

2382    {

2383      tree t;

2384

2385      ctors = BASELINK_FUNCTIONS (ctors);

2386

2387      t = build_int_2 (0, 0);

2388      TREE_TYPE (t) = build_pointer_type (totype);

2389      args = build_tree_list (NULL_TREE, expr);

2390      /* We should never try to call the abstract or base constructor

2391        from here.  */

2392      my_friendly_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))

2393                       && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)),

2394                       20011226);

2395      args = tree_cons (NULL_TREE, t, args);

2396    }

2397    for (; ctors; ctors = OVL_NEXT (ctors))

2398    {

2399      tree ctor = OVL_CURRENT (ctors);

2400      if (DECL_NONCONVERTING_P (ctor))

2401        continue ;

2402

2403      if (TREE_CODE (ctor) == TEMPLATE_DECL)

2404        cand = add_template_candidate (&candidates, ctor, totype,

2405                                   NULL_TREE, args, NULL_TREE,

2406                                   TYPE_BINFO (totype),

2407                                   TYPE_BINFO (totype),

2408                                   flags,

2409                                   DEDUCE_CALL);

2410      else

2411        cand = add_function_candidate (&candidates, ctor, totype,

2412                                  args, TYPE_BINFO (totype),

2413                                   TYPE_BINFO (totype),

2414                                  flags);

2415

2416      if (cand)

2417        cand->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE);

2418    }

5.13.1.1.2.1.1.          Add normal function

If the constructors can be used as convertion function (DECL_NONCONVERTING_P can tell out), they are included as candidates. And remember if it is a class template, then its constructors will be TEMPLATE_DECL too. Such node is added by add_template_candidate , which we have to skip now due to the complexity. Then for non-template method, add_function_candidate is called.

 

1164 static struct z_candidate *

1165 add_function_candidate (struct z_candidate **candidates,                                    in call.c

1166                       tree fn, tree ctype, tree arglist,

1167                       tree access_path, tree conversion_path,

1168                       int flags)

1169 {

1170    tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));

1171    int i, len;

1172    tree convs;

1173    tree parmnode, argnode;

1174    tree orig_arglist;

1175    int viable = 1;

1176

1177     /* Built-in functions that haven't been declared don't really

1178      exist.  */

1179    if (DECL_ANTICIPATED (fn))

1180      return NULL;

1181

1182    /* The `this', `in_chrg' and VTT arguments to constructors are not

1183      considered in overload resolution.  */

1184    if (DECL_CONSTRUCTOR_P (fn))

1185    {

1186      parmlist = skip_artificial_parms_for (fn, parmlist);

1187      orig_arglist = arglist;

1188      arglist = skip_artificial_parms_for (fn, arglist);

1189    }

1190    else

1191      orig_arglist = arglist;

1192

1193    len = list_length (arglist);

1194    convs = make_tree_vec (len);

1195

1196    /* 13.3.2 - Viable functions [over.match.viable]

1197      First, to be a viable function, a candidate function shall have enough

1198      parameters to agree in number with the arguments in the list.

1199

1200      We need to check this first; otherwise, checking the ICSes might cause

1201      us to produce an ill-formed template instantiation.  */

1202

1203    parmnode = parmlist;

1204    for (i = 0; i < len; ++i)

1205    {

1206      if (parmnode == NULL_TREE || parmnode == void_list_node)

1207        break ;

1208      parmnode = TREE_CHAIN (parmnode);

1209    }

1210

1211    if (i < len && parmnode)

1212      viable = 0;

1213

1214    /* Make sure there are default args for the rest of the parms.  */

1215    else if (!sufficient_parms_p (parmnode))

1216      viable = 0;

1217

1218    if (! viable)

1219      goto out;

1220

1221    /* Second, for F to be a viable function, there shall exist for each

1222      argument an implicit conversion sequence that converts that argument

1223      to the corresponding parameter of F.  */

1224

1225    parmnode = parmlist;

1226    argnode = arglist;

 

To be a candidate, it must be able to form a viable function invocation. As we have seen before, constructor may include more than 1 artificial argument, and the number depends on the definition of the class (whether it has VTT, virtual base).

 

1655 tree

1656 lvalue_type (tree arg)                                                                                        in tree.c

1657 {

1658    tree type = TREE_TYPE (arg);

1659    return type;

1660 }

 

From view-point of function, arguments are lvalue which can be manipulated within the function. Above lvalue_type returns the type of arg when used as an lvalue. It is possible that type of argument and type of corresponding parameter are not the same; however, they must be able to be matched by implicit conversion.

And if it encounters ellipsis parameter, ELSE block at line 1264 is executed; see that it needs still create IDENTITY_CONV for the argument, but with flag ICS_ELLIPSIS_FLAG set to indicate the IDENTITY_CONV is of ellipsis conversion.

 

add_function_candidate (continue)

 

1228    for (i = 0; i < len; ++i)

1229    {

1230      tree arg = TREE_VALUE (argnode);

1231      tree argtype = lvalue_type (arg);

1232      tree t;

1233      int is_this;

1234

1235      if (parmnode == void_list_node)

1236        break ;

1237

1238      is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)

1239              && ! DECL_CONSTRUCTOR_P (fn));

1240

1241      if (parmnode)

1242      {

1243        tree parmtype = TREE_VALUE (parmnode);

1244

1245        /* The type of the implicit object parameter ('this') for

1246          overload resolution is not always the same as for the

1247          function itself; conversion functions are considered to

1248           be members of the class being converted, and functions

1249          introduced by a using-declaration are considered to be

1250          members of the class that uses them.

1251

1252          Since build_over_call ignores the ICS for the `this'

1253           parameter, we can just change the parm type.  */

1254        if (ctype && is_this)

1255        {

1256          parmtype

1257              = build_qualified_type (ctype,

1258                                  TYPE_QUALS (TREE_TYPE (parmtype)));

1259          parmtype = build_pointer_type (parmtype);

1260        }

1261

1262        t = implicit_conversion (parmtype, argtype, arg, flags);

1263      }

1264      else

1265      {

1266        t = build1 (IDENTITY_CONV, argtype, arg);

1267        ICS_ELLIPSIS_FLAG (t) = 1;

1268      }

1269

1270      if (t && is_this)

1271        ICS_THIS_FLAG (t) = 1;

1272

1273      TREE_VEC_ELT (convs, i) = t;

1274      if (! t)

1275      {

1276        viable = 0;

1277        break ;

1278      }

1279

1280      if (ICS_BAD_FLAG (t))

1281        viable = -1;

1282

1283      if (parmnode)

1284        parmnode = TREE_CHAIN (parmnode);

1285      argnode = TREE_CHAIN (argnode);

1286    }

1287

1288   out:

1289    return add_candidate (candidates, fn, orig_arglist, convs, access_path,

1290                      conversion_path, viable);

1291 }

 

All candidates are chained tegother into list, which node of z_candidate is used to store relavant information.

 

312    struct z_candidate GTY(()) {                                                                           in call.c

313      /* The FUNCTION_DECL that will be called if this candidate is

314        selected by overload resolution.  */

315      tree fn;

316      /* The arguments to use when calling this function.  */

317      tree args;

318      /* The implicit conversion sequences for each of the arguments to

319        FN.  */

320      tree convs;

321      /* If FN is a user-defined conversion, the standard conversion

322        sequence from the type returned by FN to the desired destination

323        type.  */

324      tree second_conv;

325      int viable;

326      /* If FN is a member function, the binfo indicating the path used to

327        qualify the name of FN at the call site. This path is used to

328        determine whether or not FN is accessible if it is selected by

329        overload resolution. The DECL_CONTEXT of FN will always be a

330        (possibly improper) base of this binfo.  */

331      tree access_path;

332      /* If FN is a non-static member function, the binfo indicating the

333        subobject to which the `this' pointer should be converted if FN

334        is selected by overload resolution. The type pointed to the by

335        the `this' pointer must correspond to the most derived class

336        indicated by the CONVERSION_PATH.  */

337      tree conversion_path;

338      tree template;

339      tree warnings;

340      struct z_candidate *next;

341    };

 

Pay attention to conversion_path and access_path passed in, for constructor they are both the binfo of the target class.

 

1138 static struct z_candidate *

1139 add_candidate (struct z_candidate **candidates,                                                 in call.c

1140               tree fn, tree args, tree convs, tree access_path,

1141               tree conversion_path, int viable)

1142 {

1143    struct z_candidate *cand = ggc_alloc_cleared (sizeof (struct z_candidate));

1144

1145    cand->fn = fn;

1146    cand->args = args;

1147    cand->convs = convs;

1148    cand->access_path = access_path;

1149    cand->conversion_path = conversion_path;

1150    cand->viable = viable;

1151    cand->next = *candidates;

1152    *candidates = cand;

1153

1154    return cand;

1155 }

 

For conversion operator other than constructor, again see that conversion_path passed to add_function_candidate is binfo gotten at line 2426 which is set in add_conversions at line 2407, and is the binfo of the class that defining the method.

 

你可能感兴趣的:(function,tree,Class,Path,Constructor,initialization)