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

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

2010-12-15 10:13 363 查看
5.12.5.2.2.2.1.2.


构建

VAR_DECL


接下来在
cp_parser_simple_declaration

中,调用
cp_parser_init_declarator

来解析声明符部分。调用栈
cp_parser_declarator

à

cp_parser_direct_declarator

à

cp_parser_declarator_id

à

cp_parser_id_expression

à

cp_parser_unqualified_id

à

cp_parser_identifier

,为“
object_
”构建了一个
IDENTIFIER_NODE
。接着在
cp_parser_init_declarator

中,以下代码片段将被执行。

cp_parser_init_declarator (continue)

10095

/* Enter the newly
declared entry in the symbol table. If we're

10096

processing a declaration in a
class-specifier, we wait until

10097

after processing the initializer.
*/

10098

if (!member_p)

10099

{

10100

if
(parser->in_unbraced_linkage_specification_p)

10101

{

10102

decl_specifiers = tree_cons
(error_mark_node,

10103

get_identifier
("extern"),

10104

decl_specifiers);

10105

have_extern_spec

= false;

10106

}

10107

decl = start_decl
(declarator, decl_specifiers,

10108

is_initialized, attributes,
prefix_attributes);

10109

}


SmallObject<> object_
”是一个变量声明。一个新的树节点需要在中间树中创建来代表这个实体。在这次调用中,实参
intialized


false

attributes


prefix_attributes

都是
NULL


3670

tree

3671

start_decl

(tree declarator,

in decl.c

3672

tree declspecs,

3673

int initialized,

3674

tree attributes,

3675

tree prefix_attributes)

3676

{

3677

tree decl;

3678

tree type, tem;

3679

tree context;

3680

3681

/* This should only
be done once on the top most decl.
*/

3682

if (have_extern_spec

)

3683

{

3684

declspecs = tree_cons (NULL_TREE,
get_identifier ("extern"),

3685

declspecs);

3686

have_extern_spec

= false;

3687

}

3688

3689

/* An object
declared as __attribute__((deprecated)) suppresses

3690

warnings of uses of other
deprecated items.
*/

3691

if (lookup_attribute ("deprecated",
attributes))

3692

deprecated_state

= DEPRECATED_SUPPRESS;

3693

3694

attributes = chainon (attributes,
prefix_attributes);

3695

3696

decl = grokdeclarator (declarator, declspecs,
NORMAL,
initialized,

3697

&attributes);

3698

3699

deprecated_state

= DEPRECATED_NORMAL;

3700

3701

if (decl == NULL_TREE || TREE_CODE (decl) ==
VOID_TYPE)

3702

return
error_mark_node;

3703

3704

type = TREE_TYPE (decl);

3705

3706

if (type == error_mark_node)

3707

return
error_mark_node;

3708

3709

context = DECL_CONTEXT (decl);

3710

3711

if (initialized && context &&
TREE_CODE (context) == NAMESPACE_DECL

3712

&& context != current_namespace
&& TREE_CODE (decl) == VAR_DECL)

3713

{

3714

/* When parsing the initializer, lookup should use the
object's

3715

namespace.
*/

3716

push_decl_namespace (context);

3717

}

3718

3719

/* We are only
interested in class contexts, later.
*/

3720

if (context && TREE_CODE (context) ==
NAMESPACE_DECL)

3721

context = NULL_TREE;

作为声明的一种,期望的是某种
DECL
节点,因此需要
grokdeclarator

分析
decl-specifiers
及声明符部分来构成这个节点。

6462

tree

6463

grokdeclarator
(tree declarator,

in 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

{



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);



6654

break
;

6655

6656

}

6657

}

6658

}



6828

/* Look through the
decl specs and record which ones appear.

6829

Some typespecs are defined as
built-in typenames.

6830

Others, the ones that are
modifiers of other types,

6831

are represented by bits in
SPECBITS: set the bits for

6832

the modifiers that appear.
Storage class keywords are also in SPECBITS.

6833

6834

If there is a typedef name or
a type, store the type in TYPE.

6835

This includes builtin typedefs
such as `int'.

6836

6837

Set EXPLICIT_INT if the type is
`int' or `char' and did not

6838

come from a user typedef.

6839

6840

Set LONGLONG if `long' is
mentioned twice.

6841

6842

For C++, constructors and
destructors have their own fast treatment.

*/

6843

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);

6856

6857

/* If the entire
declaration is itself tagged as deprecated then

6858

suppress reports of
deprecated items.
*/

6859

if (!adding_implicit_members

&& id &&
TREE_DEPRECATED (id))

6860

{

6861

if (deprecated_state

!= DEPRECATED_SUPPRESS)

6862

warn_deprecated_use (id);

6863

}

6864

6865

if (TREE_CODE (id) == IDENTIFIER_NODE)

6866

{



6933

}

6934

else if (TREE_CODE (id) == TYPE_DECL)

6935

{

6936

if (type)

6937

error ("multiple declarations `%T'
and `%T'", type,

6938

TREE_TYPE (id));

6939

else

6940

{

6941

type = TREE_TYPE (id);

6942

TREE_VALUE (spec) = type;

6943

typedef_decl = id;

6944

}

6945

goto
found;

6946

}

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;



7019

ctype = NULL_TREE;



7337

scope = get_scope_of_declarator (declarator);

7338

7339

/* Now figure out
the structure of the declarator proper.

7340

Descend through it, creating
more complex types, until we reach

7341

the declared identifier (or
NULL_TREE, in an abstract declarator).

*/

7342

7343

while
(declarator && TREE_CODE (declarator) != IDENTIFIER_NODE

7344

&& TREE_CODE (declarator) !=
TEMPLATE_ID_EXPR)

7345

{



7840

}



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

{



8514

}

8515

else

8516

{

8517

/* It's a
variable.
*/

8518

8519

/* An
uninitialized decl with `extern' is a reference.
*/

8520

decl = grokvardecl

(type, declarator, &specbits,

8521

initialized,

8522

(type_quals &
TYPE_QUAL_CONST) != 0,

8523

ctype ? ctype :
in_namespace);

8524

bad_specifiers
(decl, "variable", virtualp, quals != NULL_TREE,

8525

inlinep, friendp, raises !=
NULL_TREE);

8526

8527

if (ctype)

8528

{



8547

}

8548

}

8549

8550

my_friendly_assert (!RIDBIT_SETP
(RID_MUTABLE, specbits), 19990927);

8551

8552

/* Record
`register' declaration for warnings on &

8553

and in case doing stupid
register allocation.
*/

8554

8555

if (RIDBIT_SETP (RID_REGISTER, specbits))

8556

DECL_REGISTER (decl) = 1;

8557

8558

if (RIDBIT_SETP (RID_EXTERN, specbits))

8559

DECL_THIS_EXTERN (decl) = 1;

8560

8561

if (RIDBIT_SETP (RID_STATIC, specbits))

8562

DECL_THIS_STATIC (decl) = 1;

8563

8564

/* Record
constancy and volatility. There's no need to do this

8565

when processing a template;
we'll do this for the instantiated

8566

declaration based on the
type of DECL.
*/

8567

if (!processing_template_decl)

8568

c_apply_type_quals_to_decl (type_quals, decl);

8569

8570

return
decl;

8571

}

8572

}

在上面的代码中,显然
6525
行的
WHILE

块验证声明符部分;而
6844
行的
FOR

块验证并提前对应的
type-specifier
。注意到在
6941
行,
type

指向上一节中所构建的
RECORD_TYPE


接着
type


declarator

将被组合起来由
grokvardecl

来构成期望的
VAR_DECL
。注意到对于我们的情形,在调用期间,参数
scope


NULL

constp


false

initialized


false
,而
specbits_in

包含了
0


5885

static
tree

5886

grokvardecl

(tree type,

in decl.c

5887

tree name,

5888

RID_BIT_TYPE * specbits_in,

5889

int initialized,

5890

int constp,

5891

tree scope)

5892

{

5893

tree decl;

5894

tree explicit_scope;

5895

RID_BIT_TYPE specbits;

5896

5897

my_friendly_assert (!name || TREE_CODE (name)
== IDENTIFIER_NODE,

5898

20020808);

5899

5900

specbits = *specbits_in;

5901

5902

/* Compute the
scope in which to place the variable, but remember

5903

whether or not that scope was
explicitly specified by the user.
*/

5904

explicit_scope = scope;

5905

if (!scope)

5906

{

5907

/* An explicit
"extern" specifier indicates a namespace-scope

5908

variable.
*/

5909

if (RIDBIT_SETP (RID_EXTERN, specbits))

5910

scope = current_namespace;

5911

else if (!at_function_scope_p ())

5912

{

5913

scope = current_scope ();

5914

if (!scope)

5915

scope = current_namespace;

5916

}

5917

}

5918

5919

if (scope

5920

&& (/*
If the variable is a namespace-scope variable declared in a

5921

template, we need
DECL_LANG_SPECIFIC.
*/

5922

(TREE_CODE (scope) == NAMESPACE_DECL
&& processing_template_decl)

5923

/*
Similarly for namespace-scope variables with language linkage

5924

other than C++.
*/

5925

|| (TREE_CODE (scope) ==
NAMESPACE_DECL

5926

&& current_lang_name !=
lang_name_cplusplus)

5927

/*
Similarly for static data members.
*/

5928

|| TYPE_P (scope)))

5929

decl = build_lang_decl (VAR_DECL, name,
type);

5930

else

5931

decl = build_decl
(VAR_DECL, name, type);

5932

5933

if (explicit_scope && TREE_CODE
(explicit_scope) == NAMESPACE_DECL)

5934

set_decl_namespace (decl, explicit_scope,
0);

5935

else

5936

DECL_CONTEXT (decl) = scope;

5937

5938

if (name && scope && current_lang_name

!= lang_name_c)

5939

/* We can't mangle lazily here because we
don't have any

5940

way to recover whether or
not a variable was `extern

5941

"C"' later.
*/

5942

mangle_decl (decl);

5943

5944

if (RIDBIT_SETP (RID_EXTERN, specbits))

5945

{

5946

DECL_THIS_EXTERN (decl) = 1;

5947

DECL_EXTERNAL (decl) = !initialized;

5948

}

5949

5950

/* In class
context, static means one per class,

5951

public access, and static
storage.
*/

5952

if (DECL_CLASS_SCOPE_P (decl))

5953

{

5954

TREE_PUBLIC (decl) = 1;

5955

TREE_STATIC (decl) = 1;

5956

DECL_EXTERNAL (decl) = 0;

5957

}

5958

/* At top level,
either `static' or no s.c.
makes a definition

5959

(perhaps tentative), and
absence of `static' makes it public.
*/

5960

else if (toplevel_bindings_p ())

5961

{

5962

TREE_PUBLIC (decl) = (RIDBIT_NOTSETP
(RID_STATIC, specbits)

5963

&&
(DECL_THIS_EXTERN (decl) || ! constp));

5964

TREE_STATIC (decl) = ! DECL_EXTERNAL
(decl);

5965

}

5966

/* Not at top
level, only `static' makes a static definition.

*/

5967

else

5968

{

5969

TREE_STATIC (decl) = !! RIDBIT_SETP
(RID_STATIC, specbits);

5970

TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);

5971

}

5972

5973

if (RIDBIT_SETP (RID_THREAD, specbits))

5974

{

5975

if (targetm

.have_tls)

5976

DECL_THREAD_LOCAL (decl) = 1;

5977

else

5978

/* A mere
warning is sure to result in improper semantics

5979

at runtime. Don't bother
to allow this to compile.
*/

5980

error ("thread-local storage not
supported for this target");

5981

}

5982

5983

if (TREE_PUBLIC (decl))

5984

{

5985

/* [basic.link]:
A name with no linkage (notably, the name of a class

5986

or enumeration declared in a
local scope) shall not be used to

5987

declare an entity with
linkage.

5988

5989

Only check this for public
decls for now.
*/

5990

tree t = no_linkage_check (TREE_TYPE
(decl));

5991

if (t)

5992

{

5993

if (TYPE_ANONYMOUS_P (t))

5994

/* Ignore for
now; `enum { foo } e' is pretty common.

*/;

5995

else

5996

pedwarn ("non-local variable `%#D'
uses local type `%T'",

5997

decl, t);

5998

}

5999

}

6000

6001

return
decl;

6002

}

在这一步之后,我们得到下图中的
VAR_DECL
。看到该节点的
context

域是
NULL
,因为我们不在类作用域中。


点此打开



start_decl (continue)

3832

/* Enter this
declaration into the symbol table.
*/

3833

tem = maybe_push_decl (decl);

3834

3835

if (processing_template_decl)

3836

tem = push_template_decl (tem);

3837

if (tem == error_mark_node)

3838

return
error_mark_node;

3839

3840

#if ! defined (
ASM_OUTPUT_BSS) && ! defined
(ASM_OUTPUT_ALIGNED_BSS)

3841

/* Tell the
back-end to use or not use .common as appropriate. If we say

3842

-fconserve-space, we want this
to save .data space, at the expense of

3843

wrong semantics. If we say
-fno-conserve-space, we want this to

3844

produce errors about redefs;
to do this we force variables into the

3845

data segment.
*/

3846

DECL_COMMON (tem) = ((TREE_CODE (tem) !=
VAR_DECL

3847

||
!DECL_THREAD_LOCAL (tem))

3848

&& (flag_conserve_space

|| ! TREE_PUBLIC (tem)));

3849

#endif

3850

3851

if (! processing_template_decl)

3852

start_decl_1 (tem);

3853

3854

return
tem;

3855

}

作为一个
context

域为
NULL

VAR_DECL
节点,
maybe_push_decl


decl

调用
pushdecl

。而对于我们的例子,在
3852
行的
start_decl_1

不做任何事。

566

tree

567

pushdecl (tree
x)

in name-lookup.c

568

{

569

tree t;

570

tree name;

571

int need_new_binding;

572

573

timevar_push (TV_NAME_LOOKUP);

574

575

need_new_binding = 1;

576

577

if (DECL_TEMPLATE_PARM_P (x))

578

/* Template
parameters have no context; they are not X::T even

579

when declared
within a class or namespace.
*/

580

;

581

else

582

{

583

if (current_function_decl

&& x != current_function_decl

584

/* A local
declaration for a function doesn't constitute

585

nesting.
*/

586

&& TREE_CODE (x) !=
FUNCTION_DECL

587

/* A local
declaration for an `extern' variable is in the

588

scope of the
current namespace, not the current

589

function.
*/

590

&& !(TREE_CODE (x) == VAR_DECL
&& DECL_EXTERNAL (x))

591

&& !DECL_CONTEXT (x))

592

DECL_CONTEXT (x) = current_function_decl

;



602

}

603

604

name = DECL_NAME (x);

605

if (name)

606

{

607

int different_binding_level = 0;



615

/* In case this
decl was explicitly namespace-qualified, look it

616

up in its
namespace context.
*/

617

if (DECL_NAMESPACE_SCOPE_P (x) &&
namespace_bindings_p ())

618

t = namespace_binding (name, DECL_CONTEXT
(x));

619

else

620

t = lookup_name_current_level (name);



828

/* This name is
new in its binding level.

829

Install the new
declaration and return it.
*/

830

if (namespace_bindings_p
())

831

{



872

}

873

else

874

{

875

/* Here to
install a non-global value.
*/

876

tree oldlocal = IDENTIFIER_VALUE (name);

877

tree oldglobal =
IDENTIFIER_NAMESPACE_VALUE (name);

878

879

if (need_new_binding)

880

{

881

push_local_binding (name, x, 0);

882

/* Because
push_local_binding will hook X on to the

883

current_binding_level's name list, we don't want to

884

do that
again below.
*/

885

need_new_binding = 0;

886

}



1003

}

1004

1005

if (TREE_CODE (x) == VAR_DECL)

1006

maybe_register_incomplete_var (x);

1007

}



1015

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);

1016

}

我们已经多次看过
pushdecl

;再次我们在上面给出该函数得到执行部分的代码。看到在
1006
行的
maybe_register_incomplete_var

对非外部的
VAR_DECL
不做处理。在退出
start_decl

时,我们得到如下的中间树。


点此打开



cp_parser_init_declarator (continue)

10111

/* Enter the SCOPE.
That way unqualified names appearing in the

10112

initializer will be looked up in
SCOPE.
*/

10113

if (scope)

10114

pop_p = push_scope (scope);

10115

10116

/* Perform deferred
access control checks, now that we know in which

10117

SCOPE the declared entity resides.
*/

10118

if (!member_p && decl)

10119

{

10120

tree saved_current_function_decl =
NULL_TREE;

10121

10122

/* If the entity
being declared is a function, pretend that we

10123

are in its scope. If it is a `friend', it
may have access to

10124

things that would not otherwise be
accessible.
*/

10125

if (TREE_CODE (decl) == FUNCTION_DECL)

10126

{

10127

saved_current_function_decl = current_function_decl

;

10128

current_function_decl

= decl;

10129

}

10130

10131

/* Perform the
access control checks for the declarator and the

10132

the decl-specifiers.
*/

10133

perform_deferred_access_checks
();

10134

10135

/* Restore the saved
value.
*/

10136

if (TREE_CODE (decl) == FUNCTION_DECL)

10137

current_function_decl

=
saved_current_function_decl;

10138

}

10139

10140

/* Parse the
initializer.
*/

10141

if (is_initialized)

10142

initializer = cp_parser_initializer
(parser,

10143

&is_parenthesized_init,

10144

&is_non_constant_init);

10145

else

10146

{

10147

initializer = NULL_TREE;

10148

is_parenthesized_init = false;

10149

is_non_constant_init = true;

10150

}



10178

/* Finish processing the declaration. But,
skip friend

10179

declarations.
*/

10180

if (!friend_p && decl)

10181

cp_finish_decl
(decl,

10182

initializer,

10183

asm_specification,

10184

/* If
the initializer is in parentheses, then this is

10185

a direct-initialization, which means that an

10186

`explicit' constructor is OK.
Otherwise, an

10187

`explicit' constructor
cannot be used.
*/

10188

((is_parenthesized_init ||
!is_initialized)

10189

? 0 : LOOKUP_ONLYCONVERTING));

10190

10191

/* Remember whether
or not variables were initialized by

10192

constant-expressions.
*/

10193

if (decl && TREE_CODE (decl) ==
VAR_DECL

10194

&& is_initialized &&
!is_non_constant_init)

10195

DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
(decl) = true;

10196

10197

return
decl;

10198

}

注意到在为
template-id

VAR_DECL
构建了节点之后,正是为相关声明符及
decl-specifier
执行延迟访问检查的时机。看到访问控制检查失败不会停止解析器。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: