Studying note of GCC-3.4.6 source (121)
2010-11-05 08:56
351 查看
5.12.4.2.
Parse class-head
The token follows thetemplate-parameter-list is “class” which denotes the definition/ declaration of
a class-template. Same as the previous example, along with the following call
stack: cp_parser_template_declaration_after_export
à
cp_parser_single_declaration
à
cp_parser_decl_specifier_seq
à
cp_parser_type_specifier
, keyword “class”
leads the parser to the routine cp_parser_class_specifier
.
11855
static
tree
11856
cp_parser_class_specifier
(cp_parser* parser)
in parser.c
11857
{
11858
cp_token *token;
11859
tree type;
11860
tree attributes;
11861
int has_trailing_semicolon;
11862
bool nested_name_specifier_p;
11863
unsigned saved_num_template_parameter_lists;
11864
bool pop_p = false;
11865
tree scope = NULL_TREE;
11866
11867
push_deferring_access_checks
(dk_no_deferred);
11868
11869
/* Parse the
class-head.
*/
11870
type = cp_parser_class_head (parser,
11871
&nested_name_specifier_p,
11872
&attributes);
During parsing class-specifier, access checking should be done
without deferred in general as indicated by the new inserted node of dk_no_deferred
at line 11867. However, we can see later that different access checkings may be
applied locally.
12030
static
tree
12031
cp_parser_class_head
(cp_parser* parser,
in parser.c
12032
bool*
nested_name_specifier_p,
12033
tree *attributes_p)
12034
{
12035
cp_token *token;
12036
tree nested_name_specifier;
12037
enum
tag_types class_key;
12038
tree id = NULL_TREE;
12039
tree type = NULL_TREE;
12040
tree attributes;
12041
bool template_id_p = false;
12042
bool qualified_p = false;
12043
bool invalid_nested_name_p = false;
12044
bool invalid_explicit_specialization_p =
false;
12045
bool pop_p = false;
12046
unsigned num_templates;
12047
12048
/* Assume no
nested-name-specifier will be present.
*/
12049
*nested_name_specifier_p = false;
12050
/* Assume no
template parameter lists will be used in defining the
12051
type.
*/
12052
num_templates = 0;
12053
12054
/* Look for the
class-key.
*/
12055
class_key = cp_parser_class_key (parser);
12056
if (class_key == none_type)
12057
return
error_mark_node;
12058
12059
/* Parse the
attributes.
*/
12060
attributes = cp_parser_attributes_opt (parser);
12061
12062
/* If the next
token is `::', that is invalid -- but sometimes
12063
people do try to write:
12064
12065
struct ::S {};
12066
12067
Handle this gracefully by accepting the
extra qualifier, and then
12068
issuing an error about it later if this
really is a
12069
class-head. If it turns out just to be an
elaborated type
12070
specifier, remain silent.
*/
12071
if (cp_parser_global_scope_opt
(parser, /*current_scope_valid_p=*/
false))
12072
qualified_p = true;
12073
12074
push_deferring_access_checks
(dk_no_check);
12075
12076
/* Determine the
name of the class. Begin by looking for an
12077
optional nested-name-specifier.
*/
12078
nested_name_specifier
12079
= cp_parser_nested_name_specifier_opt (parser,
12080
/*typename_keyword_p=*/
false,
12081
/*check_dependency_p=*/
false,
12082
/*type_p=*/
false,
12083
/*is_declaration=*/
false);
12084
/* If there was a
nested-name-specifier, then there *must* be an
12085
identifier.
*/
12086
if (nested_name_specifier)
12087
{
…
12143
}
12144
/* Otherwise, the
identifier is optional.
*/
12145
else
12146
{
12147
/* We don't know whether what comes next is a
template-id,
12148
an identifier, or nothing at all.
*/
12149
cp_parser_parse_tentatively
(parser);
12150
/* Check for a template-id.
*/
12151
id = cp_parser_template_id (parser,
12152
/*template_keyword_p=*/
false,
12153
/*check_dependency_p=*/
true,
12154
/*is_declaration=*/
true);
12155
/* If that didn't
work, it could still be an identifier.
*/
12156
if (!cp_parser_parse_definitely
(parser))
12157
{
12158
if (cp_lexer_next_token_is
(parser->lexer, CPP_NAME))
12159
id =
cp_parser_identifier
(parser);
12160
else
12161
id = NULL_TREE;
12162
}
12163
else
12164
{
12165
template_id_p = true;
12166
++num_templates;
12167
}
12168
}
12169
12170
pop_deferring_access_checks
();
Here, can see that at line 12074, rule of no accessing check is
added in, which adjusts the accessing check rule added by cp_parser_parse_tentatively
at line 12149 into dk_no_check too. Here token after the keyword “class” is
“SmallObject” which is an identifier and handled at line 12159 by cp_parser_identifier
.
Notice that pop_deferring_access_checks
pops the node of dk_no_checks
correspondingly.
cp_parser_class_head (continue)
12259
/* Look up the
type.
*/
12260
if (template_id_p)
12261
{
12262
type = TREE_TYPE (id);
12263
maybe_process_partial_specialization
(type);
12264
}
12265
else if (!nested_name_specifier)
12266
{
12267
/* If the class
was unnamed, create a dummy name.
*/
12268
if (!id)
12269
id = make_anon_name ();
12270
type = xref_tag
(class_key, id, /*globalize=*/
false,
12271
parser->num_template_parameter_lists);
12272
}
The processing of tokens “class SmallObject” as a class tag is exact
the same as that described in section Push tag of class
SingleThreaded
. So we just skip the detail of the handling here to avoid
unneccesary duplication.
The base class must be a defined type, finding out nodes for the
type from the class name is a complex procedure, especially the base is a class
template. Below we first have a look at class-name lookup. But before that, we
the best see how to determine the dependency of specified name.
5.12.4.2.1.
Evaluate
type dependency
5.12.4.2.1.1.
Overview
Inside a template, some constructs have semantics which may differ
from one instantiation to another. Such a construct depends on the template
parameters. In particular, types and expressions may depend on the type and/or
value of template parameters (e.g. determined by the template arguments) and which
also determines the context for name lookup for the names. Expressions may be
type-dependent (on the type of a template parameter) or value-dependent (on the
value of a non-type template parameter). In an expression of the form:
postfix-expression
( expression-list opt )
where the
postfix-expression is an identifier, the identifier denotes a dependent name if
and only if any of the expressions in the expression-list is a type-dependent
expression (14.6.2.2). If an operand of an
operator is a type-dependent expression, the operator also denotes a dependent
name. Such names are unbound and are looked up at the point of the template
instantiation (14.6.4.1) in both the context of the template definition and the
context of the point of instantiation.
[Example:
template
<class T> struct
X : B<T> {
typename
T::A* pa;
void
f(B<T>* pb) {
static
int i = B<T>::i;
pb->j++;
}
};
the base class name
B<T>, the type name T::A, the names B<T>::i and pb->j explicitly
depend on the template-parameter.
In the
definition of a class template or a member of a class template, if a base class
of the class template depends on a template-parameter, the base class scope is
not examined during unqualified name lookup either at the point of definition
of the class template or member or during an instantiation of the class
template or member. [Example:
typedef
double A;
template
<class
T> class
B {
typedef
int A;
};
template
<class T> struct
X : B<T> {
A a; // a has type double
};
The type name A in the definition of X<T> binds to the typedef
name defined in the global namespace scope, not to the typedef name defined in
the base class B<T>. [Example:
struct
A {
struct
B { /*
... */
};
int a;
int Y;
};
int a;
template
<class
T> struct
Y : T {
struct
B { /*
... */
};
B b; // The B defined in Y
void f(int i) {
a = i; } // ::a
Y* p; // Y<T>
};
Y<A> ya;
The members A::B, A::a,
and A::Y of the template argument A do not affect the binding of names in Y<A>.
5.12.4.2.1.2.
Type
dependent
Routine type_dependent_expression_p
returns true if
the expression
is type-dependent.
11966
bool
11967
type_dependent_expression_p
(tree expression)
in pt.c
11968
{
11969
if (!processing_template_decl
)
11970
return
false;
11971
11972
if (expression ==
error_mark_node)
11973
return
false;
11974
11975
/*
An unresolved name is always dependent.
*/
11976
if (TREE_CODE (expression)
== IDENTIFIER_NODE)
11977
return
true;
As we know
when parser find an identifier, it always try to look it up to find out the
declaration currently bound with the name. This declaration is the object used
in current scope. But if the identifier hasn’t visible binding in current
scope, the parser only uses the IDENTIFIER_NODE. Takes above example as
instance:
template
<class T> struct
X : B<T> {
typename
T::A* pa;
In “T::A”, the “A” at here
should only be IDENTIFIER_NODE.
type_dependent_expression_p (continue)
11979
/* Some expression forms are never
type-dependent.
*/
11980
if (TREE_CODE (expression)
== PSEUDO_DTOR_EXPR
11981
|| TREE_CODE
(expression) == SIZEOF_EXPR
11982
|| TREE_CODE
(expression) == ALIGNOF_EXPR
11983
|| TREE_CODE
(expression) == TYPEID_EXPR
11984
|| TREE_CODE
(expression) == DELETE_EXPR
11985
|| TREE_CODE
(expression) == VEC_DELETE_EXPR
11986
|| TREE_CODE
(expression) == THROW_EXPR)
11987
return
false;
11988
11989
/*
The types of these expressions depends only on the type to which
11990
the
cast occurs.
*/
11991
if (TREE_CODE (expression)
== DYNAMIC_CAST_EXPR
11992
|| TREE_CODE
(expression) == STATIC_CAST_EXPR
11993
|| TREE_CODE
(expression) == CONST_CAST_EXPR
11994
|| TREE_CODE
(expression) == REINTERPRET_CAST_EXPR
11995
|| TREE_CODE
(expression) == CAST_EXPR)
11996
return
dependent_type_p
(TREE_TYPE (expression));
11997
11998
/* The
types of these expressions depends only on the type created
11999
by the
expression.
*/
12000
if (TREE_CODE (expression)
== NEW_EXPR
12001
|| TREE_CODE
(expression) == VEC_NEW_EXPR)
12002
{
12003
/*
For NEW_EXPR tree nodes created inside a template, either
12004
the object type itself or a TREE_LIST may
appear as the
12005
operand 1.
*/
12006
tree type = TREE_OPERAND
(expression, 1);
12007
if (TREE_CODE (type) ==
TREE_LIST)
12008
/*
This is an array type. We need to check array dimensions
12009
as
well.
*/
12010
return
dependent_type_p
(TREE_VALUE
(TREE_PURPOSE (type)))
12011
|| value_dependent_expression_p
12012
(TREE_OPERAND (TREE_VALUE
(type), 1));
12013
else
12014
return
dependent_type_p
(type);
12015
}
12016
12017
if (TREE_CODE (expression)
== SCOPE_REF
12018
&& dependent_scope_ref_p
(expression,
12019
type_dependent_expression_p))
12020
return
true;
12021
12022
if (TREE_CODE (expression)
== FUNCTION_DECL
12023
&&
DECL_LANG_SPECIFIC (expression)
12024
&&
DECL_TEMPLATE_INFO (expression)
12025
&& (any_dependent_template_arguments_p
12026
(INNERMOST_TEMPLATE_ARGS
(DECL_TI_ARGS (expression)))))
12027
return
true;
12028
12029
if (TREE_CODE (expression)
== TEMPLATE_DECL
12030
&&
!DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
12031
return
false;
Accoding to
[3], following forms are never type-dependent.
literal
postfix-expression.pseduo-destructor-name
postfix-expression->pseduo-destructor-name
sizeof
unary-expression
sizeof
(type-id)
typeid
(expression)
typeid
(type-id)
::opt
delete cast-expression
::opt
delete[] cast-expression
throw
assignment-expression opt
As types of those
expressions are not dependent. For example, sizeof always of type size_t. The
GNU extension operator alignof
is
also within the group (it is of type size_t too).
Then an id-expression
is type-dependent if it
contains:
an identifier
that was declared with a
dependent type
a template-id
that is dependent
a conversion-function-id
that specifies a
dependent type
a nested-name-specifier
that contains a
class-name that names a dependent type
Expression of the following forms are type-dependent only if the
type specified by the type-id
, simple-type-specifier
or new-type-id
is dependent, even if any
subexpression is type-dependent:
simple-type-specifier
(expression-list opt
)
::opt
new new-placement opt
new-type-id
new-initializer opt
::opt
new new-placement opt
(type-id
)
new-initializer opt
dynamic_cast
<type-id
> (expression)
static_cast
<type-id
> (expression)
const_cast
<type-id
> (expression)
reinterpret_cast
<type-id
> (expression)
(type-id
) cast-expression
The core of above rules is to check type-dependence of types
contained by the expression. Above at line 12000, note that for new-type-id
, the grammar for it is:
new-type-id
type-specifier-seq new-declarator opt
new-declarator:
ptr-operator new-declarator opt
direct-new-declarator
direct-new-declarator:
[expression]
direct-new-declarator [constant-expression]
For this case, the operand
at position 1 (starts from 0) of tree node of NEW_EXPR/ VEC_NEW_EXPR is the new-type-id
which is a tree_list
,
with type-specifier-seq
at the purpose
slot and new-declarator
at the value
slot. If new-declarator
deriving direct-new-declarator
, it is the node of
ARRAY_REF, with direct-new-declarator
of sub-dimension as operand 0, and expression for the size of dimension as
operand 1. Obvious if this expression is value-dependent, new-type-id
is type-dependent too.
Then dependent_type_p
validates whether type
passed in is template parameter dependent.
11786
bool
11787
dependent_type_p
(tree type)
in
pt.c
11788
{
11789
/*
If there are no template parameters in scope, then there can't be
11790
any
dependent types.
*/
11791
if (!processing_template_decl
)
11792
return
false;
11793
11794
/*
If the type is NULL, we have not computed a type for the entity
11795
in
question; in that case, the type is dependent.
*/
11796
if (!type)
11797
return
true;
11798
11799
/* Erroneous types can be considered
non-dependent.
*/
11800
if (type == error_mark_node)
11801
return
false;
11802
11803
/* If we have not already computed the
appropriate value for TYPE,
11804
do so
now.
*/
11805
if (!TYPE_DEPENDENT_P_VALID
(type))
11806
{
11807
TYPE_DEPENDENT_P (type) = dependent_type_p_r
(type);
11808
TYPE_DEPENDENT_P_VALID
(type) = 1;
11809
}
11810
11811
return
TYPE_DEPENDENT_P (type);
11812
}
To accelerate compiling speed, some type if has been evaluated, slot
lang_flag_6
of the tree type node is set (TYPE_DEPENDENT_P_VALID) and the result is set in lang_flag_0
slot (TYPE_DEPENDENT_P).
A type is
dependent if it is:
1) A template parameter.
2) A qualified-id
with a nested-name-specifier which contains a class-name that names a dependent
type or whose unqualified-id names a dependent type.
3) A cv-qualified
type where the cv-unqualified type is dependent.
4) A compound type
constructed from any dependent type.
5) An array type
constructed from any dependent type or whose size is specified by a constant
expression that is value-dependent.
6) A template-id in
which either the template name is a template parameter or any of the template
arguments is a dependent type or an expression that is type-dependent or
value-dependent.
Below, TEMPLATE_TYPE_PARM
is the node for template parameter, and that parameter being template itself is
the node of TEMPLATE_TEMPLATE_PARM.
Then according to ISO-IE-14882-2003, 14.6 name resolution:
A name used in a template
declaration or definition and that is dependent on a template parameter is
assumed not to name a type unless the applicable name lookup finds a type name
or the name is qualified by the keyword typename.
For example:
// no B declared here
class
X;
template
<class
T> class
Y {
class
Z;
// forward
declaration of member class
void f() {
X* a1;
// declare pointer to X
T* a2;
// declare pointer to T
Y* a3;
// declare pointer to Y
Z* a4;
// declare pointer to Z
typedef
typename
T::A TA;
TA* a5;
// declare pointer to T’s A
typename
T::A* a6;
//
declare pointer to T’s A
T::A* a7;
// T::A is not a type name:
mulitply T::A by a7;
// ill-formed, no visible declaration of a7
B* a8;
// multiply B by a8; ill-formed, no
visible declaration of B and a8
}
};
A qualified-name that refers to
a type and that depends on a template-parameter shall be prefixed by the
keyword typename
to indicate that the qualified-name denotes a type, forming an elaborated-type
specifier.
elaborated-type-specifier:
typename
::opt
nested-name-specifier identifier
typename
::opt
nested-name-specifier identifer <template-argument-list>
The keyword typename
shall only be used in template declarations and definitions, including in the
return type of a function template or member function template, in the return
type for the definition of a member function of a class template or of a class
nested within a class template, and in the type-specifier for the definition of
a static member of a class template or of a class nested within a class
template. The keyword typename
shall only be applied to qualified
names, but those names need not be dependent. The keyword typename
is not premitted in a
base-specifier or in a mem-initializer; in these contexts a qualified-name that
depends on a template-parameter is implicitly assumed to be a type name.
Within the definition of a
class template or within the definition of a member of a class template, the
keyword typename
is not required when referring to the unqualified name of a previously declared
member of the class template that declares the type. The keyword typename
shall always be specified when the member is referred to using a qualified
name, even if the qualifier is simply the class template name.
For example:
template
<class
T> struct
A {
typedef
int B;
A::B b;
// ill-formed: typename required before A::B
void f(A<T>::B);
// ill-formed:
typename required before A<T>::B
typename
A::B g();
// OK
};
The keyword typename
is required whether the qualified name is A or A<T> because A or
A<T> are synoyms within a class template with the parameter list
<T>.
With above description, if a template is declared correctly, keyword
typename
always indicates a dependent type. So below at line 11704, if we see typename
,
we can assume type dependency safely and vice versa (if the template declared
wrong, for example typename
missed, error will be generated in later
parsing). Function dependent_type_p_r
does the checking.
11686
static
bool
11687
dependent_type_p_r
(tree type)
in
pt.c
11688
{
11689
tree scope;
11690
11691
/*
[temp.dep.type]
11692
11693
A
type is dependent if it is:
11694
11695
-- a
template parameter. Template template parameters are
11696
types
for us (since TYPE_P holds true for them) so we
11697
handle
them here.
*/
11698
if (TREE_CODE (type) ==
TEMPLATE_TYPE_PARM
11699
|| TREE_CODE (type) ==
TEMPLATE_TEMPLATE_PARM)
11700
return
true;
11701
/*
-- a qualified-id with a nested-name-specifier which contains a
11702
class-name that names a dependent type or
whose unqualified-id
11703
names
a dependent type.
*/
11704
if (TREE_CODE (type) ==
TYPENAME_TYPE)
11705
return
true;
11706
/*
-- a cv-qualified type where the cv-unqualified type is
11707
dependent.
*/
11708
type = TYPE_MAIN_VARIANT
(type);
11709
/*
-- a compound type constructed from any dependent type.
*/
11710
if (TYPE_PTR_TO_MEMBER_P
(type))
11711
return
(dependent_type_p
(TYPE_PTRMEM_CLASS_TYPE
(type))
11712
|| dependent_type_p
(TYPE_PTRMEM_POINTED_TO_TYPE
11713
(type)));
11714
else if (TREE_CODE (type) ==
POINTER_TYPE
11715
|| TREE_CODE (type) == REFERENCE_TYPE)
11716
return
dependent_type_p
(TREE_TYPE (type));
11717
else if (TREE_CODE (type) ==
FUNCTION_TYPE
11718
|| TREE_CODE (type) == METHOD_TYPE)
11719
{
11720
tree arg_type;
11721
11722
if (dependent_type_p
(TREE_TYPE (type)))
11723
return
true;
11724
for
(arg_type = TYPE_ARG_TYPES (type);
11725
arg_type;
11726
arg_type = TREE_CHAIN
(arg_type))
11727
if (dependent_type_p
(TREE_VALUE (arg_type)))
11728
return
true;
11729
return
false;
11730
}
Above at line 11710, TYPE_PTR_TO_MEMBER_P
is nonzero, if type
is a pointer to data member or method of a class. While for type T X::*
, TYPE_PTRMEM_CLASS_TYPE
returns X
,
and TYPE_PTRMEM_CLASS_TYPE
returns T.
For FUNCTION_DECL
(function)
or METHOD_DECL
(method of class), TREE_TYPE
returns the returned type,
and TREE_ARG_TYPE
returns the list
of argument types.
dependent_type_p_r (continue)
11731
/*
-- an array type constructed from any dependent type or whose
11732
size
is specified by a constant expression that is
11733
value-dependent.
*/
11734
if (TREE_CODE (type) ==
ARRAY_TYPE)
11735
{
11736
if (TYPE_DOMAIN (type)
11737
&& ((value_dependent_expression_p
11738
(TYPE_MAX_VALUE
(TYPE_DOMAIN (type))))
11739
|| (type_dependent_expression_p
11740
(TYPE_MAX_VALUE
(TYPE_DOMAIN (type))))))
11741
return
true;
11742
return
dependent_type_p
(TREE_TYPE (type));
11743
}
The type of boundary of an array is accessed by TYPE_DOMAIN
, and the upper and lower bounds can be visited by TYPE_MAX_VALUE
and TYPE_MIN_VALUE
respectively.
In above type dependent condition, by 5th
clause, an
array is type dependent if its size is specified by a constant expression that
is value-dependent.
5.12.4.2.1.3.
Value
dependent
Value-dependent expression should be:
Except as described below, a
constant expression is value-dependent if any subexpression is value-dependent.
An identifier is
value-dependent if it is:
A name declared with a dependent type.
The name of a non-type template parameter.
A constant with integral or enumeration type and is initialized with
an expression that is value-dependent.
Expression of the following
form are value-dependent if the unary-expression
is type-dependent or the type-id
is
dependent (even if sizeof unary-expression and sizeof (type-id) are not
type-dependent): sizeof unary-expression,
sizeof (type-id)
.
Expressions of the following
form are value-dependent if either the type-id
or simple-type-specifier
is dependent
or the expression
or cast-expression
is value-dependent:
simple-type-specifier
(expression-list opt
)
static_cast
<type-id> (expression)
const_cast
<type-id> (expression)
reinterpret_cast
<type-id> (expression)
(type-id)
cast-expression
11851
bool
11852
value_dependent_expression_p
(tree expression)
in
pt.c
11853
{
11854
if (!processing_template_decl
)
11855
return
false;
11856
11857
/*
A name declared with a dependent type.
*/
11858
if (TREE_CODE (expression)
== IDENTIFIER_NODE
11859
|| (DECL_P (expression)
11860
&& type_dependent_expression_p
(expression)))
11861
return
true;
11862
/*
A non-type template parameter.
*/
11863
if ((TREE_CODE (expression)
== CONST_DECL
11864
&&
DECL_TEMPLATE_PARM_P (expression))
11865
|| TREE_CODE (expression)
== TEMPLATE_PARM_INDEX)
11866
return
true;
11867
/*
A constant with integral or enumeration type and is initialized
11868
with
an expression that is value-dependent.
*/
11869
if (TREE_CODE (expression)
== VAR_DECL
11870
&& DECL_INITIAL
(expression)
11871
&&
INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (expression))
11872
&& value_dependent_expression_p
(DECL_INITIAL (expression)))
11873
return
true;
11874
/*
These expressions are value-dependent if the type to which the
11875
cast
occurs is dependent or the expression being casted is
11876
value-dependent.
*/
11877
if (TREE_CODE (expression)
== DYNAMIC_CAST_EXPR
11878
|| TREE_CODE
(expression) == STATIC_CAST_EXPR
11879
|| TREE_CODE
(expression) == CONST_CAST_EXPR
11880
|| TREE_CODE
(expression) == REINTERPRET_CAST_EXPR
11881
|| TREE_CODE
(expression) == CAST_EXPR)
11882
{
11883
tree type = TREE_TYPE
(expression);
11884
if (dependent_type_p
(type))
11885
return
true;
11886
/* A functional cast has a list of
operands.
*/
11887
expression = TREE_OPERAND
(expression, 0);
11888
if (!expression)
11889
{
11890
/*
If there are no operands, it must be an expression such
11891
as
"int()". This should not happen for aggregate types
11892
because it would form non-constant
expressions.
*/
11893
my_friendly_assert
(INTEGRAL_OR_ENUMERATION_TYPE_P (type),
11894
20040318);
11895
11896
return
false;
11897
}
11898
if (TREE_CODE (expression)
== TREE_LIST)
11899
{
11900
do
11901
{
11902
if (value_dependent_expression_p
(TREE_VALUE (expression)))
11903
return
true;
11904
expression =
TREE_CHAIN (expression);
11905
}
11906
while
(expression);
11907
return
false;
11908
}
11909
else
11910
return
value_dependent_expression_p
(expression);
11911
}
11912
/*
A `sizeof' expression is value-dependent if the operand is
11913
type-dependent.
*/
11914
if (TREE_CODE (expression)
== SIZEOF_EXPR
11915
|| TREE_CODE
(expression) == ALIGNOF_EXPR)
11916
{
11917
expression = TREE_OPERAND
(expression, 0);
11918
if (TYPE_P (expression))
11919
return
dependent_type_p
(expression);
11920
return
type_dependent_expression_p
(expression);
11921
}
11922
if (TREE_CODE (expression)
== SCOPE_REF)
11923
return
dependent_scope_ref_p
(expression, value_dependent_expression_p
);
11924
if (TREE_CODE (expression)
== COMPONENT_REF)
11925
return
(value_dependent_expression_p
(TREE_OPERAND (expression, 0))
11926
|| value_dependent_expression_p
(TREE_OPERAND (expression, 1)));
11927
/*
A constant expression is value-dependent if any subexpression is
11928
value-dependent.
*/
11929
if (IS_EXPR_CODE_CLASS
(TREE_CODE_CLASS (TREE_CODE (expression))))
11930
{
11931
switch
(TREE_CODE_CLASS (TREE_CODE (expression)))
11932
{
11933
case
'1':
11934
return
(value_dependent_expression_p
11935
(TREE_OPERAND
(expression, 0)));
11936
case
'<':
11937
case
'2':
11938
return
((value_dependent_expression_p
11939
(TREE_OPERAND
(expression, 0)))
11940
|| (value_dependent_expression_p
11941
(TREE_OPERAND
(expression, 1))));
11942
case
'e':
11943
{
11944
int i;
11945
for
(i = 0; i < first_rtl_op (TREE_CODE
(expression)); ++i)
11946
/* In some cases,
some of the operands may be missing.
11947
(For example, in the case of
PREDECREMENT_EXPR, the
11948
amount to increment by may be
missing.) That doesn't
11949
make the expression dependent.
*/
11950
if (TREE_OPERAND
(expression, i)
11951
&& (value_dependent_expression_p
11952
(TREE_OPERAND (expression,
i))))
11953
return
true;
11954
return
false;
11955
}
11956
}
11957
}
11958
11959
/*
The expression is not value-dependent.
*/
11960
return
false;
11961
}
Two cases
derived from above rules need further consideration. At line 11922, node of
SCOPE_REF has the class (type) as operand 0, and the field as operand 1. For
example: it is used to hold A::i below (see that the expression is
value-dependent).
template
<typename
T> struct
A {
static
const
int i = sizeof
(T);
};
A::i;
While COMPONENT_REF has the object in operand 0, and field in
operand 1. For example: it is used to hold a.i below (a.i is also
value-dependent as i is declared with dependent type).
template
<typename
T> struct
A {
T i;
};
template
<typename
V> void f (A<V>& a, V value) {
a.i = value;
}
For node of SCOPE_REF, dependent_scope_ref_p
verifies it being dependent or not. Notice that argument criterion
refers to value_dependent_expression_p
.
11816
static
bool
11817
dependent_scope_ref_p
(tree expression,
bool criterion (tree))
in
pt.c
11818
{
11819
tree scope;
11820
tree name;
11821
11822
my_friendly_assert
(TREE_CODE (expression) == SCOPE_REF, 20030714);
11823
11824
if (!TYPE_P (TREE_OPERAND
(expression, 0)))
11825
return
true;
11826
11827
scope = TREE_OPERAND
(expression, 0);
11828
name = TREE_OPERAND
(expression, 1);
11829
11830
/* [temp.dep.expr]
11831
11832
An
id-expression is type-dependent if it contains a
11833
nested-name-specifier that contains a
class-name that names a
11834
dependent type.
*/
11835
/* The
suggested resolution to Core Issue 2 implies that if the
11836
qualifying type is the current class, then
we must peek
11837
inside
it.
*/
11838
if (DECL_P (name)
11839
&&
currently_open_class (scope)
11840
&& !criterion
(name))
11841
return
false;
11842
if (dependent_type_p
(scope))
11843
return
true;
11844
11845
return
false;
11846
}
Considering
condition at line 11838, takes below example,
template
<typename
T> struct
A {
int j;
};
When parsing member j
within
class A, j
should not be considered type/value dependent within the scope, but is if
viewed from outside of the class.
Further, considering
following example:
template
<typename
T> struct
A{
typedef
T innerType;
innerType j;
};
A<int>::innerType
intType;
A<T>::innerType
aType
intType
(A<int>::innerType)
is not value-dependent. But aType
(A<T>::innerType) is.
dependent_type_p_r (continue)
11745
/*
-- a template-id in which either the template name is a template
11746
parameter ...
*/
11747
if (TREE_CODE (type) ==
BOUND_TEMPLATE_TEMPLATE_PARM)
11748
return
true;
11749
/*
... or any of the template arguments is a dependent type or
11750
an
expression that is type-dependent or value-dependent.
*/
11751
else if (CLASS_TYPE_P (type)
&& CLASSTYPE_TEMPLATE_INFO (type)
11752
&& (any_dependent_template_arguments_p
11753
(INNERMOST_TEMPLATE_ARGS
(CLASSTYPE_TI_ARGS (type)))))
11754
return
true;
11755
11756
/*
All TYPEOF_TYPEs are dependent; if the argument of the `typeof'
11757
expression is not type-dependent, then it
should already been
11758
have
resolved.
*/
11759
if (TREE_CODE (type) ==
TYPEOF_TYPE)
11760
return
true;
11761
11762
/*
The standard does not specifically mention types that are local
11763
to
template functions or local classes, but they should be
11764
considered dependent too. For example:
11765
11766
template <int I> void f() {
11767
enum E { a = I };
11768
S<sizeof (E)> s;
11769
}
11770
11771
The size of `E' cannot be known until the
value of `I' has been
11772
determined. Therefore, `E' must be
considered dependent.
*/
11773
scope = TYPE_CONTEXT (type);
11774
if (scope && TYPE_P
(scope))
11775
return
dependent_type_p
(scope);
11776
else if (scope &&
TREE_CODE (scope) == FUNCTION_DECL)
11777
return
type_dependent_expression_p
(scope);
11778
11779
/*
Other types are non-dependent.
*/
11780
return
false;
11781
}
For condition
“a template-id in which either the
template name is a template parameter or any of the template arguments is a
dependent type or an expression that is type-dependent or value-dependent
”,
considers following examples:
Example 1:
template
<class
T> struct
Temp {
int t;
};
template
<template
<class
U> class
T, typename
X, typename
V = T<X> > struct
A {
V func;
};
int main() {
A<Temp, int> a;
a.func.t = 0;
return
1;
}
Type Temp is used as the default argument which is dependent on
template-parameter X (it is the case template name is a template parameter).
Example 2:
template
<class
T> struct
Temp {
T t;
};
template<typename
T> struct
A {
Temp<T> func;
};
int main() {
A<int> a;
a.func.t = 0;
return
1;
}
Template Temp being a class member of A, accepts dependent type T.
In this case, Temp’s definition contains one level of template argument (T).
For template related tree nodes, refers to macros accessing template definition
.
It just tests innermost template argument because ISO-IE-14882-2003 defines
that:
I n an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. In such explicit specialization declaration, the keyword template followed by a template-parameter-list shall be provided instead of the template<> preceding the explicit specialization declaration of the member. The types of the template-parameters in the template-parameter-list shall be the same as those specified in the primary template definition. [Example: template <class T1> class A { template <class T2> class B { template <class T3> void mf1(T3); void mf2(); }; }; template <> template <class X> class A<int>::B { }; template <> template <> template <class T> void A<int>::B<double>::mf1(T t) { } template <class Y> template <> void A<Y>::B<double>::mf2() { } // ill-formed; B<double> is specialized but // its enclosing class template A is not |
can evaluate the template argument vector though here the vector only contains
the innermost arguments.
12116
bool
12117
any_dependent_template_arguments_p
(tree args)
in
pt.c
12118
{
12119
int i;
12120
int j;
12121
12122
if (!args)
12123
return
false;
12124
12125
for
(i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
12126
{
12127
tree level =
TMPL_ARGS_LEVEL (args, i + 1);
12128
for
(j = 0; j < TREE_VEC_LENGTH (level); ++j)
12129
if (dependent_template_arg_p
(TREE_VEC_ELT
(level, j)))
12130
return
true;
12131
}
12132
12133
return
false;
12134
}
Checking whether argument is dependent or not is quite similar with
type declaration.
12097
static
bool
12098
dependent_template_arg_p
(tree arg)
in
pt.c
12099
{
12100
if (!processing_template_decl
)
12101
return
false;
12102
12103
if (TREE_CODE (arg) ==
TEMPLATE_DECL
12104
|| TREE_CODE (arg) ==
TEMPLATE_TEMPLATE_PARM)
12105
return
dependent_template_p
(arg);
12106
else if (TYPE_P (arg))
12107
return
dependent_type_p
(arg);
12108
else
12109
return
(type_dependent_expression_p
(arg)
12110
|| value_dependent_expression_p
(arg));
12111
}
Here notice that only node of TEMPLATE_TEMPLATE_PARM or
TEMPLATE_DECL will be handled by dependent_template_p
. See that if
TEMPLATE_DECL is not used as template parameter (that is condition at line
12153 is not satisfied) and it is not contained within dependent scope, the
TEMPLATE_DECL is not regarded as dependent (ISO-IE-14882-2003 [temp.dep.type],
a template-id in which either the template name is a template
parameter or any of the template arguments is a dependent type or an expression
that is type-dependent or value-dependent).
12138
bool
12139
dependent_template_p
(tree tmpl)
in
pt.c
12140
{
12141
if (TREE_CODE (tmpl) ==
OVERLOAD)
12142
{
12143
while
(tmpl)
12144
{
12145
if (dependent_template_p
(OVL_FUNCTION (tmpl)))
12146
return
true;
12147
tmpl = OVL_CHAIN (tmpl);
12148
}
12149
return
false;
12150
}
12151
12152
/*
Template template parameters are dependent.
*/
12153
if
(DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)
12154
|| TREE_CODE (tmpl) ==
TEMPLATE_TEMPLATE_PARM)
12155
return
true;
12156
/*
So are names that have not been looked up.
*/
12157
if (TREE_CODE (tmpl) ==
SCOPE_REF
12158
|| TREE_CODE (tmpl) ==
IDENTIFIER_NODE)
12159
return
true;
12160
/*
So are member templates of dependent classes.
*/
12161
if (TYPE_P (CP_DECL_CONTEXT
(tmpl)))
12162
return
dependent_type_p
(DECL_CONTEXT (tmpl));
12163
return
false;
12164
}
See that if function template is found as overloaded function, it is
a tree node of OVERLOAD which wraps TEMPLATE_DECL by OVL_FUNCTION, so dependent_template_p
at line 12145 will find out this function template.
Special unknown_type_node
is used as type for overload
functions/methods.
type_dependent_expression_p
(continue)
12033
if (TREE_TYPE (expression)
== unknown_type_node)
12034
{
12035
if (TREE_CODE (expression)
== ADDR_EXPR)
12035
return
type_dependent_expression_p
(TREE_OPERAND (expression, 0));
12037
if (TREE_CODE (expression)
== COMPONENT_REF
12038
|| TREE_CODE
(expression) == OFFSET_REF)
12039
{
12040
if (type_dependent_expression_p
(TREE_OPERAND (expression, 0)))
12041
return
true;
12042
expression =
TREE_OPERAND (expression, 1);
12043
if (TREE_CODE
(expression) == IDENTIFIER_NODE)
12044
return
false;
12045
}
12046
/*
SCOPE_REF with non-null TREE_TYPE is always non-dependent.
*/
12047
if (TREE_CODE (expression)
== SCOPE_REF)
12048
return
false;
12049
12050
if (TREE_CODE (expression)
== BASELINK)
12051
expression =
BASELINK_FUNCTIONS (expression);
12052
if (TREE_CODE (expression)
== TEMPLATE_ID_EXPR)
12053
{
12054
if (any_dependent_template_arguments_p
12055
(TREE_OPERAND
(expression, 1)))
12056
return
true;
12057
expression =
TREE_OPERAND (expression, 0);
12058
}
12059
if (TREE_CODE (expression)
== OVERLOAD
12060
|| TREE_CODE
(expression) == FUNCTION_DECL)
12061
{
12062
while
(expression)
12063
{
12064
if (type_dependent_expression_p
(OVL_CURRENT (expression)))
12065
return
true;
12066
expression = OVL_NEXT
(expression);
12067
}
12068
return
false;
12069
}
12070
abort ();
12071
}
12072
12073
my_friendly_assert
(TREE_CODE (expression) != TYPE_DECL, 20051116);
12074
12075
return
(dependent_type_p
(TREE_TYPE (expression)));
12076
}
Above code continue to check type-dependency. See line 12043, for
name unsolved within an independent scope, simply regards it as independent
(except the error case, I can’t think out the correct one). Otherwise, goes
with code below line 12047 continue to check the operand 1.
相关文章推荐
- Studying note of GCC-3.4.6 source (110)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (146)
- Studying note of GCC-3.4.6 source (19)
- Studying note of GCC-3.4.6 source (34)
- Studying note of GCC-3.4.6 source (50)
- Studying note of GCC-3.4.6 source (53)
- Studying note of GCC-3.4.6 source (56)
- Studying note of GCC-3.4.6 source (139 - cont 2)
- Studying note of GCC-3.4.6 source (142)
- Studying note of GCC-3.4.6 source (19 cont)
- Studying note of GCC-3.4.6 source (154)
- Studying note of GCC-3.4.6 source (165)
- Studying note of GCC-3.4.6 source (29)
- Studying note of GCC-3.4.6 source (168)
- Studying note of GCC-3.4.6 source (175)
- Studying note of GCC-3.4.6 source (181)
- Studying note of GCC-3.4.6 source (48)
- Studying note of GCC-3.4.6 source (57)