您的位置:首页 > 其它

Studying note of GCC-3.4.6 source (104)

2010-09-20 11:49 288 查看
5.12.3.2.1.1.3.5.3.


Finish


With returned arg_types

and parms

,
at line 7601 in grokdeclarator

, build_function_type

creates
node of FUNCTION_TYPE as following.

(Click
here for open
)

Figure 81

:
FUNCTION_TYPE created

Now nodes
related to CALL_EXPR are useless, as no reference to CALL_EXPR node. Then at
line 8240 in grokdeclarator

,
build_method_type_directly

creates node of METHOD_TYPE as following.

(Click
here for open
)

Figure 82

:
METHOD_TYPE created

Immediately at
line 8250 in grokdeclarator

,
grokfndecl

creates node of FUNCTION_DECL as below.

(Click
here for open
)

Figure 83

:
FUNCTION_DECL created

When returns
back start_method

,
after pushing corresponding nodes of template declaration, it gets following
intermediate tree.

(Click
here for open
)

Figure 84

:
TEMPLATE_DECL created

Next at line 11087 in start_method

and within grok_special_member_properties

,
copy_fn_p

returns value to indicate the characteristics of the constructor or assignment
operator.

Assuming D is a constructor or overloaded `operator='. Let T be the
class in which D is declared. Then, this function returns:

-1, if D's is an ill-formed constructor or copy assignment operator whose
first parameter is of type `T'.

0, if D is not a copy constructor or copy assignment operator.

1, if D is a copy constructor or copy assignment operator whose
first parameter is a reference to const qualified T.

2, if D is a copy constructor or copy assignment operator whose
first parameter is a reference to non-const qualified T.

8853

int

8854

copy_fn_p

(tree d)

in decl.c

8855

{

8856

tree args;

8857

tree arg_type;

8858

int result = 1;

8859

8860

my_friendly_assert
(DECL_FUNCTION_MEMBER_P (d), 20011208);

8861

8862

if (DECL_TEMPLATE_INFO (d) &&
is_member_template (DECL_TI_TEMPLATE (d)))

8863

/*
Instantiations of template member functions are never copy

8864

functions. Note that member functions of templated classes are

8865

represented as template functions
internally, and we must

8866

accept those as copy functions.

*/

8867

return
0;

8868

8869

args = FUNCTION_FIRST_USER_PARMTYPE
(d);

8870

if (!args)

8871

return
0;

8872

8873

arg_type = TREE_VALUE
(args);

8874

8875

if (TYPE_MAIN_VARIANT
(arg_type) == DECL_CONTEXT (d))

8876

{

8877

/*
Pass by value copy assignment operator.

*/

8878

result = -1;

8879

}

8880

else if (TREE_CODE
(arg_type) == REFERENCE_TYPE

8881

&&
TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)) == DECL_CONTEXT (d))

8882

{

8883

if (CP_TYPE_CONST_P
(TREE_TYPE (arg_type)))

8884

result = 2;

8885

}

8886

else

8887

return
0;

8888

8889

args = TREE_CHAIN (args);

8890

8891

if (args && args !=
void_list_node && !TREE_PURPOSE (args))

8892

/*
There are more non-optional args.
*/

8893

return
0;

8894

8895

return
result;

8896

}

No doubt, for our copy constructor, result will be 0, as the
parameter is not of type “Lock”. So nothing is done in grok_special_member_properties

.

5.12.3.2.1.1.3.1.


Finish
parsing


After parsing the non-default constructor, we come to the end of the
class. It must be “};” to ending the definition. As GNU extension allows
declaring attributes for the class after token “}” and before “;”, it needs try
parsing this optional attributes.

cp_parser_class_specifier (continue)

11913

cp_parser_require
(parser, CPP_CLOSE_BRACE, "`}'");

11914

/*
We get better error messages by noticing a common problem: a

11915

missing trailing `;'.
*/

11916

token = cp_lexer_peek_token
(parser->lexer);

11917

has_trailing_semicolon =
(token->type == CPP_SEMICOLON);

11918

/*
Look for trailing attributes to apply to this class.
*/

11919

if
(cp_parser_allow_gnu_extensions_p (parser))

11920

{

11921

tree sub_attr =
cp_parser_attributes_opt (parser);

11922

attributes = chainon
(attributes, sub_attr);

11923

}

11924

if (type !=
error_mark_node)

11925

type = finish_struct
(type, attributes);

11926

if (pop_p)

11927

pop_scope (scope);

If everything runs smoothly, it can finialize the parsing of the
class, and install the attributes for the class at the same time.

5228

tree

5229

finish_struct

(tree t, tree attributes)

in class.c

5230

{

5231

location_t saved_loc = input_location

;

5232

5233

/* Now that we've
got all the field declarations, reverse everything

5234

as necessary.
*/

5235

unreverse_member_declarations
(t);

5236

5237

cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);

5238

5239

/* Nadger the
current location so that diagnostics point to the start of

5240

the struct, not the end.
*/

5241

input_location

= DECL_SOURCE_LOCATION (TYPE_NAME
(t));

As we have seen before, the nodes for declarator of the methods are
chained in the reverse order of the declaration, so it now restore the order
back now by reversing again.

5197

void

5198

unreverse_member_declarations

(tree t)

in class.c

5199

{

5200

tree next;

5201

tree prev;

5202

tree x;

5203

5204

/* The following
lists are all in reverse order. Put them in

5205

declaration order now.
*/

5206

TYPE_METHODS (t) = nreverse (TYPE_METHODS
(t));

5207

CLASSTYPE_DECL_LIST (t) = nreverse
(CLASSTYPE_DECL_LIST (t));

5208

5209

/* Actually, for
the TYPE_FIELDS, only the non TYPE_DECLs are in

5210

reverse order, so we can't
just use nreverse.
*/

5211

prev = NULL_TREE;

5212

for
(x =
TYPE_FIELDS (t);

5213

x && TREE_CODE (x) != TYPE_DECL;

5214

x = next)

5215

{

5216

next = TREE_CHAIN (x);

5217

TREE_CHAIN (x) = prev;

5218

prev = x;

5219

}

5220

if (prev)

5221

{

5222

TREE_CHAIN (TYPE_FIELDS (t)) = x;

5223

if (prev)

5224

TYPE_FIELDS (t) = prev;

5225

}

5226

}

At line 5237, cplus_decl_attributes

installs the optional
attributes of the class, for the struct Lock, class level attribute is absent.

finish_struct (continue)

5243

if (processing_template_decl
)

5244

{

5245

finish_struct_methods
(t);

5246

TYPE_SIZE (t) = bitsize_zero_node;

5247

TYPE_SIZE_UNIT (t) = size_zero_node;

5248

}

5249

else

5250

finish_struct_1 (t);

5251

5252

input_location

= saved_loc;

5253

5254

TYPE_BEING_DEFINED (t) = 0;

5255

5256

if (current_class_type

)

5257

popclass
();

5258

else

5259

error ("trying to finish struct, but
kicked out due to previous parse errors");

5260

5261

if (processing_template_decl
&& at_function_scope_p ())

5262

add_stmt
(build_min (TAG_DEFN, t));

5263

5264

return
t;

5265

}

If we are handling class-template, the details of the class which
will be determined at point of instantiation (for example, if it inherits from
a class-template, the derivation can only be known at point of instantiation).
So only limited operation needs be taken by finish_struct_methods

, and see that even the
size of the class is temperary declared as zero at line 5246 and 5247.

1718

static
void

1719

finish_struct_methods

(tree t)

in class.c

1720

{

1721

tree fn_fields;

1722

tree method_vec;

1723

int slot, len;

1724

1725

if (!TYPE_METHODS (t))

1726

{

1727

/* Clear these
for safety; perhaps some parsing error could set

1728

these incorrectly.
*/

1729

TYPE_HAS_CONSTRUCTOR (t) = 0;

1730

TYPE_HAS_DESTRUCTOR (t) = 0;

1731

CLASSTYPE_METHOD_VEC (t) = NULL_TREE;

1732

return
;

1733

}

1734

1735

method_vec = CLASSTYPE_METHOD_VEC (t);

1736

my_friendly_assert (method_vec != NULL_TREE,
19991215);

1737

len = TREE_VEC_LENGTH (method_vec);

1738

1739

/* First fill in
entry 0 with the constructors, entry 1 with destructors,

1740

and the next few with type
conversion operators (if any).
*/

1741

for
(fn_fields = TYPE_METHODS (t); fn_fields;

1742

fn_fields = TREE_CHAIN (fn_fields))

1743

/* Clear out this
flag.
*/

1744

DECL_IN_AGGR_P (fn_fields) = 0;

1745

1746

if (TYPE_HAS_DESTRUCTOR (t) &&
!CLASSTYPE_DESTRUCTORS (t))

1747

/* We thought there was a destructor, but
there wasn't. Some

1748

parse errors cause this
anomalous situation.
*/

1749

TYPE_HAS_DESTRUCTOR (t) = 0;

1750

1751

/* Issue warnings
about private constructors and such. If there are

1752

no methods, then some public
defaults are generated.
*/

1753

maybe_warn_about_overly_private_class (t);

1754

1755

/* Now sort the
methods.
*/

1756

while
(len
> 2 && TREE_VEC_ELT (method_vec, len-1) == NULL_TREE)

1757

len--;

1758

TREE_VEC_LENGTH (method_vec) = len;

1759

1760

/* The type
conversion ops have to live at the front of the vec, so we

1761

can't sort them.
*/

1762

for
(slot =
2; slot < len; ++slot)

1763

{

1764

tree fn = TREE_VEC_ELT (method_vec, slot);

1765

1766

if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))

1767

break
;

1768

}

1769

if (len - slot > 1)

1770

qsort (&TREE_VEC_ELT (method_vec,
slot), len-slot, sizeof
(tree),

1771

method_name_cmp);

1772

}

Seeing that this limited handling just includes correcting flags
incorrectly set by error statements encountered by parser. Sometimes, when
writing a simple class like “Lock” here, it may be mistakenly written as:

cass
Lock {

Lock();

Lock(const
Host&);

};

As it missing the access-specifier “public”, the constructors can’t
be invoked. The parser can give out warning about it. However, when the class
has friend, or has other public methods (static or non-static), it is diffcult
to tell whether the constructors can be invoked outside. The parser just
assumes that them can, and will issue error if them can’t be invoked later in
code. At line 1753, maybe_warn_about_overly_private_class

does
the checking.

And now all methods of the class are known, to accelerate the
searching speed for the method, the methods must be sorted so binary search can
be applied (line 1770).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: