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

来源:互联网 发布:今晚非农数据最新 编辑:程序博客网 时间:2024/05/13 03:50

5.13.1.1.3.       引用类型的转换

如果目标类型是引用类型(参见implicit_conversion1106行),这是由【3】条文13.3.3.1.4“引用绑定”[over.ics.ref]所指定的引用绑定的情形。

1.  当一个引用类型的形参直接绑定(8.5.3)到一个实参表达式,其隐式转换序列是恒等转换,除非该实参表达式的类型是形参类型的一个派生类,这时其隐式转换序列是一个派生类到基类的转换(13.3.3.1)。[例子:

struct A {};

struct B : public A {} b;

int f(A&);

int f(B&);

int i = f(b); // Calls f(B&), an exact match, rather than

// f(A&), a conversion

例子结束] 如果该形参直接绑定到应用在该实参表达式的一个转换函数的结果,其隐式转换序列是一个用户定义转换(13.3.3.1.2),其中的第二标准转换序列或者是一个恒等转换,或者,如果该转换函数返回该形参类型的一个派生类的实体,是派生类到基类的转换。

 2.  当一个引用类型的形参不是直接绑定到一个实参表达式,其转换序列被要求根据13.3.3.1(亦即,隐式转换序列)把实参表达式转换到该引用的援引类型。在概念上,这个转换序列负责通过该实参表达式拷贝初始化一个该引用援引类型的临时对象。最顶层的cv-限定的差别被归入初始化本身,而不构成一个转换。

 3.  一个标准转换序列不能形成,如果要求绑定一个非常量引用到一个右值(除了在绑定一个隐含对象参数;参见在13.3.1中对这个情形的特殊规则)。[注意:这意味着,例如,如果一个候选函数具有一个非常量引用参数(隐含对象参数以外),并且对应的实参是一个临时对象,或为了初始化这个引用要求一个临时对象(参见8.5.3]

 4.  不过,绑定一个引用到一个特定的实参的其他限制不影响一个标准转换序列的构成。[例如:一个具有int引用参数的函数可以是一个可行候选,即便对应的实参是一个int的位域。隐式转换序列把int位域作为一个int左值处理,并查找形参的一个精确匹配。如果是通过重载解析来选择,这样这个函数的调用将是非法的,因为禁止绑定一个非常量的引用到一个位域(8.5.3]

5.  一个引用到一个与引用兼容,带有更多限定的表达式的绑定,会影响一个标准转换序列的等级;参考13.3.3.28.5.3

 

940    static tree

941    reference_binding (tree rto, tree rfrom,tree expr, int flags)                                  incall.c

942    {

943      tree conv = NULL_TREE;

944      tree to = TREE_TYPE (rto);

945      tree from = rfrom;

946      bool related_p;

947      bool compatible_p;

948      cp_lvalue_kind lvalue_p = clk_none;

949   

950      if (TREE_CODE (to) == FUNCTION_TYPE&& expr && type_unknown_p (expr))

951      {

952        expr = instantiate_type(to, expr, tf_none);

953        if (expr == error_mark_node)

954          return NULL_TREE;

955        from = TREE_TYPE (expr);

956      }

5.13.1.1.3.1. 重载引用的解析

如果被援引的目标类型是一个函数或方法的类型,并且被传入的实参表达式一个重载,其类型是unknown_type_node并且使得type_unknown_p成立(它可能是一个baselinktemplate-id)。这也需要为该实参确定正确的候选者。

下面的函数将实例化在中rhs给定的表达式的类型,来匹配由lhstype给定的类型。

 

6001 tree

6002 instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)                           in class.c

6003 {

6004   tsubst_flags_t flags_in = flags;

6005   

6006   flags &= ~tf_ptrmem_ok;

6007   

6008   if (TREE_CODE (lhstype) ==UNKNOWN_TYPE)

6009   {

6010     if (flags & tf_error)

6011       error ("not enoughtype information");

6012     returnerror_mark_node;

6013   }

6014

6015   if (TREE_TYPE (rhs) !=NULL_TREE && ! (type_unknown_p (rhs)))

6016   {

6017     if (same_type_p (lhstype,TREE_TYPE (rhs)))

6018       returnrhs;

6019     if (flag_ms_extensions

6020        && TYPE_PTRMEMFUNC_P(lhstype)

6021        &&!TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))

6022       /*Microsoft allows `A::f' to be resolved to a

6023         pointer-to-member.  */

6024       ;

6025     else

6026     {

6027       if (flags &tf_error)

6028         error ("argumentof type `%T' does not match `%T'",

6029              TREE_TYPE (rhs),lhstype);

6030       returnerror_mark_node;

6031     }

6032   }

 

看到6015行的条件如果满足,rhs的类型是确实已知的,它必须与目标类型(lhstype)相同;否则不匹配的类型rhslhs会导致一个错误。如果rhsTREE_TYPE中具有unknown_type_nodeNULL,这表示有多个表达式适合rhs,就需要由lhs的类型来确定最后胜出者。

正如6042行的注释所提到的,在6047行开始的SWITCH块用于区分这是哪种指向函数的指针(事实上也包括引用)。

在下面6072行的NOP_EXPR,它用于表示不要求任何代码产生的转换。例如,一个‘char*’到一个‘int*’的转换不要求产生任何代码;这样的一个转换由一个NOP_EXPR来代表。其唯一的操作数是要被转换的表达式。从一个指针到一个引用的转换也是由一个NOP_EXPR来表示。如果我们来到这个分支,NOP_EXPRTREE_TYPE必须是NULL或者unknown_type_node来显示多种选择。在剥除这个顶层的NOP_EXPR之后,需要通过设置其操作数的TREE_TYPEunknown_type_node,来保留这个显示不确定性的信息。

 

instantiate_type (continue)

 

6034   if (TREE_CODE (rhs) ==BASELINK)

6035     rhs = BASELINK_FUNCTIONS(rhs);

6036

6037   /*We don't overwrite rhs if it is an overloaded function.

6038     Copying it would destroy the treelink.  */

6039   if (TREE_CODE (rhs) !=OVERLOAD)

6040     rhs = copy_node (rhs);

6041

6042   /*This should really only be used when attempting to distinguish

6043     whatsort of a pointer to function we have. For now, any

6044     arithmetic operation which is not supportedon pointers

6045     isrejected as an error.  */

6046

6047   switch(TREE_CODE (rhs))

6048   {

6049     caseTYPE_EXPR:

6050     caseCONVERT_EXPR:

6051     caseSAVE_EXPR:

6052     caseCONSTRUCTOR:

6053     caseBUFFER_REF:

6054       abort ();

6055       returnerror_mark_node;

6056

6057     caseINDIRECT_REF:

6058     caseARRAY_REF:

6059     {

6060       tree new_rhs;

6061

6062       new_rhs = instantiate_type (build_pointer_type (lhstype),

6063                              TREE_OPERAND (rhs,0), flags);

6064       if (new_rhs ==error_mark_node)

6065         return error_mark_node;

6066

6067       TREE_TYPE (rhs) =lhstype;

6068       TREE_OPERAND (rhs, 0) =new_rhs;

6069       returnrhs;

6070     }

6071

6072     caseNOP_EXPR:

6073       rhs = copy_node(TREE_OPERAND (rhs, 0));

6074       TREE_TYPE (rhs) =unknown_type_node;

6075       returninstantiate_type (lhstype, rhs, flags);

6076

6077     caseCOMPONENT_REF:

6078     {

6079       tree addr = instantiate_type (lhstype, TREE_OPERAND (rhs, 1),flags);

6080

6081       if (addr != error_mark_node

6082          &&TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))

6083         /* Do not lose object's side effects.  */

6084         addr = build(COMPOUND_EXPR, TREE_TYPE (addr),

6085                    TREE_OPERAND (rhs, 0),addr);

6086       returnaddr;

6087     }

6088

6089     caseOFFSET_REF:

6090       rhs = TREE_OPERAND (rhs,1);

6091       if (BASELINK_P (rhs))

6092         return instantiate_type(lhstype, BASELINK_FUNCTIONS (rhs), flags_in);

6093

6094       /*This can happen if we are forming a pointer-to-member for a

6095         member template.  */

6096       my_friendly_assert(TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0);

6097

6098       /*Fall through.  */

6099

6100     caseTEMPLATE_ID_EXPR:

6101     {

6102       tree fns = TREE_OPERAND(rhs, 0);

6103       tree args = TREE_OPERAND(rhs, 1);

6104

6105       return

6106          resolve_address_of_overloaded_function(lhstype, fns, flags_in,

6107                                             /*template_only=*/true,

6108                                             args);

6109     }

6110

6111     caseOVERLOAD:

6112     caseFUNCTION_DECL:

6113       return

6114          resolve_address_of_overloaded_function(lhstype, rhs, flags_in,

6115                                            /*template_only=*/false,

6116                                            /*explicit_targs=*/NULL_TREE);

6117

6118     caseTREE_LIST:

6119       /*Now we should have a baselink.  */

6120       my_friendly_assert(BASELINK_P (rhs), 990412);

6121

6122       returninstantiate_type (lhstype, BASELINK_FUNCTIONS(rhs), flags);

6123

6124     caseCALL_EXPR:

6125       /*This is too hard for now.  */

6126       abort ();

6127       returnerror_mark_node;

6128

6129     casePLUS_EXPR:

6130     caseMINUS_EXPR:

6131     caseCOMPOUND_EXPR:

6132       TREE_OPERAND (rhs, 0)

6133             = instantiate_type (lhstype, TREE_OPERAND (rhs, 0),flags);

6134       if (TREE_OPERAND (rhs,0) == error_mark_node)

6135         return error_mark_node;

6136       TREE_OPERAND (rhs, 1)

6137             = instantiate_type (lhstype, TREE_OPERAND (rhs, 1),flags);

6138       if (TREE_OPERAND (rhs,1) == error_mark_node)

6139         return error_mark_node;

6140

6141       TREE_TYPE (rhs) = lhstype;

6142       returnrhs;

6143

6144     caseMULT_EXPR:

6145     caseTRUNC_DIV_EXPR:

6146     caseFLOOR_DIV_EXPR:

6147     caseCEIL_DIV_EXPR:

6148     caseROUND_DIV_EXPR:

6149     caseRDIV_EXPR:

6150     caseTRUNC_MOD_EXPR:

6151     caseFLOOR_MOD_EXPR:

6152     caseCEIL_MOD_EXPR:

6153     caseROUND_MOD_EXPR:

6154     caseFIX_ROUND_EXPR:

6155     caseFIX_FLOOR_EXPR:

6156     caseFIX_CEIL_EXPR:

6157     caseFIX_TRUNC_EXPR:

6158     caseFLOAT_EXPR:

6159     caseNEGATE_EXPR:

6160     caseABS_EXPR:

6161     caseMAX_EXPR:

6162     caseMIN_EXPR:

6163

6164     caseBIT_AND_EXPR:

6165     caseBIT_IOR_EXPR:

6166     caseBIT_XOR_EXPR:

6167     caseLSHIFT_EXPR:

6168     caseRSHIFT_EXPR:

6169     caseLROTATE_EXPR:

6170     caseRROTATE_EXPR:

6171

6172     casePREINCREMENT_EXPR:

6173     casePREDECREMENT_EXPR:

6174     casePOSTINCREMENT_EXPR:

6175     casePOSTDECREMENT_EXPR:

6176       if (flags &tf_error)

6177         error ("invalidoperation on uninstantiated type");

6178       returnerror_mark_node;

6179

6180     caseTRUTH_AND_EXPR:

6181     caseTRUTH_OR_EXPR:

6182     caseTRUTH_XOR_EXPR:

6183     caseLT_EXPR:

6184     caseLE_EXPR:

6185     caseGT_EXPR:

6186     caseGE_EXPR:

6187     caseEQ_EXPR:

6188     caseNE_EXPR:

6189     caseTRUTH_ANDIF_EXPR:

6190     caseTRUTH_ORIF_EXPR:

6191     caseTRUTH_NOT_EXPR:

6192       if (flags &tf_error)

6193         error ("notenough type information");

6194       returnerror_mark_node;

6195

6196     caseCOND_EXPR:

6197       if (type_unknown_p(TREE_OPERAND (rhs, 0)))

6198       {

6199         if (flags &tf_error)

6200           error ("notenough type information");

6201         return error_mark_node;

6202       }

6203       TREE_OPERAND (rhs, 1)

6204           = instantiate_type (lhstype, TREE_OPERAND (rhs, 1),flags);

6205       if (TREE_OPERAND (rhs,1) == error_mark_node)

6206         return error_mark_node;

6207       TREE_OPERAND (rhs, 2)

6208           = instantiate_type (lhstype, TREE_OPERAND (rhs, 2),flags);

6209       if (TREE_OPERAND (rhs,2) == error_mark_node)

6210         return error_mark_node;

6211

6212       TREE_TYPE (rhs) =lhstype;

6213       returnrhs;

6214

6215     caseMODIFY_EXPR:

6216       TREE_OPERAND (rhs, 1)

6217           = instantiate_type (lhstype, TREE_OPERAND (rhs, 1),flags);

6218       if (TREE_OPERAND (rhs,1) == error_mark_node)

6219         return error_mark_node;

6220

6221       TREE_TYPE (rhs) =lhstype;

6222       returnrhs;

6223       

6224     caseADDR_EXPR:

6225     {

6226       if (PTRMEM_OK_P (rhs))

6227         flags |= tf_ptrmem_ok;

6228       

6229       returninstantiate_type (lhstype, TREE_OPERAND (rhs,0), flags);

6230     }

6231     caseENTRY_VALUE_EXPR:

6232       abort ();

6233       returnerror_mark_node;

6234

6235     caseERROR_MARK:

6236       returnerror_mark_node;

6237

6238     default:

6239       abort ();

6240       returnerror_mark_node;

6241   }

6242 }

 

上面的代码清楚地显示了关注的是指定类别节点哪个操作数(为表达式构建节点的函数,例如,build_binary_op,将把操作数统一到同一个类型。因此对于表达式“ptr+5”(ptr是类型“int*”),这个表达式构建函数将把‘5’提升为类型“int*”)。

如果该重载是合法的(为TEMPLATE_ID_EXPRFUNCITON_DECL,或OVERLOAD),它需要被解析以找出匹配者;显然,多于一个的匹配会导致二义性的问题。看到下面的参数explicit_targs仅用于模板的匹配,它保存了显式给定的模板实参。

3】,条文13.4“重载函数地址”([over.over]),给出了这个语法成分的意义和用法,连同例子。

1.  一个不带参数的重载函数名,在特定上下文中,被解析为一个函数,指向重载函数集中一个特定函数的函数的指针,或指向成员函数的指针。一个函数模板名被视为,在这样的上下文中,命名了一个重载函数集。被选中的函数,其类型与该上下文所要求的目标类型相匹配。这个目标类型可以是

要被初始化的一个对象或引用(8.58.5.3),

一个赋值的左手侧(5.17),

一个函数的一个参数(5.2.2),

一个用户定义操作符的一个参数(13.5),

一个函数,运算符函数,转换函数的返回值(6.6.3),

一个显式类型转换(5.2.35.2.9, 5.4),或者

一个非类型模板参数(14.3.2)。

该重载函数名之前可以是&操作符。一个重载函数名,在那些没有列出的上下文中,不能不带参数来使用。[注意:包围该重载函数名的任意多余括号对被忽略(5.1]

2.  如果这个名字是一个函数模板,执行模板实参推导(14.8.2.2),并且如果实参推导成功,产生的模板实参列表被用于产生一个函数模板特化,这个特化被加入这个正在关注的重载函数集中。

3.  非成员函数及静态成员函数匹配的目标类型为“函数指针”或“函数引用”。非静态成员函数匹配的目标类型是“成员函数指针”;成员指针中的函数类型用于,从重载成员函数集中,选择成员函数。如果一个非静态成员函数被选中,对该重载函数名的一个引用被要求具有一个成员指针的形式,如5.3.1中描述的那样。

4.  如果选中了多于一个函数,如果这个集包含了非模板函数,这个集中的函数模板特化都被淘汰;给定函数模板特化F1,如果在这个集中包含了第二个函数模板特化,其函数模板的特化程度,根据14.5.5.2的偏序规则,比F1的函数模板的特化程度高,淘汰F1。在这样的淘汰之后,应该只留下一个中选的函数。

5.  [例子:

int f(double);

int f(int);

int (*pfd)(double) = &f; // selects f(double)

int (*pfi)(int) = &f; // selects f(int)

int (*pfe)(...) = &f; // error: type mismatch

int (&rfi)(int) = f; // selects f(int)

int (&rfd)(double) = f; // selects f(double)

void g() {

(int (*)(int))&f; // cast expression as selector

}

pfe的初始化是非法的,因为没有定义具有类型int(…)f(),而不是因为二义性。另一个例子,

struct X {

int f(int);

static int f(long);

};

int (X::*p1)(int) = &X::f; // OK

int (*p2)(int) = &X::f; // error: mismatch

int (*p3)(long) = &X::f; // OK

int (X::*p4)(long) = &X::f; // error: mismatch

int (X::*p5)(int) = &(X::f); // error: wrong syntax for pointer to member

int (*p6)(long) = &(X::f); // OK

例子结束]

6.  [注意:如果f()g()都是重载函数,解析f(&g),或相当的表达式f(g),必须考虑可能性的叉积(cross product]

7.  [注意:这里没有一个函数指针到另一个函数指针的标准转换(条文4)。特别是,即使BD的一个公有基类,我们有

D* f();

B* (*p1)() = &f; // error

void g(D*);

void (*p2)(B*) = &g; // error

注意结束]

 

5723 static tree

5724 resolve_address_of_overloaded_function (tree target_type,                           inclass.c

5725                                   treeoverload,

5726                                   tsubst_flags_tflags,

5727                                   booltemplate_only,

5728                                   tree explicit_targs)

5729 {

5730   /*Here's what the standard says:

5731      

5732     [over.over]

5733

5734     If thename is a function template, template argument deduction

5735     isdone, and if the argument deduction succeeds, the deduced

5736     arguments are used to generate a singletemplate function, which

5737     isadded to the set of overloaded functions considered.

5738

5739     Non-member functions and static memberfunctions match targets of

5740     type"pointer-to-function" or "reference-to-function." Nonstatic

5741     memberfunctions match targets of type "pointer-to-member

5742     function;" the function type of thepointer to member is used to

5743     selectthe member function from the set of overloaded member

5744     functions. If a nonstatic member functionis selected, the

5745     reference to the overloaded function nameis required to have the

5746     formof a pointer to member as described in 5.3.1.

5747

5748     Ifmore than one function is selected, any template functions in

5749     theset are eliminated if the set also contains a non-template

5750     function, and any given template functionis eliminated if the

5751     setcontains a second template function that is more specialized

5752     than the first according to the partialordering rules 14.5.5.2.

5753     Aftersuch eliminations, if any, there shall remain exactly one

5754     selected function.  */

5755

5756   int is_ptrmem = 0;

5757   int is_reference = 0;

5758   /*We store the matches in a TREE_LIST rooted here. The functions

5759     arethe TREE_PURPOSE, not the TREE_VALUE, in this list, for easy

5760     interoperability withmost_specialized_instantiation.  */

5761   tree matches = NULL_TREE;

5762   tree fn;

5763

5764   /* By the time we get here, we should beseeing only real

5765     pointer-to-member types, not the internalPOINTER_TYPE to

5766     METHOD_TYPE representation.  */

5767   my_friendly_assert(!(TREE_CODE (target_type) == POINTER_TYPE

5768                    && (TREE_CODE(TREE_TYPE (target_type))

5769                         ==METHOD_TYPE)), 0);

5770

5771   my_friendly_assert (is_overloaded_fn (overload), 20030910);

5772   

5773   /*Check that the TARGET_TYPE is reasonable. */

5774   if (TYPE_PTRFN_P(target_type))

5775     /*This is OK.  */;

5776   else if (TYPE_PTRMEMFUNC_P(target_type))

5777     /*This is OK, too.  */

5778     is_ptrmem = 1;

5779   else if (TREE_CODE(target_type) == FUNCTION_TYPE)

5780   {

5781     /* This is OK, too.This comes from a conversion to reference

5782       type. */

5783     target_type = build_reference_type (target_type);

5784     is_reference = 1;

5785   }

5786   else

5787   {

5788     if (flags & tf_error)

5789       error ("/

5790            cannot resolveoverloaded function `%D' based on conversion to type `%T'",

5791            DECL_NAME(OVL_FUNCTION (overload)), target_type);

5792     returnerror_mark_node;

5793   }

5794   

5795   /*If we can find a non-template function that matches, we can just

5796     useit. There's no point in generating template instantiations

5797     ifwe're just going to throw them out anyhow. But, of course, we

5798     canonly do this when we don't *need* a template function.  */

5799   if (!template_only)

5800   {

5801     tree fns;

5802

5803     for(fns = overload; fns; fns = OVL_NEXT (fns))

5804     {

5805       tree fn = OVL_CURRENT(fns);

5806       tree fntype;

5807

5808       if (TREE_CODE (fn) ==TEMPLATE_DECL)

5809         /* We're not looking for templates just yet.  */

5810         continue;

5811

5812       if ((TREE_CODE(TREE_TYPE (fn)) == METHOD_TYPE)

5813          != is_ptrmem)

5814         /* We're looking for a non-static member, and this isn't

5815           one, or vice versa.  */

5816         continue;

5817

5818       /*Ignore anticipated decls of undeclared builtins.  */

5819       if (DECL_ANTICIPATED(fn))

5820         continue;

5821

5822       /*See if there's a match.  */

5823       fntype = TREE_TYPE (fn);

5824       if (is_ptrmem)

5825         fntype =build_ptrmemfunc_type (build_pointer_type (fntype));

5826       else if (!is_reference)

5827         fntype = build_pointer_type (fntype);

5828

5829       if (can_convert_arg (target_type, fntype, fn))

5830         matches = tree_cons(fn, NULL_TREE, matches);

5831     }

5832   }

 

记得重载被串接在一个以OVERLOAD节点开头的链表中,不过在这个头部之后的节点分别包含了FUNCTION_DECL节点,它在5805行由OVL_CURRENT获取。然后,在5823行的fntype将是确定的FUNCTION_TYPE,而不是unknown_type_node。因此从它构建指针类型。对于这些类型,can_convert_arg将检查该类型是否可以被隐式地转换到target_type,并且在处理这个指针转换的standard_conversion中,在619行,我们可以看到函数指针要求精确匹配,就像上面例子所显示的那样。

而在重载函数中,非模板函数优于模板函数,如果找到了非模板函数,就忽略所有的模板函数。如果我们不能找到匹配的非模板函数,那么我们就要查找匹配的模板函数,我们将进入下面5837行的IF块。

 

resolve_address_of_overloaded_function(continue)

 

5834   /*Now, if we've already got a match (or matches), there's no need

5835     toproceed to the template functions. But, if we don't have a

5836     matchwe need to look at them, too.  */

5837   if (!matches)

5838   {

5839     tree target_fn_type;

5840     tree target_arg_types;

5841     tree target_ret_type;

5842     tree fns;

5843

5844     if (is_ptrmem)

5845       target_fn_type

5846           = TREE_TYPE(TYPE_PTRMEMFUNC_FN_TYPE (target_type));

5847     else

5848       target_fn_type =TREE_TYPE (target_type);

5849     target_arg_types =TYPE_ARG_TYPES (target_fn_type);

5850     target_ret_type =TREE_TYPE (target_fn_type);

5851

5852     /*Never do unification on the 'this' parameter. */

5853     if (TREE_CODE(target_fn_type) == METHOD_TYPE)

5854       target_arg_types =TREE_CHAIN (target_arg_types);

5855    

5856     for(fns = overload; fns; fns = OVL_NEXT (fns))

5857     {

5858       tree fn = OVL_CURRENT(fns);

5859       tree instantiation;

5860       tree instantiation_type;

5861       tree targs;

5862

5863       if (TREE_CODE (fn) !=TEMPLATE_DECL)

5864         /* We're only looking for templates.  */

5865         continue;

5866

5867       if ((TREE_CODE(TREE_TYPE (fn)) == METHOD_TYPE)

5868          != is_ptrmem)

5869         /* We're not looking for a non-static member, and this is

5870           one, or vice versa.  */

5871         continue;

5872

5873       /*Try to do argument deduction.  */

5874       targs = make_tree_vec(DECL_NTPARMS (fn));

5875       if (fn_type_unification (fn, explicit_targs, targs,

5876                          target_arg_types,target_ret_type,

5877                          DEDUCE_EXACT, -1) !=0)

5878         /* Argument deduction failed.  */

5879         continue;

5880

5881       /*Instantiate the template.  */

5882       instantiation =instantiate_template (fn, targs, flags);

5883       if (instantiation ==error_mark_node)

5884         /* Instantiation failed. */

5885         continue;

5886

5887       /*See if there's a match.  */

5888       instantiation_type =TREE_TYPE (instantiation);

5889       if (is_ptrmem)

5890         instantiation_type =

5891            build_ptrmemfunc_type (build_pointer_type (instantiation_type));

5892       else if (!is_reference)

5893         instantiation_type = build_pointer_type (instantiation_type);

5894       if (can_convert_arg (target_type, instantiation_type,instantiation))

5895         matches = tree_cons(instantiation, fn, matches);

5896     }

5897

5898     /*Now, remove all but the most specialized of the matches.  */

5899     if (matches)

5900     {

5901       tree match =most_specialized_instantiation (matches);

5902

5903       if (match !=error_mark_node)

5904         matches = tree_cons(match, NULL_TREE, NULL_TREE);

5905     }

5906   }

 

在前一节,我们已经看过了模板实参推导。这里我们就不麻烦再看一遍了。

 

resolve_address_of_overloaded_function(continue)

 

5908 Now we should have exactly one function inMATCHES.  */

5909   if (matches == NULL_TREE)

5910   {

5911     /*There were *no* matches.  */

5912     if (flags & tf_error)

5913     {

5914       error ("no matchesconverting function `%D' to type `%#T'",

5915            DECL_NAME(OVL_FUNCTION (overload)),

5916            target_type);

5917

5918       /* print_candidates expects a chain with thefunctions in

5919         TREE_VALUE slots, so we cons one uphere (we're losing anyway,

5920         sowhy be clever?).  */

5921       for(; overload; overload = OVL_NEXT (overload))

5922         matches = tree_cons(NULL_TREE, OVL_CURRENT (overload),

5923                           matches);

5924           

5925       print_candidates(matches);

5926     }

5927     returnerror_mark_node;

5928   }

5929   else if (TREE_CHAIN(matches))

5930   {

5931     /*There were too many matches.  */

5932

5933     if (flags & tf_error)

5934     {

5935       tree match;

5936

5937       error ("convertingoverloaded function `%D' to type `%#T' is ambiguous",

5938            DECL_NAME(OVL_FUNCTION (overload)),

5939            target_type);

5940

5941       /*Since print_candidates expects the functions in the

5942         TREE_VALUE slot, we flip themhere.  */

5943       for(match = matches; match; match = TREE_CHAIN (match))

5944         TREE_VALUE (match) =TREE_PURPOSE (match);

5945

5946       print_candidates(matches);

5947     }

5948       

5949     returnerror_mark_node;

5950   }

5951

5952   /*Good, exactly one match. Now, convert it to the correct type.  */

5953   fn = TREE_PURPOSE (matches);

5954

5955   if(DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)

5956      && !(flags &tf_ptrmem_ok) && !flag_ms_extensions)

5957   {

5958     staticint explained;

5959       

5960     if (!(flags &tf_error))

5961       returnerror_mark_node;

5962

5963     pedwarn ("assumingpointer to member `%D'", fn);

5964     if (!explained)

5965     {

5966       pedwarn ("(apointer to member can only be formed with `&%E')", fn);

5967       explained = 1;

5968     }

5969   }

5970

5971   /*If we're doing overload resolution purely for the purpose of

5972     determining conversion sequences, we shouldnot consider the

5973     function used. If this conversion sequenceis selected, the

5974     function will be marked as used at thispoint.  */

5975   if (!(flags & tf_conv))

5976     mark_used(fn);

5977

5978   if (TYPE_PTRFN_P(target_type) || TYPE_PTRMEMFUNC_P (target_type))

5979     returnbuild_unary_op (ADDR_EXPR, fn, 0);

5980   else

5981   {

5982     /*The target must be a REFERENCE_TYPE. Above, build_unary_op

5983       willmark the function as addressed, but here we must do it

5984       explicitly.  */

5985     cxx_mark_addressable (fn);

5986

5987     returnfn;

5988   }

5989 }

 

最后,需要把合格的查找结果标记为可取址,这是对代码产生有重要意义的信息。而由该函数返回的fn是匹配的重载。并且这个返回值在952行被保存入expr。而from955行被更新到这个类型。

 

原创粉丝点击