现在的位置: 首页 > 综合 > 正文

GCC-3.4.6源代码学习笔记(147-续2)

2013年11月07日 ⁄ 综合 ⁄ 共 10522字 ⁄ 字号 评论关闭

 

unify (continue)

 

9964

   
 
case
PTRMEM_CST:

9965

    
{

9966

      
/*
A pointer-to-member constant can be unified only with

9967

        
another constant. 
*/

9968

      
if (TREE_CODE (arg) !=
PTRMEM_CST)

9969

        
return
1;

9970

9971

      
/*
Just unify the class member. It would be useless (and possibly

9972

        
wrong, depending on the strict flags)
to unify also

9973

        
PTRMEM_CST_CLASS, because we want to be
sure that both parm and

9974

        
arg refer to the same variable, even if
through different

9975

        
classes.
For instance:

9976

9977

         
struct A { int x; };

9978

         
struct B : A { };

9979

9980

        
Unification of &A::x and &B::x
must succeed. 
*/

9981

      
return
unify
(tparms, targs, PTRMEM_CST_MEMBER (parm),

9982

                 
PTRMEM_CST_MEMBER (arg),
strict);

9983

    
}

9984

9985

    
case
POINTER_TYPE:

9986

    
{

9987

      
if (TREE_CODE (arg) !=
POINTER_TYPE)

9988

        
return
1;

9989

  

9990

      
/*
[temp.deduct.call]

9991

9992

        
A

can be another pointer or pointer to member
type that can

9993

        
be
converted to the deduced A via a qualification

9994

        
conversion (_conv.qual_).

9995

9996

        
We
pass down STRICT here rather than UNIFY_ALLOW_NONE.

9997

        
This will allow for additional
cv-qualification of the

9998

        
pointed-to types if appropriate. 
*/

9999

  

10000

     
if (TREE_CODE (TREE_TYPE
(arg)) == RECORD_TYPE)

10001

       
/* The derived-to-base conversion only persists through one

10002

         

level of pointers. 
*/

10003

       
strict |= (strict_in
& UNIFY_ALLOW_DERIVED);

10004

10005

     
return

unify
(tparms, targs, TREE_TYPE (parm),

10006

                
TREE_TYPE
(arg), strict);

10007

   
}

10008

10009

   
case
REFERENCE_TYPE:

10010

     
if (TREE_CODE (arg) !=
REFERENCE_TYPE)

10011

       
return

1;

10012

     
return
unify
(tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),

10013

                
strict &
UNIFY_ALLOW_MORE_CV_QUAL);

10014

10015

   
case
ARRAY_TYPE:

10016

     
if (TREE_CODE (arg) !=
ARRAY_TYPE)

10017

        
return

1;

10018

     
if ((TYPE_DOMAIN (parm)
== NULL_TREE)

10019

         
!= (TYPE_DOMAIN
(arg) == NULL_TREE))

10020

        
return

1;

10021

     
if (TYPE_DOMAIN (parm)
!= NULL_TREE

10022

        
&& unify
(tparms, targs, TYPE_DOMAIN (parm),

10023

                 
TYPE_DOMAIN
(arg), UNIFY_ALLOW_NONE) != 0)

10024

        
return

1;

10025

     
return
unify
(tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),

10026

                
strict &
UNIFY_ALLOW_MORE_CV_QUAL);

10027

10028

   
case
REAL_TYPE:

10029

   
case
COMPLEX_TYPE:

10030

   
case
VECTOR_TYPE:

10031

   
case
INTEGER_TYPE:

10032

   
case
BOOLEAN_TYPE:

10033

   
case
ENUMERAL_TYPE:

10034

   
case
VOID_TYPE:

10035

     
if (TREE_CODE (arg) !=
TREE_CODE (parm))

10036

       
return

1;

10037

10038

     
if (TREE_CODE (parm) ==
INTEGER_TYPE

10039

        
&& TREE_CODE
(TYPE_MAX_VALUE (parm)) != INTEGER_CST)

10040

     
{

10041

       
if (TYPE_MIN_VALUE
(parm) && TYPE_MIN_VALUE (arg)

10042

          
&& unify
(tparms, targs, TYPE_MIN_VALUE (parm),

10043

                   

TYPE_MIN_VALUE (arg), UNIFY_ALLOW_INTEGER))

10044

         
return
1;

10045

       
if (TYPE_MAX_VALUE
(parm) && TYPE_MAX_VALUE (arg)

10046

          
&& unify
(tparms, targs, TYPE_MAX_VALUE (parm),

10047

                   

TYPE_MAX_VALUE (arg),

10048

                   
UNIFY_ALLOW_INTEGER |
UNIFY_ALLOW_MAX_CORRECTION))

10049

         
return
1;

10050

  
   
}

10051

     
/*
We have already checked cv-qualification at the top of the

10052

       

function. 
*/

10053

     
else if
(!same_type_ignoring_top_level_qualifiers_p (arg, parm))

10054

       
return

1;

10055

10056

     
/*
As far as unification is concerned, this wins. Later checks

10057

       

will invalidate it if necessary. 

*/

10058

     
return
0;

10059

10060

   
/*
Types INTEGER_CST and MINUS_EXPR can come from array bounds. 
*/

10061

   
/*
Type INTEGER_CST can come from ordinary constant template args. 
*/

10062

   
case
INTEGER_CST:

10063

     
while
(TREE_CODE (arg) == NOP_EXPR)

10064

       
arg = TREE_OPERAND
(arg, 0);

10065

10066

     
if (TREE_CODE (arg) !=
INTEGER_CST)

10067

       
return

1;

10068

     
return
!tree_int_cst_equal (parm, arg);

10069

10070

   
case
TREE_VEC:

10071

   
{

10072

     
int i;

10073

     
if (TREE_CODE (arg) !=
TREE_VEC)

10074

       
return
1;

10075

     
if (TREE_VEC_LENGTH
(parm) != TREE_VEC_LENGTH (arg))

10076

       
return
1;

10077

     
for

(i = 0; i < TREE_VEC_LENGTH (parm); ++i)

10078

       
if (unify
(tparms, targs,

10079

               
TREE_VEC_ELT
(parm, i), TREE_VEC_ELT (arg, i),

10080

               

UNIFY_ALLOW_NONE))

10081

         
return
1;

10082

     
return

0;

10083

   
}

 

看一下
9971
行的注释,它解释了为什么推导
PTRMEM_CST_MEMBER
,而不是整个结构。并且注意到对于标量的类型(从
REAL_TYPE

ENUMERATE_TYPE
,而
VOID_TYPE
是一个反常,它不能够被用作模板形参,但可以被传递作为缺省实参),它们对应非类型模板形参(不包括
VOID_TYPE
)。

 

unify (continue)

 

10085

   
case
RECORD_TYPE:

10086

   
case
UNION_TYPE:

10087

     
if (TREE_CODE (arg) !=
TREE_CODE (parm))

10088

       
return

1;

10089

 

10090

     
if (TYPE_PTRMEMFUNC_P
(parm))

10091

     
{

10092

       
if (!TYPE_PTRMEMFUNC_P
(arg))

10093

         
return
1;

10094

10095

       
return
unify
(tparms, targs,

10096

                
  
TYPE_PTRMEMFUNC_FN_TYPE (parm),

10097

                  

TYPE_PTRMEMFUNC_FN_TYPE (arg),

10098

                  
strict);

10099

     
}

10100

10101

     
if
(CLASSTYPE_TEMPLATE_INFO (parm))

10102

     
{

10103

       
tree t = NULL_TREE;

10104

10105

       
if (strict_in &
UNIFY_ALLOW_DERIVED)

10106

       
{

10107

         
/* First, we try to unify the PARM and ARG directly. 
*/

10108

         
t = try_class_unification
(tparms, targs,

10109

                             
 
parm, arg);

10110

10111

         
if (!t)

10112

         
{

10113

          
 
/* Fallback to the
special case allowed in

10114

             

[temp.deduct.call]:

10115

     
    

10116

             

If P is a class, and P has the form

10117

             

template-id, then A can be a derived class of

10118

             

the deduced A. Likewise, if P is a pointer to

10119

             
a

class of the form template-id, A can be a

10120

             

pointer to a derived class pointed to by the

10121

             

deduced A. 
*/

10122

           
t = get_template_base
(tparms, targs,

10123

                              

parm, arg);

10124

10125

           
if (! t || t ==
error_mark_node)

10126

             
return
1;

10127

         
}

10128

 
      
}

10129

       
else if
(CLASSTYPE_TEMPLATE_INFO (arg)

10130

             
&&
(CLASSTYPE_TI_TEMPLATE (parm)

10131

                   
==
CLASSTYPE_TI_TEMPLATE (arg)))

10132

         
/* Perhaps PARM is something like S<U> and ARG is
S<int>.

10133

     
      
Then, we should unify `int' and `U'. 
*/

10134

         
t = arg;

10135

       
else

10136

         
/* There's no chance of unification succeeding. 
*/

10137

         
return
1;

10138

10139

       
return
unify
(tparms, targs, CLASSTYPE_TI_ARGS
(parm),

10140

                  

CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE);

10141

     
}

10142

     
else if
(!same_type_ignoring_top_level_qualifiers_p (parm, arg))

10143

       
return

1;

10144

     
return
0;

 

在上面的
10101
行,如果
CLASSTYPE_TEMPLATE_INFO
不是
null
,表示
parm

是一个类模板。看到在该函数的
9741
行,
strict_in

拷贝自参数
strict

,其中的
UNIFY_ALLOW_DERIVED
是,当通过函数调用推导模板实参时,在
type_unification_real


中设置的(参考在
maybe_adjust_types_for_deduction



之前的段落)。

 

9486

static
tree

9487

try_class_unification

(tree tparms, tree targs, tree parm, tree arg)                        
in pt.c

9488

{

9489

  
tree copy_of_targs;

9490

9491

  
if (!CLASSTYPE_TEMPLATE_INFO
(arg)

9492

      
||
(most_general_template (CLASSTYPE_TI_TEMPLATE (arg))

9493

        
!= most_general_template
(CLASSTYPE_TI_TEMPLATE (parm))))

9494

    
return
NULL_TREE;

9495

9496

 
 
/* We need to make a new template argument
vector for the call to

9497

    
unify.
If we used TARGS, we'd clutter it up with the result of

9498

    
the
attempted unification, even if this class didn't work out.

9499

    
We
also don't want to commit ourselves to all the unifications

9500

    
we've
already done, since unification is supposed to be done on

9501

    
an
argument-by-argument basis. In other words, consider the

9502

    
following
pathological case:

9503

9504

       
template <int I, int J, int K>

9505

       
  
struct S {};

9506

       

9507

       
template <int I, int J>

9508

       
  
struct S<I, J, 2> : public S<I, I,
I>, S<J, J, J> {};

9509

       

9510

       
template <int I, int J, int K>

9511

       
  
void f(S<I, J, K>, S<I, I, I>);

9512

       

9513

       
void g() {

9514

         
S<0, 0, 0> s0;

9515

         
S<0, 1, 2> s2;

9516

       

9517

         
f

(s0, s2);

9518

       
}

9519

9520

    
Now,
by the time we consider the unification involving `s2', we

9521

    
already know that we must have `f<0, 0,
0>'. But, even though

9522

    
`S<0, 1, 2>' is derived from `S<0,
0, 0>', the code is invalid

9523

    
because there are two ways to unify base
classes of S<0, 1, 2>

9524

    
with
S<I, I, I>. If we kept the already deduced knowledge, we

9525

    
would
reject the possibility I=1. 
*/

9526

  
copy_of_targs =
make_tree_vec (TREE_VEC_LENGTH (targs));

9527

  

9528

 
 
/* If unification failed, we're done. 
*/

9529

  
if (unify
(tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm),

9530

          
CLASSTYPE_TI_ARGS
(arg), UNIFY_ALLOW_NONE))

9531

    
return
NULL_TREE;

9532

9533

  
return
arg;

9534

}

 

这里有一个长的注释解释了为什么使用拷贝的模板实参的
vector
,并给出了一个作为错误的例子。进一步的,如果为在
9517
行的
f

交换
s0


s2

,这是好的代码。对于形参“
S<I, I, I>
”,“
S<0, 1, 2>
”不是好的结果,因为“
S<0, 1, 2>
”派生自“
S<0, 0, 0>
”及“
S<1, 1, 1>
”,两者都匹配“
S<I, I, I>
”这个形式。回忆【
3
】规定实参推导是以每个实参为单位进行的,在推导之后,所推导的实参应该与之前推导出的结果,或显式给定的实参相匹配。但看到这里对
unify


的调用,只是一个尝试,通过使用模板实参
vector
的拷贝,就可以不改变得到之前推导的实参。

对于上面注释中给出的例子,
s2

是不同于
S<I, I, I>
的模板,因此
try_class_unification



9494
行返回,然后进入下面的函数来检查基类是否可以统一(因为现在使用了
UNIFY_ALLOW_DERIVED
)。

 

9614

static
tree

9615

get_template_base

(tree tparms, tree targs, tree parm, tree arg)                            
in pt.c

9616

{

9617

  
tree rval;

9618

  
tree arg_binfo;

9619

9620

  
my_friendly_assert
(IS_AGGR_TYPE_CODE (TREE_CODE (arg)), 92);

9621

  

9622

  
arg_binfo = TYPE_BINFO (complete_type
(arg));

9623

  
rval = get_template_base_recursive
(tparms,
targs,

9624

                                
parm,
arg_binfo,

9625

                                
NULL_TREE,

9626

                                
GTB_IGNORE_TYPE);

9627

9628

  
/*
Since get_template_base_recursive marks the bases classes, we

9629

    
must
unmark them here. 
*/

9630

  
dfs_walk (arg_binfo,
dfs_unmark, markedp, 0);

9631

9632

  
return
rval;

9633

}

 

这个函数遍历该类的继承树,以前序在基类上执行
try_class_unification


。看到对于
s2

,其基类“
S<0, 0, 0>
”及“
S<1, 1, 1>
”依次在
9554
行进入
try_class_unification


。但是在最后一次的递归中,分别由
rval


r

所指向的,不相等的“
S<0, 0, 0>
”及“
S<1, 1, 1>
”导致该函数在
9566
行返回
error_mark_node

 

9540

static
tree

9541

get_template_base_recursive


(tree tparms,                                                  
in
pt.c

9542

                        
tree
targs,

9543

                        
tree
parm,

9544

                        
tree
arg_binfo,

9545

     
                   
tree rval,

9546

                        
int
flags)

9547

{

9548

  
tree binfos;

9549

  
int i, n_baselinks;

9550

  
tree arg = BINFO_TYPE
(arg_binfo);

9551

9552

  
if (!(flags &
GTB_IGNORE_TYPE))

9553

  
{

9554

    
tree r = try_class_unification
(tparms, targs,

9555

                            
parm, arg);

9556

9557

    
/*
If there is more than one satisfactory baseclass, then:

9558

9559

      
[temp.deduct.call]

9560

9561

      
If
they yield more than one possible deduced A, the type

9562

      
deduction fails.

9563

9564

      
applies. 

*/

9565

    
if (r && rval
&& !same_type_p (r, rval))

9566

      
return
error_mark_node;

9567

    
else if (r)

9568

      
rval = r;

9569

  
}

9570

9571

  
binfos = BINFO_BASETYPES
(arg_binfo);

9572

  
n_baselinks = binfos ?
TREE_VEC_LENGTH (binfos) : 0;

9573

9574

  
/*
Process base types. 
*/

9575

  
for
(i = 0; i < n_baselinks; i++)

9576

  
{

9577

    
tree base_binfo =
TREE_VEC_ELT (binfos, i);

9578

    
int this_virtual;

9579

9580

    
/*
Skip this base, if we've already seen it. 

*/

9581

    
if (BINFO_MARKED
(base_binfo))

9582

      
continue
;

9583

抱歉!评论已关闭.