Studying note of GCC-3.4.6 source (150)

5.13.1.1.3.2.  Reference to known type

For already known from-type, reference_binding does with below code.

 

reference_binding (continue)

 

958      if (TREE_CODE (from) == REFERENCE_TYPE)

959      {

960        /* Anything with reference type is an lvalue.  */

961        lvalue_p = clk_ordinary;

962        from = TREE_TYPE (from);

963      }

964      else if (expr)

965        lvalue_p = real_lvalue_p (expr);

966   

967      /* Figure out whether or not the types are reference-related and

968        reference compatible. We have do do this after stripping

969        references from FROM.  */

970      related_p = reference_related_p (to, from);

971      compatible_p = reference_compatible_p (to, from);

 

Below two functions determine the reference related and reference compatible between to and from , which [3], clause 8.5.3 “References” gives the definitions and the purpose as below.

4.  Given types “cv1 T1” and “cv2 T2,” “cv1 T1” is reference-related to “cv2 T2” if T1 is the same type as T2, or T1 is a base class of T2. “cv1 T1” is reference-compatible with “cv2 T2” if T1 is reference-related to T2 and cv1 is the same cv-qualification as, or greater cv-qualification than, cv2 . For purposes of overload resolution, cases for which cv1 is greater cv-qualification than cv2 are identified as reference compatible with added qualification (see 13.3.3.2). In all cases where the reference-related or reference compatible relationship of two types is used to establish the validity of a reference binding, and T1 is a base class of T2, a program that necessitates such a binding is ill-formed if T1 is an inaccessible (clause 11) or ambiguous (10.2) base class of T2.

 

716    static bool

717    reference_related_p (tree t1, tree t2)                                                                 in call.c

718    {

719      t1 = TYPE_MAIN_VARIANT (t1);

720      t2 = TYPE_MAIN_VARIANT (t2);

721   

722      /* [dcl.init.ref]

723   

724        Given types "cv1 T1" and "cv2 T2," "cv1 T1" is reference-related

725        to "cv2 T2" if T1 is the same type as T2, or T1 is a base class

726        of T2.  */

727      return (same_type_p (t1, t2)

728            || (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)

729               && DERIVED_FROM_P (t1, t2)));

730    }

 

In short, if T1 is at least reference-related to T2 (see reference-compatible is a little stronger condition), the expression like: “T1& t1 = t2; // t2 of type T2” is legal.

 

734    static bool

735    reference_compatible_p (tree t1, tree t2)                                                           in call.c

736    {

737      /* [dcl.init.ref]

738   

739        "cv1 T1" is reference compatible with "cv2 T2" if T1 is

740         reference-related to T2 and cv1 is the same cv-qualification as,

741        or greater cv-qualification than, cv2.  */

742      return (reference_related_p (t1, t2)

743             && at_least_as_qualified_p (t1, t2));

744    }

 

Comments at line 975, 1005 and those other tagged by [dcl.init.ref] below, are abstracted from [3], section 8.5.3 “References”.

In both cases the reference is said to bind directly to the initializer expression. (Note the usual lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are not needed, and therefore are suppressed, when such direct bindings to lvalues are done.) And [3] also gives below examples to help the understanding:

double d = 2.0;

double& rd = d;      // rd refers to d

const double& rcd = d;   // rcd refers to d

struct A {};

struct B: public A {} b;

A& ra = b;       // ra refers to A sub-object in B

const A& rca = b;   // rca refers to A sub-object in B

[3] defines the order of the trying as below code does. It can see that temporary should be avoided as possible. And remember that node of REF_BIND is used to indicate the existence of reference in the conversion sequence no matter it is of temporary or not.

 

reference_binding (continue)

 

973      if (lvalue_p && compatible_p)

974      {

975        /* [dcl.init.ref]

976   

977          If the initializer expression

978        

979          -- is an lvalue (but not an lvalue for a bit-field), and "cv1 T1"

1000           is reference-compatible with "cv2 T2,"

1001       

1002         the reference is bound directly to the initializer expression

1003         lvalue.  */

1004       conv = build1 (IDENTITY_CONV, from, expr);

1005       conv = direct_reference_binding (rto, conv);

1006       if ((lvalue_p & clk_bitfield) != 0

1007          || ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to)))

1008         /* For the purposes of overload resolution, we ignore the fact

1009           this expression is a bitfield or packed field. (In particular,

1010            [over.ics.ref] says specifically that a function with a

1011           non-const reference parameter is viable even if the

1012           argument is a bitfield.)

1013  

1014           However, when we actually call the function we must create

1015           a temporary to which to bind the reference. If the

1016           reference is volatile, or isn't const, then we cannot make

1017           a temporary, so we just issue an error when the conversion

1018           actually occurs.  */

1019         NEED_TEMPORARY_P (conv) = 1;

1020                                   

1021       return conv;

1022     }

1023     else if (CLASS_TYPE_P (from) && !(flags & LOOKUP_NO_CONVERSION))

1024     {

1025       /* [dcl.init.ref]

1026  

1027         If the initializer expression

1028  

1029         -- has a class type (i.e., T2 is a class type) can be

1030           implicitly converted to an lvalue of type "cv3 T3," where

1031           "cv1 T1" is reference-compatible with "cv3 T3". (this

1032           conversion is selected by enumerating the applicable

1033           conversion functions (_over.match.ref_) and choosing the

1034           best one through overload resolution. (_over.match_).

1035  

1036         the reference is bound to the lvalue result of the conversion

1037         i n the second case.  */

1038       conv = convert_class_to_reference (to, from, expr);

1039       if (conv)

1040         return conv;

1041     }

 

See, direct_reference_binding is invoked only when we have known that the source type is reference compatible with target type. And argument conv passed should be an IDENTITY_CONV of the source type.

If source type isn’t a reference, or it is not the reference-compatible with the target type; then at line 1023, if source type is class type and user-defined conversion lookup is allowed, the front-end will look into the class definition to find the conversion operator that can return value of type reference-compatible with target type.

 

749    static tree

750    convert_class_to_reference (tree t, tree s, tree expr)                                                 in call.c

751    {

752      tree conversions;

753      tree arglist;

754      tree conv;

755      tree reference_type;

756      struct z_candidate *candidates;

757      struct z_candidate *cand;

758      bool any_viable_p;

759   

760      conversions = lookup_conversions (s);

761      if (!conversions)

762        return NULL_TREE;

763   

764      /* [over.match.ref]

765   

766         Assuming that "cv1 T" is the underlying type of the reference

767         being initialized, and "cv S" is the type of the initializer

768         expression, with S a class type, the candidate functions are

769         selected as follows:

770   

771         --The conversion functions of S and its base classes are

772           considered. Those that are not hidden within S and yield type

773           "reference to cv2 T2", where "cv1 T" is reference-compatible

774           (_dcl.init.ref_) with "cv2 T2", are candidate functions.

775   

776         The argument list has one argument, which is the initializer

777         expression.  */

778   

779      candidates = 0;

780   

781      /* Conceptually, we should take the address of EXPR and put it in

782        the argument list. Unfortunately, however, that can result in

783        error messages, which we should not issue now because we are just

784        trying to find a conversion operator. Therefore, we use NULL,

785        cast to the appropriate type.  */

786      arglist = build_int_2 (0, 0);

787      TREE_TYPE (arglist) = build_pointer_type (s);

788      arglist = build_tree_list (NULL_TREE, arglist);

789   

790      reference_type = build_reference_type (t);

791   

792      while (conversions)

793      {

794        tree fns = TREE_VALUE (conversions);

795   

796        for (; fns; fns = OVL_NEXT (fns))

797        {

798          tree f = OVL_CURRENT (fns);

799          tree t2 = TREE_TYPE (TREE_TYPE (f));

800          

801          cand = NULL;

802   

803          /* If this is a template function, try to get an exact

804            match.  */

805          if (TREE_CODE (f) == TEMPLATE_DECL)

806          {

807            cand = add_template_candidate (&candidates,

808                                       f, s,

809                                       NULL_TREE,

810                                        arglist,

811                                        reference_type,

812                                       TYPE_BINFO (s),

813                                       TREE_PURPOSE (conversions),

814                                       LOOKUP_NORMAL,

815                                       DEDUCE_CONV);

816              

817            if (cand)

818            {

819              /* Now, see if the conversion function really returns

820                an lvalue of the appropriate type. From the

821                point of view of unification, simply returning an

822                rvalue of the right type is good enough.  */

823              f = cand->fn;

824              t2 = TREE_TYPE (TREE_TYPE (f));

825              if (TREE_CODE (t2) != REFERENCE_TYPE

826                  || ! reference_compatible_p (t, TREE_TYPE (t2)))

827              {

828                candidates = candidates->next;

829                cand = NULL;

830              }

831            }

832          }

833          else if (TREE_CODE (t2) == REFERENCE_TYPE

834                 && reference_compatible_p (t, TREE_TYPE (t2)))

835            cand = add_function_candidate (&candidates, f, s, arglist,

836                                        TYPE_BINFO (s),      

837                                       TREE_PURPOSE (conversions),

838                                       LOOKUP_NORMAL);

839          

840          if (cand)

841          {

842            /* Build a standard conversion sequence indicating the

843              binding from the reference type returned by the

844              function to the desired REFERENCE_TYPE.  */

845            cand->second_conv

846                  = (direct_reference_binding

847                        (reference_type,

848                         build1 (IDENTITY_CONV,

849                               TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),

850                               NULL_TREE)));

851                          ICS_BAD_FLAG (cand->second_conv)

852                              |= ICS_BAD_FLAG (TREE_VEC_ELT (cand->convs, 0));

853          }

854        }

855        conversions = TREE_CHAIN (conversions);

856      }

857   

858      candidates = splice_viable (candidates, pedantic , &any_viable_p);

859      /* If none of the conversion functions worked out, let our caller

860        know.  */

861      if (!any_viable_p)

862        return NULL_TREE;

863   

864      cand = tourney (candidates);

865      if (!cand)

866        return NULL_TREE;

867   

868      /* Now that we know that this is the function we're going to use fix

869        the dummy first argument.  */

870      cand->args = tree_cons (NULL_TREE,

871                          build_this (expr),

872                          TREE_CHAIN (cand->args));

873   

874      /* Build a user-defined conversion sequence representing the

875        conversion.  */

876      conv = build_conv (USER_CONV,

877                      TREE_TYPE (TREE_TYPE (cand->fn)),

878                      build1 (IDENTITY_CONV, TREE_TYPE (expr), expr));

879      TREE_OPERAND (conv, 1) = build_zc_wrapper (cand);

880   

881      /* Merge it with the standard conversion sequence from the

882        conversion function's return type to the desired type.  */

883      cand->second_conv = merge_conversion_sequences (conv, cand->second_conv);

884   

885      if (cand->viable == -1)

886        ICS_BAD_FLAG (conv) = 1;

887     

888      return cand->second_conv;

889    }

 

The whole process of finding out the qualified conversion for reference binding is almost the same as that of the conversion for non-reference, except the construction of the second_conv at line 883. Remember code above handles cases so-call “direct bindings”, which needsn’t temperaries. Otherwise, it needs following code to cover the left cases.

 

reference_binding (continue)

 

1023    /* From this point on, we conceptually need temporaries, even if we

1024      elide them. Only the cases above are "direct bindings".  */

1025    if (flags & LOOKUP_NO_TEMP_BIND)

1026      return NULL_TREE;

1027

1028    /* [over.ics.rank]

1029      

1030      When a parameter of reference type is not bound directly to an

1031      argument expression, the conversion sequence is the one required

1032      to convert the argument expression to the underlying type of the

1033      reference according to _over.best.ics_. Conceptually, this

1034      conversion sequence corresponds to copy-initializing a temporary

1035      of the underlying type with the argument expression. Any

1036      difference in top-level cv-qualification is subsumed by the

1037      initialization itself and does not constitute a conversion.  */

1038

1039    /* [dcl.init.ref]

1040

1041      Otherwise, the reference shall be to a non-volatile const type.  */

1042    if (!CP_TYPE_CONST_NON_VOLATILE_P (to))

1043      return NULL_TREE;

1044

1045    /* [dcl.init.ref]

1046      

1047      If the initializer expression is an rvalue, with T2 a class type,

1048      and "cv1 T1" is reference-compatible with "cv2 T2", the reference

1049      is bound in one of the following ways:

1050      

1051      -- The reference is bound to the object represented by the rvalue

1052        or to a sub-object within that object. 

1053

1054      -- ...

1055   

1056      We use the first alternative. The implicit conversion sequence

1057      is supposed to be same as we would obtain by generating a

1058      temporary. Fortunately, if the types are reference compatible,

1059      then this is either an identity conversion or the derived-to-base

1060      conversion, just as for direct binding.  */

1061    if (CLASS_TYPE_P (from) && compatible_p)

1062    {

1063      conv = build1 (IDENTITY_CONV, from, expr);

1064      conv = direct_reference_binding (rto, conv);

1065      if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE))

1066        CHECK_COPY_CONSTRUCTOR_P (TREE_OPERAND (conv, 0)) = 1;

1067      return conv;

1068    }

1069

1070    /* [dcl.init.ref]

1071

1072      Otherwise, a temporary of type "cv1 T1" is created and

1073      initialized from the initializer expression using the rules for a

1074      non-reference copy initialization. If T1 is reference-related to

1075      T2, cv1 must be the same cv-qualification as, or greater

1076      cv-qualification than, cv2; otherwise, the program is ill-formed.  */

1077    if (related_p && !at_least_as_qualified_p (to, from))

1078      return NULL_TREE;

1079

1080    conv = implicit_conversion (to, from, expr, flags);

1081    if (!conv)

1082      return NULL_TREE;

1083

1084    conv = build_conv (REF_BIND, rto, conv);

1085    /* This reference binding, unlike those above, requires the

1086      creation of a temporary.  */

1087    NEED_TEMPORARY_P (conv) = 1;

1088

1089    return conv;

1090 }

 

Above at line 1025, if set with LOOKUP_NO_TEMP_BIND, it means temporaries will not be bound to references. Next, reference that can be bound to tempoary must be const, which is ensured by condition at line 1042.

Below examples explains comment at line 1041, which is the precondition for cases that code following will handle.

double& rd2 = 2.0;   // error: not an lvalue and reference not const

int  i = 2;

double& rd3 = i;  // error: type mismatch and reference not const

Then the other way mentioned by comment at line 1045 is that:

A temporary of type “cv1T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object 93) within the temporary.

[3] says that the choice is implementation defined. Here the front-end just adopts both choices.

1) If source type is a class type, and it is reference compatible to target type, here the conditions, except with the initializer expression isn’t a lvalue (instead here the reference is const), are same as “direct bindings”, and is treated the same way.

2) Other cases, generating temporary for reference binding).

[3] describes that for both cases, the constructor that would be used to make the copy shall be callable whether or not the copy is actually done. For example:

struct A { };

struct B : public A { } b;

extern B f();

const A& rca = f();   // Either bound to the A sub-object of the B rvalue,

// or the entire B object is copied and the reference is bound to the A sub-object of the copy

And examples for comment at line 1072 are shown in below:

const double& rcd2 = 2;   // rcd2 refers to temporary with value 2.0

const volatile int cvi = 1;

const int& r = cvi;  // error: type qualifiers dropped

In first example, “2” is a constant rvalue, so temporary is required to be the representation of “2” and be able to be referred. See for the front-end, only the last case needs temprorary as line 1087 indicates. And conv returned by the function is the (implict) convert sequence expected.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值