您的位置:首页 > 编程语言

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

域中表示我们正在全局名字空间中。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: