GCC-3.4.6源代码学习笔记(148)

5.13.1.1.2.2.  确定最优

在收集了所有的候选者后,需要挑出可行的候选者(因为收集的时候,我们只考虑了类型,没有别的),并为涉及的转换函数评估等级,以选出最优的候选。下面的代码执行这个处理。

 

build_user_type_conversion_1 (continue)

 

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

2479    if (!any_viable_p)

2480      return 0;

2481

2482    cand = tourney (candidates);

5.13.1.1.2.2.1.          挑选可行的候选者

在下面的函数中,其参数 strict_p 被传递入 pedantic 的值,它如果非 0 ,就要求编译器对标准所禁止的一切给出警告。回忆如果隐式转换不能奏效, implicit_conversion 将返回 NULL ;而对于标准所禁止的转换,将设置 ICS_BAD_FLAG 标记。

 

2165 static struct z_candidate *

2166 splice_viable (struct z_candidate *cands,                                                            in call.c

2167              bool strict_p,

2168              bool *any_viable_p)

2169 {

2170    struct z_candidate *viable;

2171    struct z_candidate **last_viable;

2172    struct z_candidate **cand;

2173

2174    viable = NULL;

2175    last_viable = &viable;

2176    *any_viable_p = false;

2177

2178    cand = &cands;

2179    while (*cand)

2180    {

2181      struct z_candidate *c = *cand;

2182      if (strict_p ? c->viable == 1 : c->viable)

2183      {

2184        *last_viable = c;

2185        *cand = c->next;

2186        c ->next = NULL;

2187        last_viable = &c->next;

2188        *any_viable_p = true;

2189      }

2190      else

2191        cand = &c->next;

2192    }

2193

2194    return viable ? viable : cands;

2195 }

5.13.1.1.2.2.2.          选出最优

3 】的条文 13.3.3 .2 “隐式转换序列排名“给出了挑选最优候选者的规则 [over.ics.rank ]

implicit_conversion 通过,首先尝试标准转换及引用绑定,如果失败,才尝试用户定义转换,实现了规则 2 的第一部分。

1.  13.3 .3.2 基于更好的转换序列与更好的转换之间的关系,定义了隐式转换序列的一个偏序( partial ordering )。如果一个隐式转换序列 S1 被这些规则定义为比 S2 更好的转换序列,那么同时 S2 亦是比 S1 更差的转换序列。如果转换序列 S1 不比转换序列 S2 好,也不比它差,就说 S1 S2 是不可区分( indistinguishable )的转换序列。

2.  当比较隐式转换序列的基本形式(如 13.3.3 .1 所定义)时

一个标准转换序列( 13.3.3 .1.1 )是比一个用户定义转换序列或一个省略转换序列更好的转换序列,而

一个用户定义转换序列( 13.3.3 .1.2 )是比一个省略转换序列( 13.3.3.1.3 )更优的转换序列。

3.  两个具有相同形式的隐式转换序列是不可区分的转换序列,除非适用下面其中任一规则:

标准转换序列 S1 是比标准转换序列 S2 更好的转换序列,如果

— S1 S2 的一个正确的子序列(比较 13.3.3 .1.1 所定义的规范形式的转换序列,不包括任意左值转型( Lvalue Transformation );恒等转换序列被认为是任意非恒等转换序列的一个子序列);否则,

— S1 的等级比 S2 的等级高,或 S1 S2 具有相同的等级,并且根据下面段落的规则是不可区分的;否则,

— S1 S2 仅是它们的限定转换不同,并且分别产生相似的类型 T1 T2 4.4 ),而类型 T1 cv- 限定是类型 T2 cv- 限定的一个正确子集,并且 S1 不是不推荐的字符串数组到指针的转换( 4.2 )。

[ 例子:

int f(const int *);

int f(int *);

int i;

int j = f(&i); // Calls f(int *)

例子结束 ] ;否则,

— S1 S2 都是引用绑定( 8.5.3 ),并且除了最顶层的 cv- 限定词,这些引用的类型都相同,并且由 S2 的援引所初始化的引用的类型,比由 S1 的援引所初始化的引用的类型,具有更多的 cv- 限定。 [ 例如:

int f(const int &);

int f(int &);

int g(const int &);

int g(int);

int i;

int j = f(i); // Calls f(int &)

int k = g(i); // ambiguous

class X {

public :

void f() const ;

void f();

};

void g(const X& a, X b) {

a.f(); //Calls X::f() const

b.f(); //Calls X::f()

}

例子结束 ]

用户定义转换序列 U1 是比另一个用户定义转换序列更好的转换序列,如果它们包含了相同的用户定义转换函数或构造函数,并且如果 U1 的第二标准转换序列优于 U2 的第二标准转换序列。 [ 例如:

struct A {

operator short();

} a;

int f(int);

int f(float);

int i = f(a); // Calls f(int), because short → int is better than short → float.

例子结束 ]

4.  标准转换序列根据它们的等级排序:一个精确匹配( Exact Match )优于提升( Promotion ),提升优于转换。两个具有相同等级的转换序列是不可区分,除非适用以下任一规则:

一个不是指针转换,或成员指针转换,或布尔转换的转换要优于这些转换。

如果类 B 从类 A 直接或间接派生, B* A* 的转换优于 B* void* 的转换, A* void* 的转换优于 B* void* 的转换。

如果类 B 从类 A 直接或间接派生,而类 C B 直接或间接派生, C* B* 的转换优于 C* A* 的转换, [ 例如:

struct A {};

struct B : public A {};

struct C : public B {};

C *pc;

int f(A *);

int f(B *);

int i = f(pc); // Calls f(B *)

例子结束 ]

绑定一个具有类型 C 的表达式到一个具有类型“ B& ”的引用,要优于绑定一个具有类型 C 的表达式到一个具有类型“ A& ”的引用,

— A::* B::* 的转换优于 A::* C::* 的转换,

— C B 的转换优于 C A 的转换,

— B* A* 的转换优于 C* A* 的转换,

绑定一个具有类型 B 的表达式到一个具有类型“ A& ”的引用,要优于绑定一个具有类型 C 的表达式到一个具有类型“ A& ”的引用,

— B::* C::* 的转换优于 A::* C::* 的转换,并且

— B A 的转换优于 C A 的转换。

[ 注意:仅在比较一个自用户定义的初始化转换的第二标准转换序列的上下文中,被比较的转换序列将具有不同的源类型(参见 see 13.3.3 );在其他上下文中,源类型必须是相同,而目标类型不同 ]

 

5936 static struct z_candidate *

5937 tourney (struct z_candidate *candidates)                                                            in call.c

5938 {

5939    struct z_candidate *champ = candidates, *challenger;

5940    int fate;

5941    int champ_compared_to_predecessor = 0;

5942

5943    /* Walk through the list once, comparing each current champ to the next

5944      candidate, knocking out a candidate or two with each comparison.  */

5945

5946    for (challenger = champ->next; challenger; )

5947    {

5948      fate = joust (champ, challenger, 0);

5949      if (fate == 1)

5950        challenger = challenger->next;

5951      else

5952       {

5953        if (fate == 0)

5954        {

5955          champ = challenger->next;

5956          if (champ == 0)

5957            return 0;

5958          champ_compared_to_predecessor = 0;

5959        }

5960        else

5961        {

5962          champ = challenger;

5963          champ_compared_to_predecessor = 1;

5964        }

5965

5966        challenger = champ->next;

5967      }

5968    }

5969

5970    /* Make sure the champ is better than all the candidates it hasn't yet

5971      been compared to.  */

5972

5973    for (challenger = candidates;

5974        challenger != champ

5975           && !(champ_compared_to_predecessor && challenger->next == champ);

5976        challenger = challenger->next)

5977    {

5978      fate = joust (champ, challenger, 0);

5979      if (fate != 1)

5980        return 0;

5981    }

5982

5983    return champ;

5984 }

 

通过 joust 候选者被一个个比较来选出最佳者,该函数返回 1 如果 champ 是更优的, -1 如果 challenger 是更优的,或者 0 如果具有二义性。注意到 champ 总是指向列表中的前一个候选者,而 challenger 是紧跟 champ 之后的候选者。看到在 5946 行的 FOR 循环中 champ 总是指向两个中较佳者,如果能确定的话。

5973 行的 FOR 循环中,如果 champ_compared_to_predecessor 0 ,那么退出的条件变成:“ challenger != champ ”;否则就变成:“ challenger != champ && challenger->next != champ ”。注意到仅当 challenger 最后一次发现优于 champ (因而 champ challenger 更新),并之后没有出现二义性的结果时, champ_compared_to_predecessor 可以是 1 ;而这个标记 0 ,仅当最后一次比较的结果是 champ 优于 chanlleger 。因此对于该标记为 1 champ 之前的候选者不需要比较,但当标记为 0 时需要包括之。为什么需要第二个 FOR 循环呢?首先注意到如果找到最佳候选者,最后一次的比较必然不会出现二义性,否则该函数将在 5957 行返回 0 。另外看到如果出现二义性,这两个候选者都被跳过,比较在后面的候选者中重新开始。因此有可能具有二义性的候选者要优于在第一个 FOR 循环中找到的最佳候选者,而这个情形,在第二 FOR 循环中,将被发现为一个错误,并在 5980 行返回 0

在上面看到,被选出的可行候选者的 viable 域是非 0 值。并记得如果该转换不为标准所允许,这个域将保存值 -1 。作为一个快速的挑选,不同的 viable 值显示谁为更优。毫无疑问,标准所允许的转换总是更优胜。

 

5653 static int

5654 joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)                      in call.c

5655 {

5656    int winner = 0;

5657    int i, off1 = 0, off2 = 0, len;

5658

5659     /* Candidates that involve bad conversions are always worse than those

5660      that don't.  */

5661    if (cand1->viable > cand2->viable)

5662      return 1;

5663    if (cand1->viable < cand2->viable)

5664      return -1;

5665

5666    /* If we have two pseudo-candidates for conversions to the same type,

5667      or two candidates for the same function, arbitrarily pick one.  */

5668    if (cand1->fn == cand2->fn

5669        && (TYPE_P (cand1->fn) || DECL_P (cand1->fn)))

5670      return 1;

5671

5672    /* a viable function F1

5673      is defined to be a better function than another viable function F2 if

5674      for all arguments i, ICSi(F1) is not a worse conversion sequence than

5675      ICSi(F2), and then */

5676

5677    /* for some argument j, ICSj(F1) is a better conversion sequence than

5678      ICSj(F2) */

5679

5680    /* For comparing static and non-static member functions, we ignore

5681      the implicit object parameter of the non-static function. The

5682      standard says to pretend that the static function has an object

5683      parm, but that won't work with operator overloading.  */

5684    len = TREE_VEC_LENGTH (cand1->convs);

5685    if (len != TREE_VEC_LENGTH (cand2->convs))

5686    {

5687      if (DECL_STATIC_FUNCTION_P (cand1->fn)

5688          && ! DECL_STATIC_FUNCTION_P (cand2->fn))

5689        off2 = 1;

5690      else if (! DECL_STATIC_FUNCTION_P (cand1->fn)

5691             && DECL_STATIC_FUNCTION_P (cand2->fn))

5692      {

5693        off1 = 1;

5694        --len;

5695      }

5696      else

5697        abort ();

5698    }

5699

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

5701    {

5702      tree t1 = TREE_VEC_ELT (cand1->convs, i+off1);

5703      tree t2 = TREE_VEC_ELT (cand2->convs, i+off2);

5704      int comp = compare_ics (t1, t2);

5705

5706      if (comp != 0)

5707      {

5708        if (warn_sign_promo

5709           && ICS_RANK (t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK

5710           && TREE_CODE (t1) == STD_CONV

5711           && TREE_CODE (t2) == STD_CONV

5712           && TREE_CODE (TREE_TYPE (t1)) == INTEGER_TYPE

5713           && TREE_CODE (TREE_TYPE (t2)) == INTEGER_TYPE

5714           && (TYPE_PRECISION (TREE_TYPE (t1))

5715                == TYPE_PRECISION (TREE_TYPE (t2)))

5716           && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (t1, 0)))

5717           || (TREE_CODE (TREE_TYPE (TREE_OPERAND (t1, 0)))

5718                == ENUMERAL_TYPE)))

5719        {

5720          tree type = TREE_TYPE (TREE_OPERAND (t1, 0));

5721          tree type1, type2;

5722           struct z_candidate *w, *l;

5723          if (comp > 0)

5724            type1 = TREE_TYPE (t1), type2 = TREE_TYPE (t2),

5725               w = cand1, l = cand2;

5726          else

5727            type1 = TREE_TYPE (t2), type2 = TREE_TYPE (t1),

5728                w = cand2, l = cand1;

5729

5730          if (warn)

5731          {

5732            warning ("passing `%T' chooses `%T' over `%T'",

5733                     type, type1, type2);

5734            warning ("  in call to `%D'", w->fn);

5735          }

5736           else

5737            add_warning (w, l);

5738        }

5739

5740        if (winner && comp != winner)

5741        {

5742          winner = 0;

5743          goto tweak;

5744        }

5745        winner = comp;

5746      }

5747    }

 

候选者中有可能同时包括了静态转换函数及非静态转换函数。如果相比较的候选者在一者是静态的,另一者不是;就需要在比较过程中忽略隐含的‘ this ’指针。因此在 5702 5703 行的 t1 t2 拷贝出需要的参数,并传递给如下的函数。

 

5293 static int

5294 compare_ics (tree ics1, tree ics2)                                                                       in call.c

5295 {

5296    tree from_type1;

5297    tree from_type2;

5298    tree to_type1;

5299    tree to_type2;

5300    tree deref_from_type1 = NULL_TREE;

5301    tree deref_from_type2 = NULL_TREE;

5302    tree deref_to_type1 = NULL_TREE;

5303    tree deref_to_type2 = NULL_TREE;

5304    int rank1, rank2;

5305

5306    /* REF_BINDING is nonzero if the result of the conversion sequence

5307      is a reference type. In that case TARGET_TYPE is the

5308      type referred to by the reference.  */

5309    tree target_type1;

5310    tree target_type2;

5311

5312    /* Handle implicit object parameters.  */

5313    maybe_handle_implicit_object (&ics1);

5314    maybe_handle_implicit_object (&ics2);

5315

5316    /* Handle reference parameters.  */

5317    target_type1 = maybe_handle_ref_bind (&ics1);

5318    target_type2 = maybe_handle_ref_bind (&ics2);

5319

5320    /* [over.ics.rank]

5321

5322      When comparing the basic forms of implicit conversion sequences (as

5323      defined in _over.best.ics_)

5324

5325      --a standard conversion sequence (_over.ics.scs_) is a better

5326       conversion sequence than a user-defined conversion sequence

5327       or an ellipsis conversion sequence, and

5328      

5329      --a user-defined conversion sequence (_over.ics.user_) is a

5330       better conversion sequence than an ellipsis conversion sequence

5331       (_over.ics.ellipsis_).  */

5332    rank1 = ICS_RANK (ics1);

5333    rank2 = ICS_RANK (ics2);

 

下面在 5258 行的注释来自【 3 】条文 13.3.1 “候选函数及实参列表”,条款 4 。它解释到现在需要把‘ this ’指针转换为相匹配 cv- 限定的引用。

 

5253 static void

5254 maybe_handle_implicit_object (tree *ics)                                                            in call.c

5255 {

5256    if (ICS_THIS_FLAG (*ics))

5257    {

5258      /* [over.match.funcs]

5259   

5260        For non-static member functions, the type of the

5261        implicit object parameter is "reference to cv X"

5262        where X is the class of which the function is a

5263        member and cv is the cv-qualification on the member

5264        function declaration.  */

5265      tree t = *ics;

5266      tree reference_type;

5267

5268      /* The `this' parameter is a pointer to a class type. Make the

5269        implicit conversion talk about a reference to that same class

5270        type.  */

5271      reference_type = TREE_TYPE (TREE_TYPE (*ics));

5272      reference_type = build_reference_type (reference_type);

5273

5274      if (TREE_CODE (t) == QUAL_CONV)

5275        t = TREE_OPERAND (t, 0);

5276      if (TREE_CODE (t) == PTR_CONV)

5277        t = TREE_OPERAND (t, 0);

5278      t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE);

5279      t = direct_reference_binding (reference_type, t);

5280      *ics = t;

5281    }

5282 }

 

既然我们知道的具体的引用类型,就可以直接构建这个转换序列。这个需要增加的转换序列应该仅是 REF_BIND 。注意上面 5274 5277 行的代码,看到在 standard_conversion 603 行, PTR_CONV 总是构建在 QUAL_CONV 中,如果它们都出现。

 

895    static tree

896    direct_reference_binding (tree type, tree conv)                                                         in call.c

897    {

898      tree t;

899   

900      my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 20030306);

901      my_friendly_assert (TREE_CODE (TREE_TYPE (conv)) != REFERENCE_TYPE,

902                       20030306);

903   

904      t = TREE_TYPE (type);

905   

906      /* [over.ics.rank]

907        

908        When a parameter of reference type binds directly

909        (_dcl.init.ref_) to an argument expression, the implicit

910        conversion sequence is the identity conversion, unless the

911         argument expression has a type that is a derived class of the

912        parameter type, in which case the implicit conversion sequence is

913        a derived-to-base Conversion.

914        

915        If the parameter binds directly to the result of applying a

916        conversion function to the argument expression, the implicit

917        conversion sequence is a user-defined conversion sequence

918        (_over.ics.user_), with the second standard conversion sequence

919        either an identity conversion or, if the conversion function

920        returns an entity of a type that is a derived class of the

921        parameter type, a derived-to-base conversion.  */

922      if (!same_type_ignoring_top_level_qualifiers_p (t, TREE_TYPE (conv)))

923      {

924        /* Represent the derived-to-base conversion.  */

925        conv = build_conv (BASE_CONV, t, conv);

926        /* We will actually be binding to the base-class subobject in

927          the derived class, so we mark this conversion appropriately.

928          That way, convert_like knows not to generate a temporary.  */

929        NEED_TEMPORARY_P (conv) = 0;

930      }

931      return build_conv (REF_BIND, type, conv);

932    }

 

那么在上面的 5317 行, maybe_handle_ref_bind 获取了转换的余下部分,并返回由 REF_BIND 所得引用的援引的类型。

 

5270 static tree

5271 maybe_handle_ref_bind (tree *ics)                                                                     in call.c

5272 {

5273    if (TREE_CODE (*ics) == REF_BIND)

5274    {

5275      tree old_ics = *ics;

5276      tree type = TREE_TYPE (TREE_TYPE (old_ics));

5277      *ics = TREE_OPERAND (old_ics, 0);

5278      ICS_USER_FLAG (*ics) = ICS_USER_FLAG (old_ics);

5279      ICS_BAD_FLAG (*ics) = ICS_BAD_FLAG (old_ics);

5280      return type;

5281    }

5282

5283    return NULL_TREE;

5284 }

 

ICS_RANK 被定义为如下。前面我们看到 C++ 标准为标准转换定义了内部的等级,这个等级就保存在 ICS_STD_RANK 中,而标准转换之外的转换都只有唯一的等级。

 

352    #define ICS_RANK (NODE)                            /                                                in call.c

353      (ICS_BAD_FLAG (NODE) ? BAD_RANK                /

354       : ICS_ELLIPSIS_FLAG (NODE) ? ELLIPSIS_RANK       /

355       : ICS_USER_FLAG (NODE) ? USER_RANK            /

356       : ICS_STD_RANK (NODE))

 

如果我们可以来到这里, BAD_RANK 表示该转换不为标准所允许,但作为扩展还是 OK 的。

 

compare_ics (continue)

 

5335    if (rank1 > rank2)

5336      return -1;

5337    else if (rank1 < rank2)

5338      return 1;

5339

5340    if (rank1 == BAD_RANK)

5341    {

5342      /* XXX Isn't this an extension? */

5343      /* Both ICS are bad. We try to make a decision based on what

5344        would have happened if they'd been good.  */

5345      if (ICS_USER_FLAG (ics1) > ICS_USER_FLAG (ics2)

5346         || ICS_STD_RANK (ics1) > ICS_STD_RANK (ics2))

5347        return -1;

5348      else if (ICS_USER_FLAG (ics1) < ICS_USER_FLAG (ics2)

5349            || ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2))

5350        return 1;

5351

5352      /* We couldn't make up our minds; try to figure it out below.  */

5353    }

5354

5355    if (ICS_ELLIPSIS_FLAG (ics1))

5356      /* Both conversions are ellipsis conversions.  */

5357      return 0;

5358

5359    /* User-defined conversion sequence U1 is a better conversion sequence

5360      than another user-defined conversion sequence U2 if they contain the

5361      same user-defined conversion operator or constructor and if the sec-

5362      ond standard conversion sequence of U1 is better than the second

5363      standard conversion sequence of U2.  */

5364

5365    if (ICS_USER_FLAG (ics1))

5366    {

5367      tree t1, t2;

5368

5369      for (t1 = ics1; TREE_CODE (t1) != USER_CONV; t1 = TREE_OPERAND (t1, 0))

5370        if (TREE_CODE (t1) == AMBIG_CONV)

5371          return 0;

5372      for (t2 = ics2; TREE_CODE (t2) != USER_CONV; t2 = TREE_OPERAND (t2, 0))

5373        if (TREE_CODE (t2) == AMBIG_CONV)

5374          return 0;

5375

5376      if (USER_CONV_FN (t1) != USER_CONV_FN (t2))

5377        return 0;

5378

5379      /* We can just fall through here, after setting up

5380        FROM_TYPE1 and FROM_TYPE2.  */

5381      from_type1 = TREE_TYPE (t1);

5382      from_type2 = TREE_TYPE (t2);

5383    }

5384    else

5385    {

5386      /* We're dealing with two standard conversion sequences.

5387

5388        [over.ics.rank]

5389   

5390        Standard conversion sequence S1 is a better conversion

5391        sequence than standard conversion sequence S2 if

5392      

5393        --S1 is a proper subsequence of S2 (comparing the conversion

5394         sequences in the canonical form defined by _over.ics.scs_,

5395         excluding any Lvalue Transformation; the identity

5396         conversion sequence is considered to be a subsequence of

5397         any non-identity conversion sequence */

5398       

5399      from_type1 = ics1;

5400      while (TREE_CODE (from_type1) != IDENTITY_CONV)

5401        from_type1 = TREE_OPERAND (from_type1, 0);

5402      from_type1 = TREE_TYPE (from_type1);

5403       

5404      from_type2 = ics2;

5405      while (TREE_CODE (from_type2) != IDENTITY_CONV)

5406        from_type2 = TREE_OPERAND (from_type2, 0);

5407      from_type2 = TREE_TYPE (from_type2);

5408    }

 

上面在 5365 行,如果满足条件,表示该序列包含了用户定义转换,而在那一点上, ics1 ics2 具有相同的等级,因此它们要么同时包含用户定义转换,要么都不包含。在 5376 行的 USER_CONV_FN 保存了为这个 USER_CONV 所找出的转换函数。如果这两个候选的参数所使用的用户定义转换不相同,它们是包括区分的(等级上)。

而对于标准转换序列,【 3 】的条文 13.3.3 .1.1 ,条款 2 ,强调以规范的次序应用转换,依次为:左值转型( Lvalue Transformation ),提升( Promotion )或转换( Conversion ),限定调整( Qualifier Adjustment );回到 standard_conversion ,看到它确实会产生这个序列,但次序相反。

 

compare_ics (continue)

 

5410    if (same_type_p (from_type1, from_type2))

5411    {

5412      if (is_subseq (ics1, ics2))

5413        return 1;

5414      if (is_subseq (ics2, ics1))

5415        return -1;

5416    }

 

进一步的,【 3 】的条文 13.3.3 .2 ,条款 3 5386 行的注释),在等级评估过程中,左值转型应该被排除;在前端中,这对应着 LVALUE_CONV RVALUE_CONV 。因此 is_subseq 根据标准,如果 ics1 ics2 的一个正确子序列,就返回 true

 

5177 static bool

5178 is_subseq (tree ics1, tree ics2)                                                                          in call.c

5179 {

5180    /* We can assume that a conversion of the same code

5181      between the same types indicates a subsequence since we only get

5182      here if the types we are converting from are the same.  */

5183

5184    while (TREE_CODE (ics1) == RVALUE_CONV

5185          || TREE_CODE (ics1) == LVALUE_CONV)

5186      ics1 = TREE_OPERAND (ics1, 0);

5187

5188    while (1)

5189    {

5190      while (TREE_CODE (ics2) == RVALUE_CONV

5191            || TREE_CODE (ics2) == LVALUE_CONV)

5192        ics2 = TREE_OPERAND (ics2, 0);

5193

5194      if (TREE_CODE (ics2) == USER_CONV

5195         || TREE_CODE (ics2) == AMBIG_CONV

5196         || TREE_CODE (ics2) == IDENTITY_CONV)

5197        /* At this point, ICS1 cannot be a proper subsequence of

5198          ICS2. We can get a USER_CONV when we are comparing the

5199          second standard conversion sequence of two user conversion

5200          sequences.  */

5201        return false;

5202

5203      ics2 = TREE_OPERAND (ics2, 0);

5204

5205      if (TREE_CODE (ics2) == TREE_CODE (ics1)

5206         && same_type_p (TREE_TYPE (ics2), TREE_TYPE (ics1))

5207          && same_type_p (TREE_TYPE (TREE_OPERAND (ics2, 0)),

5208                         TREE_TYPE (TREE_OPERAND (ics1, 0))))

5209        return true;

5210    }

5211 }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值