GCC-3.4.6源代码学习笔记(129)
2010-12-05 11:13
337 查看
5.12.5.2.2.
函数定义
–
函数体部分
5.12.5.2.2.1.
准备函数体解析
现在我们在
decl_specifiers
中得到了
return-type-specifier
,
declarator
指向
CALL_EXPR
,而
declares_class_or_enum
为
0
。记得如果我们正在定义新类型,
declares_class_or_enum
是
2
,这在
function-definition
中不被允许。
cp_parser_init_declarator (continue)
9975
/* If the
DECLARATOR was erroneous, there's no need to go
9976
further.
*/
9977
if (declarator == error_mark_node)
9978
return
error_mark_node;
9979
9980
if (declares_class_or_enum & 2)
9981
cp_parser_check_for_definition_in_return_type
9982
(declarator, TREE_VALUE
(decl_specifiers));
9983
9984
/* Figure out what
scope the entity declared by the DECLARATOR is
9985
located in. `grokdeclarator'
sometimes changes the scope, so
9986
we compute it now.
*/
9987
scope = get_scope_of_declarator (declarator);
9988
9989
/* If we're
allowing GNU extensions, look for an asm-specification
9990
and attributes.
*/
9991
if (cp_parser_allow_gnu_extensions_p
(parser))
9992
{
9993
/* Look for an
asm-specification.
*/
9994
asm_specification =
cp_parser_asm_specification_opt (parser);
9995
/* And attributes.
*/
9996
attributes = cp_parser_attributes_opt (parser);
9997
}
9998
else
9999
{
10000
asm_specification = NULL_TREE;
10001
attributes = NULL_TREE;
10002
}
10003
10004
/* Peek at the next
token.
*/
10005
token = cp_lexer_peek_token
(parser->lexer);
10006
/* Check to see if
the token indicates the start of a
10007
function-definition.
*/
10008
if (cp_parser_token_starts_function_definition_p
(token))
10009
{
10010
if (!function_definition_allowed_p)
10011
{
10012
/* If a
function-definition should not appear here, issue an
10013
error message.
*/
10014
cp_parser_error (parser,
10015
"a function-definition
is not allowed here");
10016
return
error_mark_node;
10017
}
10018
else
10019
{
10020
/* Neither
attributes nor an asm-specification are allowed
10021
on a function-definition.
*/
10022
if (asm_specification)
10023
error ("an asm-specification is
not allowed on a function-definition");
10024
if (attributes)
10025
error ("attributes are not allowed
on a function-definition");
10026
/* This is a
function-definition.
*/
10027
*function_definition_p = true;
10028
10029
/* Parse the
function definition.
*/
10030
if (member_p)
10031
decl =
cp_parser_save_member_function_body (parser,
10032
decl_specifiers,
10033
declarator,
10034
prefix_attributes);
10035
else
10036
decl
10037
= (cp_parser_function_definition_from_specifiers_and_declarator
10038
(parser, decl_specifiers,
prefix_attributes, declarator));
10039
10040
return
decl;
10041
}
10042
}
…
10197
return
decl;
10198
}
如果我们在声明符后找到“
{
”,这表示
function-definition
。我们在
10037
行继续。
14314
static
tree
14315
cp_parser_function_definition_from_specifiers_and_declarator
in parser.c
14316
(cp_parser* parser,
14317
tree decl_specifiers,
14318
tree attributes,
14319
tree declarator)
14320
{
14321
tree fn;
14322
bool success_p;
14323
14324
/* Begin the
function-definition.
*/
14325
success_p = begin_function_definition
(decl_specifiers,
14326
attributes,
14327
declarator);
首先,我们需要设立用于函数定义的框架,并把它合并入中间树。这个框架对于所有非类绑定的函数定义都是通用的。而每个定义都以自己的方式填充该框架。
1897
int
1898
begin_function_definition
(tree
decl_specs, tree attributes, tree declarator)
in parser.c
1899
{
1900
if (!start_function (decl_specs, declarator,
attributes, SF_DEFAULT))
1901
return
0;
1902
1903
/* The things we're
about to see are not directly qualified by any
1904
template headers we've seen
thus far.
*/
1905
reset_specialization ();
1906
1907
return
1;
1908
}
这里的参数
flags
具有值
SF_DEFAULT
,这表示一个普通的未解析的函数。下面的
have_extern_spec
仅在看到“
extern
”时为
true
。
10181
int
10182
start_function
(tree declspecs, tree declarator, tree attrs, int flags)
in decl.c
10183
{
10184
tree decl1;
10185
tree ctype = NULL_TREE;
10186
tree fntype;
10187
tree restype;
10188
int doing_friend = 0;
10189
struct cp_binding_level *bl;
10190
tree current_function_parms;
10191
10192
/* Sanity
check.
*/
10193
my_friendly_assert
(TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);
10194
my_friendly_assert (TREE_CHAIN
(void_list_node) == NULL_TREE, 161);
10195
10196
/* This should only
be done once on the top most decl.
*/
10197
if (have_extern_spec
)
10198
{
10199
declspecs = tree_cons (NULL_TREE,
get_identifier ("extern"), declspecs);
10200
have_extern_spec
= false;
10201
}
10202
10203
if (flags & SF_PRE_PARSED)
10204
{
...
10225
}
10226
else
10227
{
10228
decl1 = grokdeclarator (declarator,
declspecs, FUNCDEF, 1, &attrs);
因为这是未解析的函数,
FUNCTION_TYPE
及
FUNCTION_DECL
节点应该被构建,作为容器来保存以中间形式产生的定义。
6462
tree
6463
grokdeclarator
(tree declarator,
i
n decl.c
6464
tree declspecs,
6465
enum
decl_context decl_context,
6466
int initialized,
6467
tree* attrlist)
6468
{
6469
RID_BIT_TYPE specbits;
6470
int nclasses = 0;
6471
tree spec;
6472
tree type = NULL_TREE;
6473
int longlong = 0;
6474
int type_quals;
6475
int virtualp, explicitp, friendp, inlinep,
staticp;
6476
int
explicit_int = 0;
6477
int explicit_char = 0;
6478
int defaulted_int = 0;
6479
int extern_langp = 0;
6480
tree dependant_name = NULL_TREE;
6481
6482
tree typedef_decl = NULL_TREE;
6483
const
char
*name;
6484
tree typedef_type = NULL_TREE;
6485
int funcdef_flag = 0;
6486
enum
tree_code innermost_code = ERROR_MARK;
6487
int bitfield = 0;
6488
#if 0
6489
/* See the code
below that used this.
*/
6490
tree decl_attr = NULL_TREE;
6491
#endif
6492
6493
/* Keep track of
what sort of function is being processed
6494
so that we can warn about
default return values, or explicit
6495
return values which do not
match prescribed defaults.
*/
6496
special_function_kind sfk = sfk_none;
6497
6498
tree dname = NULL_TREE;
6499
tree ctype = current_class_type
;
6500
tree ctor_return_type = NULL_TREE;
6501
enum
overload_flags flags = NO_SPECIAL;
6502
tree quals = NULL_TREE;
6503
tree raises = NULL_TREE;
6504
int template_count = 0;
6505
tree in_namespace = NULL_TREE;
6506
tree returned_attrs = NULL_TREE;
6507
tree scope = NULL_TREE;
6508
tree parms = NULL_TREE;
6509
6510
RIDBIT_RESET_ALL (specbits);
6511
if (decl_context == FUNCDEF)
6512
funcdef_flag = 1, decl_context = NORMAL;
6513
else if (decl_context == MEMFUNCDEF)
6514
funcdef_flag = -1, decl_context = FIELD;
6515
else if (decl_context == BITFIELD)
6516
bitfield = 1, decl_context = FIELD;
6517
6518
/* Look inside a
declarator for the name being declared
6519
and get it as a string, for an
error message.
*/
6520
{
6521
tree *next = &declarator;
6522
tree decl;
6523
name = NULL;
6524
6525
while
(next
&& *next)
6526
{
6527
decl = *next;
6528
switch
(TREE_CODE (decl))
6529
{
...
6591
case
CALL_EXPR:
6592
innermost_code = TREE_CODE (decl);
...
6601
next = &TREE_OPERAND (decl, 0);
6602
decl = *next;
...
6610
ctype = NULL_TREE;
6611
break
;
...
6629
case
IDENTIFIER_NODE:
6630
if (TREE_CODE (decl) ==
IDENTIFIER_NODE)
6631
dname = decl;
6632
6633
next = 0;
6634
6635
if (C_IS_RESERVED_WORD (dname))
6636
{
...
6640
}
6641
else if (!IDENTIFIER_TYPENAME_P
(dname))
6642
name = IDENTIFIER_POINTER (dname);
6643
else
6644
{
...
6653
}
6654
break
;
...
6784
}
6785
}
6786
}
...
6844
for
(spec =
declspecs; spec; spec = TREE_CHAIN (spec))
6845
{
6846
int i;
6847
tree id;
6848
6849
/* Certain parse errors slip through. For
example,
6850
`int class;' is not caught
by the parser. Try
6851
weakly to recover here.
*/
6852
if (TREE_CODE (spec) != TREE_LIST)
6853
return
0;
6854
6855
id = TREE_VALUE (spec);
...
6947
if (type)
6948
error ("two or more data types in
declaration of `%s'", name);
6949
else if (TREE_CODE (id) == IDENTIFIER_NODE)
6950
{
...
6960
}
6961
else if (id != error_mark_node)
6962
/* Can't change
CLASS nodes into RECORD nodes here!
*/
6963
type = id;
6964
6965
found: ;
6966
}
6967
6968
#if 0
6969
/* See the code
below that used this.
*/
6970
if (typedef_decl)
6971
decl_attr = DECL_ATTRIBUTES (typedef_decl);
6972
#endif
6973
typedef_type = type;
...
7179
staticp = 0;
7180
inlinep = !! RIDBIT_SETP (RID_INLINE,
specbits);
7181
virtualp = RIDBIT_SETP (RID_VIRTUAL,
specbits);
7182
RIDBIT_RESET (RID_VIRTUAL, specbits);
7183
explicitp = RIDBIT_SETP (RID_EXPLICIT,
specbits) != 0;
7184
RIDBIT_RESET (RID_EXPLICIT, specbits);
仅就执行到的代码而言,我们可以看到这第一部分的处理相当简单,在
6963
行,
type
指向
integer_type_node
,其类型是
INTEGER_TYPE
。
grokdeclarator (continue)
7343
while
(declarator && TREE_CODE (declarator) != IDENTIFIER_NODE
7344
&& TREE_CODE (declarator) !=
TEMPLATE_ID_EXPR)
7345
{
...
7392
switch
(TREE_CODE (declarator))
7393
{
...
7432
case
CALL_EXPR:
7433
{
7434
tree arg_types;
7435
int funcdecl_p;
7436
tree inner_parms =
CALL_DECLARATOR_PARMS (declarator);
7437
tree inner_decl = TREE_OPERAND
(declarator, 0);
7438
7439
/* Declaring
a function type.
7440
Make sure we have a
valid type for the function to return.
*/
7441
7442
/* We now
know that the TYPE_QUALS don't apply to the
7443
decl, but to its return
type.
*/
7444
type_quals = TYPE_UNQUALIFIED;
...
7471
/* Say it's a
definition only for the CALL_EXPR
7472
closest to the
identifier.
*/
7473
funcdecl_p
7474
= inner_decl
7475
&& (TREE_CODE
(inner_decl) == IDENTIFIER_NODE
7476
|| TREE_CODE (inner_decl) ==
TEMPLATE_ID_EXPR
7477
|| TREE_CODE (inner_decl) ==
BIT_NOT_EXPR);
...
7576
/* Construct
the function type and go to the next
7577
inner layer of
declarator.
*/
7578
7579
declarator = TREE_OPERAND (declarator,
0);
7580
7581
arg_types = grokparms (inner_parms,
&parms);
7582
7583
if (declarator && flags == DTOR_FLAG)
7584
{
...
7597
}
7598
7599
/* ANSI says
that `const int foo ();'
7600
does not make the
function foo const.
*/
7601
type =
build_function_type
(type, arg_types);
7602
}
7603
break
;
...
7839
}
7840
}
因为声明符已经被验证,可以为之构建树节点了。
CALL_DECLARATOR_PARMS
提取函数的参数列表。在
7581
行,因为
inner_parms
是
void_list_node
,
grokparms
所返回的值是
NULL
。然后在
7601
行,如下的一个
FUNCTION_TYPE
被构建。
grokdeclarator (continue)
8163
{
8164
tree decl;
8165
8166
if (decl_context == PARM)
8167
{
...
8172
}
8173
else if (decl_context == FIELD)
8174
{
...
8427
}
8428
else if (TREE_CODE (type) == FUNCTION_TYPE
8429
|| TREE_CODE (type) == METHOD_TYPE)
8430
{
8431
tree original_name;
8432
int publicp = 0;
8433
8434
if (! declarator)
8435
return
NULL_TREE;
8436
8437
if (TREE_CODE (declarator) ==
TEMPLATE_ID_EXPR)
8438
original_name = dname;
8439
else
8440
original_name = declarator;
8441
8442
/* Record
presence of `static'.
*/
8443
publicp = (ctype != NULL_TREE
8444
|| RIDBIT_SETP (RID_EXTERN,
specbits)
8445
|| !RIDBIT_SETP (RID_STATIC,
specbits));
8446
8447
decl = grokfndecl (ctype, type,
original_name, parms, declarator,
8448
virtualp, flags, quals,
raises,
8449
1, friendp,
8450
publicp, inlinep,
funcdef_flag,
8451
template_count,
in_namespace);
8452
if (decl == NULL_TREE)
8453
return
NULL_TREE;
8454
8455
if (staticp == 1)
8456
{
...
8461
}
8462
}
8463
else
8464
{
...
8470
}
在这里,下面函数的参数
declarator
来自
original_name
,它在
8440
行获得其内容;而同一行的
declarator
则在
7579
行被更新为“
main
”的
IDENTIFIER_NODE
。另外,参数
parms
在
grokparms
的
7581
行得到值
NULL
。
5582
static
tree
5583
grokfndecl (tree
ctype,
in decl.c
5584
tree type,
5585
tree declarator,
5586
tree parms,
5587
tree orig_declarator,
5588
int virtualp,
5589
enum
overload_flags flags,
5590
tree quals,
5591
tree raises,
5592
int check,
5593
int friendp,
5594
int publicp,
5595
int inlinep,
5596
int funcdef_flag,
5597
int template_count,
5598
tree in_namespace)
5599
{
5600
tree decl;
5601
int staticp = ctype && TREE_CODE
(type) == FUNCTION_TYPE;
5602
int has_default_arg = 0;
5603
tree t;
5604
5605
if (raises)
5606
type = build_exception_variant (type,
raises);
5607
5608
decl = build_lang_decl
(FUNCTION_DECL, declarator, type);
5609
DECL_ARGUMENTS (decl) = parms;
5610
/* Propagate
volatile out from type to decl.
*/
5611
if (TYPE_VOLATILE (type))
5612
TREE_THIS_VOLATILE (decl) = 1;
5613
5614
/* If this decl has
namespace scope, set that up.
*/
5615
if (in_namespace)
5616
set_decl_namespace (decl, in_namespace,
friendp);
5617
else if (!ctype)
5618
DECL_CONTEXT (decl) = FROB_CONTEXT (
current_namespace
);
5619
5620
/* `main' and
builtins have implicit 'C' linkage.
*/
5621
if ((MAIN_NAME_P (declarator)
5622
|| (IDENTIFIER_LENGTH (declarator) > 10
5623
&& IDENTIFIER_POINTER
(declarator)[0] == '_'
5624
&& IDENTIFIER_POINTER
(declarator)[1] == '_'
5625
&& strncmp (IDENTIFIER_POINTER
(declarator)+2, "builtin_", 8) == 0))
5626
&& current_lang_name
== lang_name_cplusplus
5627
&& ctype == NULL_TREE
5628
/* NULL_TREE
means global namespace.
*/
5629
&& DECL_CONTEXT (decl) ==
NULL_TREE)
5630
SET_DECL_LANGUAGE
(decl, lang_c);
首先,下面的
FUNCTION_DECL
被构建。记得
null
在
context
域中表示我们正在全局名字空间中。
函数定义
–
函数体部分
5.12.5.2.2.1.
准备函数体解析
现在我们在
decl_specifiers
中得到了
return-type-specifier
,
declarator
指向
CALL_EXPR
,而
declares_class_or_enum
为
0
。记得如果我们正在定义新类型,
declares_class_or_enum
是
2
,这在
function-definition
中不被允许。
cp_parser_init_declarator (continue)
9975
/* If the
DECLARATOR was erroneous, there's no need to go
9976
further.
*/
9977
if (declarator == error_mark_node)
9978
return
error_mark_node;
9979
9980
if (declares_class_or_enum & 2)
9981
cp_parser_check_for_definition_in_return_type
9982
(declarator, TREE_VALUE
(decl_specifiers));
9983
9984
/* Figure out what
scope the entity declared by the DECLARATOR is
9985
located in. `grokdeclarator'
sometimes changes the scope, so
9986
we compute it now.
*/
9987
scope = get_scope_of_declarator (declarator);
9988
9989
/* If we're
allowing GNU extensions, look for an asm-specification
9990
and attributes.
*/
9991
if (cp_parser_allow_gnu_extensions_p
(parser))
9992
{
9993
/* Look for an
asm-specification.
*/
9994
asm_specification =
cp_parser_asm_specification_opt (parser);
9995
/* And attributes.
*/
9996
attributes = cp_parser_attributes_opt (parser);
9997
}
9998
else
9999
{
10000
asm_specification = NULL_TREE;
10001
attributes = NULL_TREE;
10002
}
10003
10004
/* Peek at the next
token.
*/
10005
token = cp_lexer_peek_token
(parser->lexer);
10006
/* Check to see if
the token indicates the start of a
10007
function-definition.
*/
10008
if (cp_parser_token_starts_function_definition_p
(token))
10009
{
10010
if (!function_definition_allowed_p)
10011
{
10012
/* If a
function-definition should not appear here, issue an
10013
error message.
*/
10014
cp_parser_error (parser,
10015
"a function-definition
is not allowed here");
10016
return
error_mark_node;
10017
}
10018
else
10019
{
10020
/* Neither
attributes nor an asm-specification are allowed
10021
on a function-definition.
*/
10022
if (asm_specification)
10023
error ("an asm-specification is
not allowed on a function-definition");
10024
if (attributes)
10025
error ("attributes are not allowed
on a function-definition");
10026
/* This is a
function-definition.
*/
10027
*function_definition_p = true;
10028
10029
/* Parse the
function definition.
*/
10030
if (member_p)
10031
decl =
cp_parser_save_member_function_body (parser,
10032
decl_specifiers,
10033
declarator,
10034
prefix_attributes);
10035
else
10036
decl
10037
= (cp_parser_function_definition_from_specifiers_and_declarator
10038
(parser, decl_specifiers,
prefix_attributes, declarator));
10039
10040
return
decl;
10041
}
10042
}
…
10197
return
decl;
10198
}
如果我们在声明符后找到“
{
”,这表示
function-definition
。我们在
10037
行继续。
14314
static
tree
14315
cp_parser_function_definition_from_specifiers_and_declarator
in parser.c
14316
(cp_parser* parser,
14317
tree decl_specifiers,
14318
tree attributes,
14319
tree declarator)
14320
{
14321
tree fn;
14322
bool success_p;
14323
14324
/* Begin the
function-definition.
*/
14325
success_p = begin_function_definition
(decl_specifiers,
14326
attributes,
14327
declarator);
首先,我们需要设立用于函数定义的框架,并把它合并入中间树。这个框架对于所有非类绑定的函数定义都是通用的。而每个定义都以自己的方式填充该框架。
1897
int
1898
begin_function_definition
(tree
decl_specs, tree attributes, tree declarator)
in parser.c
1899
{
1900
if (!start_function (decl_specs, declarator,
attributes, SF_DEFAULT))
1901
return
0;
1902
1903
/* The things we're
about to see are not directly qualified by any
1904
template headers we've seen
thus far.
*/
1905
reset_specialization ();
1906
1907
return
1;
1908
}
这里的参数
flags
具有值
SF_DEFAULT
,这表示一个普通的未解析的函数。下面的
have_extern_spec
仅在看到“
extern
”时为
true
。
10181
int
10182
start_function
(tree declspecs, tree declarator, tree attrs, int flags)
in decl.c
10183
{
10184
tree decl1;
10185
tree ctype = NULL_TREE;
10186
tree fntype;
10187
tree restype;
10188
int doing_friend = 0;
10189
struct cp_binding_level *bl;
10190
tree current_function_parms;
10191
10192
/* Sanity
check.
*/
10193
my_friendly_assert
(TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);
10194
my_friendly_assert (TREE_CHAIN
(void_list_node) == NULL_TREE, 161);
10195
10196
/* This should only
be done once on the top most decl.
*/
10197
if (have_extern_spec
)
10198
{
10199
declspecs = tree_cons (NULL_TREE,
get_identifier ("extern"), declspecs);
10200
have_extern_spec
= false;
10201
}
10202
10203
if (flags & SF_PRE_PARSED)
10204
{
...
10225
}
10226
else
10227
{
10228
decl1 = grokdeclarator (declarator,
declspecs, FUNCDEF, 1, &attrs);
因为这是未解析的函数,
FUNCTION_TYPE
及
FUNCTION_DECL
节点应该被构建,作为容器来保存以中间形式产生的定义。
6462
tree
6463
grokdeclarator
(tree declarator,
i
n decl.c
6464
tree declspecs,
6465
enum
decl_context decl_context,
6466
int initialized,
6467
tree* attrlist)
6468
{
6469
RID_BIT_TYPE specbits;
6470
int nclasses = 0;
6471
tree spec;
6472
tree type = NULL_TREE;
6473
int longlong = 0;
6474
int type_quals;
6475
int virtualp, explicitp, friendp, inlinep,
staticp;
6476
int
explicit_int = 0;
6477
int explicit_char = 0;
6478
int defaulted_int = 0;
6479
int extern_langp = 0;
6480
tree dependant_name = NULL_TREE;
6481
6482
tree typedef_decl = NULL_TREE;
6483
const
char
*name;
6484
tree typedef_type = NULL_TREE;
6485
int funcdef_flag = 0;
6486
enum
tree_code innermost_code = ERROR_MARK;
6487
int bitfield = 0;
6488
#if 0
6489
/* See the code
below that used this.
*/
6490
tree decl_attr = NULL_TREE;
6491
#endif
6492
6493
/* Keep track of
what sort of function is being processed
6494
so that we can warn about
default return values, or explicit
6495
return values which do not
match prescribed defaults.
*/
6496
special_function_kind sfk = sfk_none;
6497
6498
tree dname = NULL_TREE;
6499
tree ctype = current_class_type
;
6500
tree ctor_return_type = NULL_TREE;
6501
enum
overload_flags flags = NO_SPECIAL;
6502
tree quals = NULL_TREE;
6503
tree raises = NULL_TREE;
6504
int template_count = 0;
6505
tree in_namespace = NULL_TREE;
6506
tree returned_attrs = NULL_TREE;
6507
tree scope = NULL_TREE;
6508
tree parms = NULL_TREE;
6509
6510
RIDBIT_RESET_ALL (specbits);
6511
if (decl_context == FUNCDEF)
6512
funcdef_flag = 1, decl_context = NORMAL;
6513
else if (decl_context == MEMFUNCDEF)
6514
funcdef_flag = -1, decl_context = FIELD;
6515
else if (decl_context == BITFIELD)
6516
bitfield = 1, decl_context = FIELD;
6517
6518
/* Look inside a
declarator for the name being declared
6519
and get it as a string, for an
error message.
*/
6520
{
6521
tree *next = &declarator;
6522
tree decl;
6523
name = NULL;
6524
6525
while
(next
&& *next)
6526
{
6527
decl = *next;
6528
switch
(TREE_CODE (decl))
6529
{
...
6591
case
CALL_EXPR:
6592
innermost_code = TREE_CODE (decl);
...
6601
next = &TREE_OPERAND (decl, 0);
6602
decl = *next;
...
6610
ctype = NULL_TREE;
6611
break
;
...
6629
case
IDENTIFIER_NODE:
6630
if (TREE_CODE (decl) ==
IDENTIFIER_NODE)
6631
dname = decl;
6632
6633
next = 0;
6634
6635
if (C_IS_RESERVED_WORD (dname))
6636
{
...
6640
}
6641
else if (!IDENTIFIER_TYPENAME_P
(dname))
6642
name = IDENTIFIER_POINTER (dname);
6643
else
6644
{
...
6653
}
6654
break
;
...
6784
}
6785
}
6786
}
...
6844
for
(spec =
declspecs; spec; spec = TREE_CHAIN (spec))
6845
{
6846
int i;
6847
tree id;
6848
6849
/* Certain parse errors slip through. For
example,
6850
`int class;' is not caught
by the parser. Try
6851
weakly to recover here.
*/
6852
if (TREE_CODE (spec) != TREE_LIST)
6853
return
0;
6854
6855
id = TREE_VALUE (spec);
...
6947
if (type)
6948
error ("two or more data types in
declaration of `%s'", name);
6949
else if (TREE_CODE (id) == IDENTIFIER_NODE)
6950
{
...
6960
}
6961
else if (id != error_mark_node)
6962
/* Can't change
CLASS nodes into RECORD nodes here!
*/
6963
type = id;
6964
6965
found: ;
6966
}
6967
6968
#if 0
6969
/* See the code
below that used this.
*/
6970
if (typedef_decl)
6971
decl_attr = DECL_ATTRIBUTES (typedef_decl);
6972
#endif
6973
typedef_type = type;
...
7179
staticp = 0;
7180
inlinep = !! RIDBIT_SETP (RID_INLINE,
specbits);
7181
virtualp = RIDBIT_SETP (RID_VIRTUAL,
specbits);
7182
RIDBIT_RESET (RID_VIRTUAL, specbits);
7183
explicitp = RIDBIT_SETP (RID_EXPLICIT,
specbits) != 0;
7184
RIDBIT_RESET (RID_EXPLICIT, specbits);
仅就执行到的代码而言,我们可以看到这第一部分的处理相当简单,在
6963
行,
type
指向
integer_type_node
,其类型是
INTEGER_TYPE
。
grokdeclarator (continue)
7343
while
(declarator && TREE_CODE (declarator) != IDENTIFIER_NODE
7344
&& TREE_CODE (declarator) !=
TEMPLATE_ID_EXPR)
7345
{
...
7392
switch
(TREE_CODE (declarator))
7393
{
...
7432
case
CALL_EXPR:
7433
{
7434
tree arg_types;
7435
int funcdecl_p;
7436
tree inner_parms =
CALL_DECLARATOR_PARMS (declarator);
7437
tree inner_decl = TREE_OPERAND
(declarator, 0);
7438
7439
/* Declaring
a function type.
7440
Make sure we have a
valid type for the function to return.
*/
7441
7442
/* We now
know that the TYPE_QUALS don't apply to the
7443
decl, but to its return
type.
*/
7444
type_quals = TYPE_UNQUALIFIED;
...
7471
/* Say it's a
definition only for the CALL_EXPR
7472
closest to the
identifier.
*/
7473
funcdecl_p
7474
= inner_decl
7475
&& (TREE_CODE
(inner_decl) == IDENTIFIER_NODE
7476
|| TREE_CODE (inner_decl) ==
TEMPLATE_ID_EXPR
7477
|| TREE_CODE (inner_decl) ==
BIT_NOT_EXPR);
...
7576
/* Construct
the function type and go to the next
7577
inner layer of
declarator.
*/
7578
7579
declarator = TREE_OPERAND (declarator,
0);
7580
7581
arg_types = grokparms (inner_parms,
&parms);
7582
7583
if (declarator && flags == DTOR_FLAG)
7584
{
...
7597
}
7598
7599
/* ANSI says
that `const int foo ();'
7600
does not make the
function foo const.
*/
7601
type =
build_function_type
(type, arg_types);
7602
}
7603
break
;
...
7839
}
7840
}
因为声明符已经被验证,可以为之构建树节点了。
CALL_DECLARATOR_PARMS
提取函数的参数列表。在
7581
行,因为
inner_parms
是
void_list_node
,
grokparms
所返回的值是
NULL
。然后在
7601
行,如下的一个
FUNCTION_TYPE
被构建。
grokdeclarator (continue)
8163
{
8164
tree decl;
8165
8166
if (decl_context == PARM)
8167
{
...
8172
}
8173
else if (decl_context == FIELD)
8174
{
...
8427
}
8428
else if (TREE_CODE (type) == FUNCTION_TYPE
8429
|| TREE_CODE (type) == METHOD_TYPE)
8430
{
8431
tree original_name;
8432
int publicp = 0;
8433
8434
if (! declarator)
8435
return
NULL_TREE;
8436
8437
if (TREE_CODE (declarator) ==
TEMPLATE_ID_EXPR)
8438
original_name = dname;
8439
else
8440
original_name = declarator;
8441
8442
/* Record
presence of `static'.
*/
8443
publicp = (ctype != NULL_TREE
8444
|| RIDBIT_SETP (RID_EXTERN,
specbits)
8445
|| !RIDBIT_SETP (RID_STATIC,
specbits));
8446
8447
decl = grokfndecl (ctype, type,
original_name, parms, declarator,
8448
virtualp, flags, quals,
raises,
8449
1, friendp,
8450
publicp, inlinep,
funcdef_flag,
8451
template_count,
in_namespace);
8452
if (decl == NULL_TREE)
8453
return
NULL_TREE;
8454
8455
if (staticp == 1)
8456
{
...
8461
}
8462
}
8463
else
8464
{
...
8470
}
在这里,下面函数的参数
declarator
来自
original_name
,它在
8440
行获得其内容;而同一行的
declarator
则在
7579
行被更新为“
main
”的
IDENTIFIER_NODE
。另外,参数
parms
在
grokparms
的
7581
行得到值
NULL
。
5582
static
tree
5583
grokfndecl (tree
ctype,
in decl.c
5584
tree type,
5585
tree declarator,
5586
tree parms,
5587
tree orig_declarator,
5588
int virtualp,
5589
enum
overload_flags flags,
5590
tree quals,
5591
tree raises,
5592
int check,
5593
int friendp,
5594
int publicp,
5595
int inlinep,
5596
int funcdef_flag,
5597
int template_count,
5598
tree in_namespace)
5599
{
5600
tree decl;
5601
int staticp = ctype && TREE_CODE
(type) == FUNCTION_TYPE;
5602
int has_default_arg = 0;
5603
tree t;
5604
5605
if (raises)
5606
type = build_exception_variant (type,
raises);
5607
5608
decl = build_lang_decl
(FUNCTION_DECL, declarator, type);
5609
DECL_ARGUMENTS (decl) = parms;
5610
/* Propagate
volatile out from type to decl.
*/
5611
if (TYPE_VOLATILE (type))
5612
TREE_THIS_VOLATILE (decl) = 1;
5613
5614
/* If this decl has
namespace scope, set that up.
*/
5615
if (in_namespace)
5616
set_decl_namespace (decl, in_namespace,
friendp);
5617
else if (!ctype)
5618
DECL_CONTEXT (decl) = FROB_CONTEXT (
current_namespace
);
5619
5620
/* `main' and
builtins have implicit 'C' linkage.
*/
5621
if ((MAIN_NAME_P (declarator)
5622
|| (IDENTIFIER_LENGTH (declarator) > 10
5623
&& IDENTIFIER_POINTER
(declarator)[0] == '_'
5624
&& IDENTIFIER_POINTER
(declarator)[1] == '_'
5625
&& strncmp (IDENTIFIER_POINTER
(declarator)+2, "builtin_", 8) == 0))
5626
&& current_lang_name
== lang_name_cplusplus
5627
&& ctype == NULL_TREE
5628
/* NULL_TREE
means global namespace.
*/
5629
&& DECL_CONTEXT (decl) ==
NULL_TREE)
5630
SET_DECL_LANGUAGE
(decl, lang_c);
首先,下面的
FUNCTION_DECL
被构建。记得
null
在
context
域中表示我们正在全局名字空间中。
相关文章推荐
- GCC-3.4.6源代码学习笔记(129 续)
- GCC-3.4.6源代码学习笔记(118)
- GCC-3.4.6源代码学习笔记(147)
- GCC-3.4.6源代码学习笔记(78)
- GCC-3.4.6源代码学习笔记(44)
- GCC-3.4.6源代码学习笔记(162)
- GCC-3.4.6源代码学习笔记(29)
- GCC-3.4.6源代码学习笔记(39)
- GCC-3.4.6源代码学习笔记(153)
- GCC-3.4.6源代码学习笔记(24续)
- GCC-3.4.6源代码学习笔记(161)
- GCC-3.4.6源代码学习笔记(135)
- GCC-3.4.6源代码学习笔记(6)
- GCC-3.4.6源代码学习笔记(57)
- GCC-3.4.6源代码学习笔记(59)
- GCC-3.4.6源代码学习笔记(115)
- GCC-3.4.6源代码学习笔记(95)
- GCC-3.4.6源代码学习笔记(62)
- GCC-3.4.6源代码学习笔记(96)
- GCC-3.4.6源代码学习笔记(34)