您的位置:首页 > 其它

Studying note of GCC-3.4.6 source (147)

2011-01-22 08:33 375 查看
5.13.1.1.2.1.2.

Add template

Below mechanism of implict conversion will try to see if it is
possible to implicitly invoke certain template conversion operator. This
procedure can't be closed by turning off command line option
“–fimiplicit-template”. As the template function is invoked implicit, it is
impossible to specify the template argument directly; the template arguments could
only be deduced from the arguments of the call. And those can’t be deduced
should not be selected.

At point of invocation, ctype

is the type of ‘this’ pointer, explicit_targs

are any explicit template arguments; arglist

is the arguments provided; and return_type

is the desired type for conversion operators (or it is NULL for normal template
function). Then access_path

is the binfo of the class that visits the function (type of ‘this’ pointer
here), and conversion_path

is the binfo of the class that defining the function.

2134

static
struct
z_candidate *

2135

add_template_candidate

(struct
z_candidate
**candidates, tree tmpl, tree ctype,
in
call.c

2136

tree
explicit_targs, tree arglist, tree return_type,

2137

tree
access_path, tree conversion_path, int flags,

2138

unification_kind_t strict)

2139

{

2140

return

2141

add_template_candidate_real
(candidates, tmpl, ctype,

2142

explicit_targs,
arglist, return_type,

2143

access_path,
conversion_path,

2144

flags, NULL_TREE,
strict);

2145

}

Further, strict

here is DEDUCE_CALL for normal template
function (or DEDUCE_CONV for conversion operators); while in calling add_template_candidate_real

below, it passes NULL into obj

.

2035

static
struct
z_candidate*

2036

add_template_candidate_real

(struct
z_candidate
**candidates, tree tmpl,
in call.c

2037

tree
ctype, tree explicit_targs, tree arglist,

2038

tree
return_type, tree access_path,

2039

tree
conversion_path, int flags, tree obj,

2040

unification_kind_t
strict)

2041

{

2042

int ntparms = DECL_NTPARMS
(tmpl);

2043

tree targs = make_tree_vec
(ntparms);

2044

tree args_without_in_chrg =
arglist;

2045

struct
z_candidate *cand;

2046

int i;

2047

tree fn;

2048

2049

/*
We don't do deduction on the in-charge parameter, the VTT

2050

parameter or 'this'.
*/

2051

if
(DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))

2052

args_without_in_chrg =
TREE_CHAIN (args_without_in_chrg);

2053

2054

if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P
(tmpl)

2055

|| DECL_BASE_CONSTRUCTOR_P
(tmpl))

2056

&&
TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (tmpl)))

2057

args_without_in_chrg =
TREE_CHAIN (args_without_in_chrg);

2058

2059

i = fn_type_unification
(tmpl, explicit_targs,
targs,

2060

args_without_in_chrg,

2061

return_type, strict, -1);

Above,
DECL_NTPARMS returns the number of template parameters of tmpl

; correspondingly, targs

is
the vector allocated for the deduced argument; and args_without_in_chrg

indicated by
its name, should hold arguments except those in-charge parameters (‘this’
pointer, VTT etc).

5.12.4.1.1.2.2.1.


Deduce
template argument


[3], clause 14.8.2
“Template argument deduction” is shown in below [temp.deduct
]

.

1.
When a
function template specialization is referenced, all of the template arguments
must have values. The values can be either explicitly specified or, in some
cases, deduced from the use. [Example:

void f(Array<dcomplex>& cv,
Array<int>& ci) {

sort(cv); //
call sort(Array<dcomplex>&)

sort(ci); //
call sort(Array<int>&)

}

and

void g(double d) {

int i = convert<int>(d);
// call
convert<int,double>(double)

int c = convert<char>(d);
// call
convert<char,double>(double)

}


end example]

2.
When an
explicit template argument list is specified, the template arguments must be
compatible with the template parameter list and must result in a valid
function type as described below; otherwise type deduction fails. Specifically,
the following steps are performed when evaluating an explicitly specified
template argument list with respect to a given function template:


The specified template arguments must match the template
parameters in kind
(i.e., type,
nontype, template), and there must not be more arguments than there are
parameters; otherwise type deduction fails.


Nontype arguments must match the types of the corresponding
nontype template parameters, or must be convertible to the types of the
corresponding nontype parameters as specified in 14.3.2,
otherwise type deduction fails.


All references in the function type of the function template to
the corresponding template parameters are replaced by the specified template
argument values. If a substitution in a template parameter or in the function
type of the function template results in an invalid type, type deduction
fails. [Note: The equivalent substitution in exception specifications is done
only when the function is instantiated, at which point a program is ill-formed
if the substitution results in an invalid type.] Type deduction may fail for
the following reasons:

Ø

Attempting to create an array with an element type that is void, a
function type, or a reference type, or attempting to create an array with a
size that is zero or negative. [Example:

template
<class
T> int f(T[5]);

int I = f<int>(0);
// invalid array

int j = f<void>(0);
// invalid array
]

Ø

Attempting to use a type that is not a class type in a qualified
name. [Example:

template
<class
T> int f(typename
T::B*);

int i = f<int>(0); ]

Ø

Attempting to use a type in the qualifier portion of a qualified
name that names a type when that type does not contain the specified member,
or if the specified member is not a type where a type is required. [Example:

template
<class
T> int f(typename
T::B*);

struct
A {};

struct
C { int B; };

int i = f<A>(0);

int j = f<C>(0); ]

Ø

Attempting to create a pointer to reference type.

Ø

Attempting to create a reference to a reference type or a
reference to void.

Ø

Attempting to create "pointer to member of T" when T is
not a class type. [Example:

template
<class
T> int f(int T::*);

int i = f<int>(0); ]

Ø

Attempting to perform an invalid conversion in either a template
argument expression, or an expression used in the function declaration. [Example:

template
<class
T, T*> int f(int);

int i2 = f<int,1>(0);
// can’t conv 1
to int*
]

Ø

Attempting to create a function type in which a parameter has a
type of void.

Ø

Attempting to create a cv-qualified function type.

3.
After this
substitution is performed, the function parameter type adjustments described
in 8.3.5 are performed. [Example: A
parameter type of “void () (const
int,
int[5])” becomes “void(*) (int,int*)”. ] [Note: A top-level qualifier in a
function parameter declaration does not affect the function type but still
affects the type of the function parameter variable within the function.

end note] [Example:

template
<class
T>
void f(T t);

template
<class
X> void g(const
X x);

template
<class
Z> void h(Z, Z*);

int main() {

f<int>(1);
// #1: function
type is f(int), t is nonconst

f<const
int>(1);

// #2: function type is f(int), t is const

g<int>(1);
// #3: function
type is g(int), x is const

g<const
int>(1);

// #4: function type is g(int), x is const

h<const
int>(1,0);

// #5: function type is h(int, const int*)

}


end example] [Note: f<int>(1) and f<const
int>(1) call distinct functions even
though both of the functions called have the same function type.
—end note]

4.
The resulting substituted and adjusted
function type is used as the type of the function template for template
argument deduction. When all template arguments have been deduced, all uses
of template parameters in nondeduced contexts are replaced with the
corresponding deduced argument values. If the substitution results in an
invalid type, as described above, type deduction fails.

5.
Except as
described above, the use of an invalid value shall not cause type deduction
to fail.
[Example: In the following
example 1000 is converted to signed char and results in an implementation-defined
value as specified in (4.7). In other words, both templates are considered
even though 1000, when converted to signed char, results in an
implementation- defined value.

template
<int> int f(int);

template
<signed char> int f(int);

int i1 = f<1>(0);
// ambiguous

int i2 = f<1000>(0);
// ambiguous


end example]

Below function returns 0,
if the template argument deduction succees.

8893

int

8894

fn_type_unification

(tree fn,
in
pt.c

8895

tree
explicit_targs,

8896

tree targs,

8897

tree args,

8898

tree
return_type,

8899

unification_kind_t strict,

8900

int len)

8901

{

8902

tree parms;

8903

tree fntype;

8904

int result;

8905

8906

my_friendly_assert (TREE_CODE (fn) ==
TEMPLATE_DECL, 0);

8907

8908

fntype = TREE_TYPE (fn);

8909

if (explicit_targs)

8910

{

8911

/*
[temp.deduct]

8912

8913

The
specified template arguments must match the template

8914

parameters in kind (i.e., type, nontype,
template), and there

8915

must
not be more arguments than there are parameters;

8916

otherwise type deduction fails.

8917

8918

Nontype arguments must match the types of
the corresponding

8919

nontype template parameters, or must be
convertible to the

8920

types of the corresponding nontype
parameters as specified in

8921

_temp.arg.nontype_, otherwise type
deduction fails.

8922

8923

All
references in the function type of the function template

8924

to
the corresponding template parameters are replaced by the

8925

specified template argument values. If a
substitution in a

8926

template parameter or in the function
type of the function

8927

template results in an invalid type, type
deduction fails.
*/

8928

int i;

8929

tree converted_args;

8930

bool incomplete;

8931

8932

if (explicit_targs ==
error_mark_node)

8933

return
1;

8934

8935

converted_args

8936

= (coerce_template_parms
(DECL_INNERMOST_TEMPLATE_PARMS
(fn),

8937

explicit_targs,
NULL_TREE, tf_none,

8938

/*require_all_arguments=*/
0));

8939

if (converted_args ==
error_mark_node)

8940

return
1;

8941

8942

/*
Substitute the explicit args into the function type. This is

8943

necessary so that, for instance,
explicitly declared function

8944

arguments can match null pointed
constants. If we were given

8945

an
incomplete set of explicit args, we must not do semantic

8946

processing during substitution as we
could create partial

8947

instantiations.
*/

8948

incomplete = NUM_TMPL_ARGS
(explicit_targs) != NUM_TMPL_ARGS (targs);

8949

processing_template_decl

+=
incomplete;

8950

fntype = tsubst (fntype,
converted_args, tf_none, NULL_TREE);

8951

processing_template_decl

-=
incomplete;

8952

8953

if (fntype ==
error_mark_node)

8954

return
1;

8955

8956

/*
Place the explicitly specified arguments in TARGS.
*/

8957

for
(i = NUM_TMPL_ARGS (converted_args); i--;)

8958

TREE_VEC_ELT (targs, i)
= TREE_VEC_ELT (converted_args, i);

8959

}

Argument explicit_args

are explicit template arguments,
for example, provided via a template-id. And we have seen an example of coerce_template_parms

in previous section, which converts the explicit arguments to match the
parameters, and the result is returned to converted_arg

at
line 8935. Then tsubst

at line 8950 subsititutes the template
parameters with the converted arguments.

fn_type_unification (continue)

8961

parms = TYPE_ARG_TYPES
(fntype);

8962

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

*/

8963

if (DECL_NONSTATIC_MEMBER_FUNCTION_P
(fn))

8964

parms = TREE_CHAIN
(parms);

8965

8966

if (return_type)

8967

{

8968

/*
We've been given a return type to match, prepend it.
*/

8969

parms = tree_cons
(NULL_TREE, TREE_TYPE (fntype), parms);

8970

args = tree_cons
(NULL_TREE, return_type, args);

8971

if (len >= 0)

8972

++len;

8973

}

8974

8975

/* We allow incomplete unification without an
error message here

8976

because the standard doesn't seem to
explicitly prohibit it. Our

8977

callers
must be ready to deal with unification failures in any

8978

event.

*/

8979

result = type_unification_real
(DECL_INNERMOST_TEMPLATE_PARMS
(fn),

8980

targs, parms, args, /*subr=*/
0,

8981

strict, /*allow_incomplete*/
1, len);

8982

8983

if (result == 0)

8984

/*
All is well so far. Now, check:

8985

8986

[temp.deduct]

8987

8988

When
all template arguments have been deduced, all uses of

8989

template parameters in nondeduced
contexts are replaced with

8990

the
corresponding deduced argument values. If the

8991

substitution results in an invalid type,
as described above,

8992

type
deduction fails.
*/

8993

if (tsubst (TREE_TYPE
(fn), targs, tf_none, NULL_TREE)

8994

==
error_mark_node)

8995

return
1;

8996

8997

return
result;

8998

}

Keep in mind that now it is handling template function.

In below function, tparms

refers to the template parameters; targs

is
the vector for holding deduced template arguments that would be gotten here
(see it may not be empty if explicit template arguments are given. It contains
those arguments after converting); xparms

are the parameters including the returned
type for conversion operator; xargs

is args_without_in_chrg

above (i.e., arguments of
the call) plus the expected returned type for conversion operator; and If subr

is
1, it means the function being called recursively (to unify the arguments of a
function or method parameter of a function template); allow_incomplete

is 1; and xlen

is
-1 to indicate to consider all parameters, otherwise is the number of xparms

to consider before returning success.

9113

static
int

9114

type_unification_real

(tree tparms,
in
pt.c

9115

tree targs,

9116

tree xparms,

9117

tree xargs,

9118

int subr,

9119

unification_kind_t
strict,

9120

int
allow_incomplete,

9121

int xlen)

9122

{

9123

tree parm, arg;

9124

int i;

9125

int ntparms =
TREE_VEC_LENGTH (tparms);

9126

int sub_strict;

9127

int saw_undeduced = 0;

9128

tree parms, args;

9129

int len;

9130

9131

my_friendly_assert
(TREE_CODE (tparms) == TREE_VEC, 289);

9132

my_friendly_assert (xparms
== NULL_TREE

9133

||
TREE_CODE (xparms) == TREE_LIST, 290);

9134

my_friendly_assert (!xargs
|| TREE_CODE (xargs) == TREE_LIST, 291);

9135

my_friendly_assert (ntparms
> 0, 292);

9136

9137

switch
(strict)

9138

{

9139

case
DEDUCE_CALL:

9140

sub_strict = (UNIFY_ALLOW_OUTER_LEVEL |
UNIFY_ALLOW_MORE_CV_QUAL

9141

|
UNIFY_ALLOW_DERIVED);

9142

break
;

9143

9144

case
DEDUCE_CONV:

9145

sub_strict =
UNIFY_ALLOW_LESS_CV_QUAL;

9146

break
;

9147

9148

case
DEDUCE_EXACT:

9149

sub_strict =
UNIFY_ALLOW_NONE;

9150

break
;

9151

9152

case
DEDUCE_ORDER:

9153

sub_strict =
UNIFY_ALLOW_NONE;

9154

break
;

9155

9156

default
:

9157

abort ();

9158

}

9159

9160

if (xlen == 0)

9161

return
0;

The parameter strict

is one of below, and sub_strict

is set accordingly
above:

Ø

DEDUCE_CALL: We are deducing
arguments for a function call, as in [temp.deduct.call].

Ø

DEDUCE_CONV: We are deducing
arguments for a conversion function, as in [temp.deduct.conv].

Ø

DEDUCE_EXACT: We are deducing
arguments when doing an explicit instantiation as in [temp.explicit], when
determining an explicit specialization as in [temp.expl.spec], or when taking
the address of a function template, as in [temp.deduct.funcaddr].

Ø

DEDUCE_ORDER: We are deducing
arguments when calculating the partial ordering between specializations of
function or class templates, as in [temp.func.order] and [temp.class.order].

type_unification_real (continue)

9163

again:

9164

parms = xparms;

9165

args = xargs;

9166

len = xlen;

9167

9168

while
(parms

9169

&& parms != void_list_node

9170

&& args

9171

&& args !=
void_list_node)

9172

{

9173

parm = TREE_VALUE (parms);

9174

parms = TREE_CHAIN
(parms);

9175

arg = TREE_VALUE (args);

9176

args = TREE_CHAIN (args);

9177

9178

if (arg == error_mark_node)

9179

return
1;

9180

if (arg ==
unknown_type_node)

9181

/*
We can't deduce anything from this, but we might get all the

9182

template args from other function
args.
*/

9183

continue
;

9184

9185

/*
Conversions will be performed on a function argument that

9186

corresponds with a function parameter
that contains only

9187

non-deducible template parameters and
explicitly specified

9188

template parameters.
*/

9189

if (!uses_template_parms
(parm))

9190

{

9191

tree type;

9192

9193

if (!TYPE_P (arg))

9194

type = TREE_TYPE
(arg);

9195

else

9196

type = arg;

9197

9198

if (same_type_p (parm,
type))

9199

continue
;

9200

if (strict !=
DEDUCE_EXACT

9201

&& can_convert_arg
(parm, type, TYPE_P (arg) ?
NULL_TREE : arg))

9202

continue
;

9203

9204

return
1;

9205

}

9206

9207

if (!TYPE_P (arg))

9208

{

9209

my_friendly_assert (TREE_TYPE (arg) !=
NULL_TREE, 293);

9210

if (type_unknown_p (arg))

9211

{

9212

/*
[temp.deduct.type] A template-argument can be deduced from

9213

a
pointer to function or pointer to member
function

9214

argument if
the set of overloaded functions does not

9215

contain
function templates and at most one of a set of

9216

overloaded
functions provides a unique match.
*/

9217

9218

if (resolve_overloaded_unification

9219

(tparms, targs, parm, arg,
strict, sub_strict)

9220

!= 0)

9221

return
1;

9222

continue
;

9223

}

9224

arg = TREE_TYPE (arg);

9225

if (arg == error_mark_node)

9226

return
1;

9227

}

9228

9229

{

9230

int arg_strict = sub_strict;

9231

9232

if (!subr)

9233

arg_strict |= maybe_adjust_types_for_deduction
(strict, &parm, &arg);

9234

9235

if (unify
(tparms,
targs, parm, arg, arg_strict))

9236

return
1;

9237

}

9238

9239

/* Are we done
with the interesting parms?
*/

9240

if (--len == 0)

9241

goto
done;

9242

}

See that if the parameter doesn’t depend on template parameter, it
sees if the type of argument can be implicitly converted to the type of
parameter, just as common function argument matching does. Then if arg

has
TREE_TYPE of unknown_type_node

,
it is possible reference to overload of some kind (see in below, it maybe
“&A::f”, or “&f” within the class scope). So it tries arg

as
overload by resolve_overloaded_unification

.
And remember that method had been looked up would have BASELINK created for.

9281

static
int

9282

resolve_overloaded_unification

(tree tparms,
in
pt.c

9283

tree targs,

9284

tree parm,

9285

tree arg,

9286

unification_kind_t strict,

9287

int
sub_strict)

9288

{

9289

tree tempargs = copy_node
(targs);

9290

int good = 0;

9291

bool addr_p;

9292

9293

if (TREE_CODE (arg) ==
ADDR_EXPR)

9294

{

9295

arg = TREE_OPERAND (arg,
0);

9296

addr_p = true;

9297

}

9298

else

9299

addr_p = false;

9300

9301

if (TREE_CODE (arg) ==
COMPONENT_REF)

9302

/*
Handle `&x' where `x' is some static or non-static member

9303

function name.
*/

9304

arg = TREE_OPERAND (arg,
1);

9305

9306

if (TREE_CODE (arg) ==
OFFSET_REF)

9307

arg = TREE_OPERAND (arg,
1);

9308

9309

/*
Strip baselink information.
*/

9310

if (BASELINK_P (arg))

9311

arg = BASELINK_FUNCTIONS
(arg);

9312

9313

if (TREE_CODE (arg) ==
TEMPLATE_ID_EXPR)

9314

{

9315

/*
If we got some explicit template args, we need to plug them into

9316

the
affected templates before we try to unify, in case the

9317

explicit args will completely resolve the
templates in question.
*/

9318

9319

tree expl_subargs =
TREE_OPERAND (arg, 1);

9320

arg = TREE_OPERAND (arg,
0);

9321

9322

for
(; arg; arg = OVL_NEXT (arg))

9323

{

9324

tree fn = OVL_CURRENT
(arg);

9325

tree subargs, elem;

9326

9327

if (TREE_CODE (fn) !=
TEMPLATE_DECL)

9328

continue
;

9329

9330

subargs = get_bindings_overload
(fn,
DECL_TEMPLATE_RESULT (fn),

9331

expl_subargs);

9332

if (subargs)

9333

{

9334

elem = tsubst
(TREE_TYPE (fn), subargs, tf_none, NULL_TREE);

9335

good += try_one_overload
(tparms, targs, tempargs, parm,

9336

elem, strict,
sub_strict, addr_p);

9337

}

9338

}

9339

}

9340

else if (TREE_CODE (arg) ==
OVERLOAD

9341

|| TREE_CODE (arg) ==
FUNCTION_DECL)

9342

{

9343

for
(; arg; arg = OVL_NEXT (arg))

9344

good += try_one_overload
(tparms, targs, tempargs, parm,

9345

TREE_TYPE
(OVL_CURRENT (arg)),

9346

strict,
sub_strict, addr_p);

9347

}

9348

else

9349

abort ();

9350

9351

/*
[temp.deduct.type] A template-argument can be deduced from a pointer

9352

to
function or pointer to member function argument if the set of

9353

overloaded functions does not contain
function templates and at most

9354

one of
a set of overloaded functions provides a unique match.

9355

9356

So if
we found multiple possibilities, we return success but don't

9357

deduce
anything.
*/

9358

9359

if (good == 1)

9360

{

9361

int i = TREE_VEC_LENGTH
(targs);

9362

for
(; i--; )

9363

if (TREE_VEC_ELT
(tempargs, i))

9364

TREE_VEC_ELT (targs, i) = TREE_VEC_ELT
(tempargs, i);

9365

}

9366

if (good)

9367

return
0;

9368

9369

return
1;

9370

}

At line 9313 above, the qaulified arg

shoud be node of function, it
is either OVERLOAD, or TEMPLATE_EXPR_ID, or FUNCTION_DECL. In TEMPLATE_EXPR_ID,
the first operand is the node of TEMPLATE_DECL for the template function; and
the second operand if non-null is TREE_VEC of explicit arguments. If the
template function is overloaded, the front-end traverses the overload list, and
tries every template function found. At line 9330, DECL_TEMPLATE_RESULT in
TEMPLATE_DECL of template function is *_DECL for object to be created (e.g.,
FUNCTION_DECL).

10424

static
tree

10425

get_bindings_overload

(tree fn, tree decl, tree explicit_args)
in pt.c

10426

{

10427

return
get_bindings_real
(fn, decl, explicit_args, 0,
DEDUCE_EXACT, -1);

10428

}

Now fn

is the TEMPLATE_DECL, and decl

is the associated FUNCTION_DECL with explicit_args

refers to explicit template arguments. And note it uses DEDUCE_EXACT for the
deduction carried out. The function returns the deduced argument if successing.

10355

static
tree

10356

get_bindings_real

(tree fn,
in
pt.c

10357

tree decl,

10358

tree explicit_args,

10359

int
check_rettype,

10360

int deduce,

10361

int len)

10362

{

10363

int ntparms = DECL_NTPARMS
(fn);

10364

tree targs = make_tree_vec
(ntparms);

10365

tree decl_type;

10366

tree decl_arg_types;

10367

int i;

10368

10369

/*
Substitute the explicit template arguments into the type of DECL.

10370

The
call to fn_type_unification will handle substitution into the

10371

FN.

*/

10372

decl_type = TREE_TYPE (decl);

10373

if (explicit_args &&
uses_template_parms
(decl_type))

10374

{

10375

tree tmpl;

10376

tree converted_args;

10377

10378

if (DECL_TEMPLATE_INFO
(decl))

10379

tmpl = DECL_TI_TEMPLATE
(decl);

10380

else

10381

/*
We can get here for some invalid specializations.
*/

10382

return
NULL_TREE;

10383

10384

converted_args

10385

= (coerce_template_parms
(DECL_INNERMOST_TEMPLATE_PARMS
(tmpl),

10386

explicit_args,
NULL_TREE,

10387

tf_none, /*require_all_arguments=*/
0));

10388

if (converted_args ==
error_mark_node)

10389

return
NULL_TREE;

10390

10391

decl_type = tsubst
(decl_type, converted_args, tf_none, NULL_TREE);

10392

if (decl_type ==
error_mark_node)

10393

return
NULL_TREE;

10394

}

10395

10396

decl_arg_types =
TYPE_ARG_TYPES (decl_type);

10397

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

*/

10398

if
(DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))

10399

decl_arg_types =
TREE_CHAIN (decl_arg_types);

10400

10401

i = fn_type_unification
(fn, explicit_args, targs,

10402

decl_arg_types,

10403

(check_rettype ||
DECL_CONV_FN_P (fn)

10404

? TREE_TYPE
(decl_type) : NULL_TREE),

10405

deduce,
len);

10406

10407

if (i != 0)

10408

return
NULL_TREE;

10409

10410

return
targs;

10411

}

At line 10379, DECL_TI_TEMPLATE
returns the TEMPLATE_DECL instantiated or specialized by decl

. This TEMPLATE_DECL will be
the immediate parent, not the most general template. For example, in:

template
<class
T> struct
S { template
<class
U> void f(U); }

The FUNCTION_DECL for ‘S<int>::f<double>’ will have, as
its DECL_TI_TEMPLATE, `template
<class
U> S<int>::f<U>'.

As a special case, for a member friend template of a template class,
this value will not be a TEMPLATE_DECL, but rather an IDENTIFIER_NODE or
OVERLOAD indicating the name of the template and any explicit template
arguments provided. For example, in:

template
<class
T> struct
S { friend
void f<int>(int, double); }

The DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f'.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: