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

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

2010-09-09 11:51 477 查看
5.12.3.2.1.1.3.1. 解析默认构造函数
类似于类“SingleThreaded”解析其成员,依次调用cp_parser_class_specifier[/i],cp_parser_member_specification_opt[/i],cp_parser_member_declaration[/i],cp_parser_decl_specifier_seq[/i],在下面的代码片段中按照构造函数解析这个decl-specifier。

cp_parser_decl_specifier_seq (continue)

6741 [/i] /* Constructors are a special case. The `S' in `S()' is not a
6742 [/i] decl-specifier; it is the beginning of the declarator. */
6743 [/i] constructor_p = (!decl_spec
6744 [/i] && constructor_possible_p
6745 [/i] && cp_parser_constructor_declarator_p (parser,
6746 [/i] friend_p));

在6744行,constructor_possible_p[/i]是parser的in_declarator_p[/i]域取反。该域在解析声明符期间为true。

14161 [/i]static bool
14162 [/i]cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) in parser.c[/i]
14163 [/i]{
14164 [/i] bool constructor_p;
14165 [/i] tree type_decl = NULL_TREE;
14166 [/i] bool nested_name_p;
14167 [/i] cp_token *next_token;
14168 [/i]
14169 [/i] /* The common case is that this is not a constructor declarator, so
14170 [/i] try to avoid doing lots of work if at all possible. It's not
14171 [/i] valid declare a constructor at function scope. */
14172 [/i] if (at_function_scope_p ())
14173 [/i] return false;
14174 [/i] /* And only certain tokens can begin a constructor declarator. */
14175 [/i] next_token = cp_lexer_peek_token (parser->lexer);
14176 [/i] if (next_token->type != CPP_NAME
14177 [/i] && next_token->type != CPP_SCOPE
14178 [/i] && next_token->type != CPP_NESTED_NAME_SPECIFIER
14179 [/i] && next_token->type != CPP_TEMPLATE_ID)
14180 [/i] return false;
14181 [/i]
14182 [/i] /* Parse tentatively; we are going to roll back all of the tokens
14183 [/i] consumed here. */
14184 [/i] cp_parser_parse_tentatively (parser);
14185 [/i] /* Assume that we are looking at a constructor declarator. */
14186 [/i] constructor_p = true;
14187 [/i]
14188 [/i] /* Look for the optional `::' operator. */
14189 [/i] cp_parser_global_scope_opt (parser,
14190 [/i] /*current_scope_valid_p=*/false);
14191 [/i] /* Look for the nested-name-specifier. */
14192 [/i] nested_name_p
14193 [/i] = (cp_parser_nested_name_specifier_opt (parser,
14194 [/i] /*typename_keyword_p=*/false,
14195 [/i] /*check_dependency_p=*/false,
14196 [/i] /*type_p=*/false,
14197 [/i] /*is_declaration=*/false)
14198 [/i] != NULL_TREE);
14199 [/i] /* Outside of a class-specifier, there must be a
14200 [/i] nested-name-specifier. */
14201 [/i] if (!nested_name_p &&
14202 [/i] (!at_class_scope_p () || !TYPE_BEING_DEFINED (current_class_type[/i])
14203 [/i] || friend_p))
14204 [/i] constructor_p = false;
14205 [/i] /* If we still think that this might be a constructor-declarator,
14206 [/i] look for a class-name. */
14207 [/i] if (constructor_p)
14208 [/i] {
14209 [/i] /* If we have:
14210 [/i]
14211 [/i] template <typename T> struct S { S(); };
14212 [/i] template <typename T> S<T>::S ();
14213 [/i]
14214 [/i] we must recognize that the nested `S' names a class.
14215 [/i] Similarly, for:
14216 [/i]
14217 [/i] template <typename T> S<T>::S<T> ();
14218 [/i]
14219 [/i] we must recognize that the nested `S' names a template. */
14220 [/i] type_decl = cp_parser_class_name (parser,
14221 [/i] /*typename_keyword_p=*/false,
14222 [/i] /*template_keyword_p=*/false,
14223 [/i] /*type_p=*/false,
14224 [/i] /*check_dependency_p=*/false,
14225 [/i] /*class_head_p=*/false,
14226 [/i] /*is_declaration=*/false);
14227 [/i] /* If there was no class-name, then this is not a constructor. */
14228 [/i] constructor_p = !cp_parser_error_occurred (parser);
14229 [/i] }

注意到上面14217行的注释中给出的例子,对于例子“template <typename T> S<T>::S();”“template <typename T> S<T>::”部分是nested-name-specifier,函数cp_parser_class_name[/i] 确定“S”是否代表类名;如果不是,cp_parser_error_occurred[/i]将返回非0值。而由cp_parser_class_name[/i]返回的type_decl[/i]是代表该类的TYPE_DECL。我们在后面来看名字查找的过程。

cp_parser_constructor_declarator_p (continue)

14231 [/i] /* If we're still considering a constructor, we have to see a `(',
14232 [/i] to begin the parameter-declaration-clause, followed by either a
14233 [/i] `)', an `...', or a decl-specifier. We need to check for a
14234 [/i] type-specifier to avoid being fooled into thinking that:
14235 [/i]
14236 [/i] S::S (f) (int);
14237 [/i]
14238 [/i] is a constructor. (It is actually a function named `f' that
14239 [/i] takes one parameter (of type `int') and returns a value of type
14240 [/i] `S::S'. */
14241 [/i] if (constructor_p
14242 [/i] && cp_parser_require (parser, CPP_OPEN_PAREN, "`('"))
14243 [/i] {
14244 [/i] if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
14245 [/i] && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS)
14246 [/i] /* A parameter declaration begins with a decl-specifier,
14247 [/i] which is either the "attribute" keyword, a storage class
14248 [/i] specifier, or (usually) a type-specifier. */
14249 [/i] && !cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE)
14250 [/i] && !cp_parser_storage_class_specifier_opt (parser))
14251 [/i] {

14298 [/i] }
14299 [/i] }
14300 [/i] else
14301 [/i] constructor_p = false;
14302 [/i] /* We did not really want to consume any tokens. */
14303 [/i] cp_parser_abort_tentative_parse (parser);
14304 [/i]
14305 [/i] return constructor_p;
14306 [/i]}

接着,当cp_parser_constructor_declarator_p[/i]返回到cp_parser_decl_specifier_seq[/i]时,decl_spec[/i]保持为NULL。因此执行下面的代码。

cp_parser_decl_specifier_seq (continue)

6807 [/i] /* If we still do not have a DECL_SPEC, then there are no more
6808 [/i] decl-specifiers. */
6809 [/i] if (!decl_spec)
6810 [/i] {
6811 [/i] /* Issue an error message, unless the entire construct was
6812 [/i] optional. */
6813 [/i] if (!(flags & CP_PARSER_FLAGS_OPTIONAL))
6814 [/i] {
6815 [/i] cp_parser_error (parser, "expected decl specifier");
6816 [/i] return error_mark_node;
6817 [/i] }
6818 [/i]
6819 [/i] break;
6820 [/i] }

注意到在调用该函数时,flags[/i]是CP_PARSER_FLAGS_OPTIONAL,它表示构造函数是可选的。在6819行,将跳出WHILE[/b]循环,并且返回NULL,因为构造函数是声明符(declarator)而不是decl-specifier。
5.12.3.2.1.1.3.4.1. 解析声明符
因为构造函数或析构函数是声明符,如果我们写下正确的构造函数或析构函数,我们将进入12603行的ELSE[/b]块,开始按照声明符来解析构造函数。
在一个可选的decl-specifier-seq后,跟着一列声明符。每个声明符仅包含一个declarator-id,它命名了所声明的标识符。出现在一个declarator-id中的unqualified-id应该是一个简单的标识符,除了某些特殊函数的声明及模板特化或偏特化的声明。一个declarator-id不应该是被修饰的(qualified),除非是在类定义体外的成员函数或静态数据成员的定义,或是在其名字空间外的变量或函数的定义及显式具现,或是在其名字空间外先前所声明的一个显式特化的定义,或是为另一个类或名字空间成员的友元函数的声明。当该declarator-id具有修饰时,该声明应该援引一个先前所声明的成员,该成员属于该修饰符所引用的名字空间或类,并且该成员不能由using声明引入,该using声明在该declarator-id的nested-name-specifie部分所限定的类或名字空间域中。[注意:如果修饰符是全局域::的解析操作符(resolution operator),该declarator-id援引声明在全局名字空间的名字。]
一个auto,static,extern,register,mutable,friend,inline,virtual或typedef说明符直接应用到每个在init-declarator-list中的declarator-id;每个declarator-id的类型依赖于该decl-specifier-seq及其声明符。
因此,一个特定标识符的声明具有形式:“T D”,其中T是一个decl-specifier-seq,而D是一个声明符。下面是一个确定由这样一个声明中所包含的declarator-id所指定的类型的递归过程。
首先,该decl-specifier-seq确定了一个类型。在声明T D中,decl-specifier-seq T确定了类型“T”。[例如:在声明int unsigned i;中,类型指示符int unsigned确定了类型“unsigned int”]
声明T D,其中D是一个未加修饰(unadorned)的标识符,该标识符的类型是“T”。
声明T D,其中D具有形式“( D1 )”,其中所包含的declarator-id的类型,与声明T D1中所包含的declarator-id的类型相同。
括号不改变嵌入的(embedded)declarator-id的类型,但它们可以改变复杂声明符的绑定。

cp_parser_member_declaration (continue)

12508 [/i] /* Check for an invalid type-name. */
12509 [/i] if (cp_parser_diagnose_invalid_type_name (parser))
12510 [/i] return;
12511 [/i] /* If there is no declarator, then the decl-specifier-seq should
12512 [/i] specify a type. */
12513 [/i] if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
12514 [/i] {

12602 [/i] }
12603 [/i] else
12604 [/i] {
12605 [/i] /* See if these declarations will be friends. */
12606 [/i] friend_p = cp_parser_friend_p (decl_specifiers);
12607 [/i]
12608 [/i] /* Keep going until we hit the `;' at the end of the
12609 [/i] declaration. */
12610 [/i] while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
12611 [/i] {
12612 [/i] tree attributes = NULL_TREE;
12613 [/i] tree first_attribute;
12614 [/i]
12615 [/i] /* Peek at the next token. */
12616 [/i] token = cp_lexer_peek_token (parser->lexer);
12617 [/i]
12618 [/i] /* Check for a bitfield declaration. */
12619 [/i] if (token->type == CPP_COLON
12620 [/i] || (token->type == CPP_NAME
12621 [/i] && cp_lexer_peek_nth_token (parser->lexer, 2)->type
12622 [/i] == CPP_COLON))
12623 [/i] {

12657 [/i] }
12658 [/i] else
12659 [/i] {
12660 [/i] tree declarator;
12661 [/i] tree initializer;
12662 [/i] tree asm_specification;
12663 [/i] int ctor_dtor_or_conv_p;
12664 [/i]
12665 [/i] /* Parse the declarator. */
12666 [/i] declarator
12667 [/i] = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
12668 [/i] &ctor_dtor_or_conv_p,
12669 [/i] /*parenthesized_p=*/NULL,
12670 [/i] /*member_p=*/true);

在我们的例子中,上面的decl_specifiers[/i]是NULL(即,没有decl-specifier-seq部分)。那么declarator部分由下面的函数来解析。

10259 [/i]static tree
10260 [/i]cp_parser_declarator (cp_parser* parser, in parser.c[/i]
10261 [/i] cp_parser_declarator_kind dcl_kind,
10262 [/i] int* ctor_dtor_or_conv_p,
10263 [/i] bool* parenthesized_p,
10264 [/i] bool member_p)
10265 [/i]{
10266 [/i] cp_token *token;
10267 [/i] tree declarator;
10268 [/i] enum tree_code code;
10269 [/i] tree cv_qualifier_seq;
10270 [/i] tree class_type;
10271 [/i] tree attributes = NULL_TREE;
10272 [/i]
10273 [/i] /* Assume this is not a constructor, destructor, or type-conversion
10274 [/i] operator. */
10275 [/i] if (ctor_dtor_or_conv_p)
10276 [/i] *ctor_dtor_or_conv_p = 0;
10277 [/i]
10278 [/i] if (cp_parser_allow_gnu_extensions_p (parser))
10279 [/i] attributes = cp_parser_attributes_opt (parser);
10280 [/i]
10281 [/i] /* Peek at the next token. */
10282 [/i] token = cp_lexer_peek_token (parser->lexer);
10283 [/i]
10284 [/i] /* Check for the ptr-operator production. */
10285 [/i] cp_parser_parse_tentatively (parser);
10286 [/i] /* Parse the ptr-operator. */
10287 [/i] code = cp_parser_ptr_operator (parser,
10288 [/i] &class_type,
10289 [/i] &cv_qualifier_seq);
10290 [/i] /* If that worked, then we have a ptr-operator. */
10291 [/i] if (cp_parser_parse_definitely (parser))
10292 [/i] {

10324 [/i] }
10325 [/i] /* Everything else is a direct-declarator. */
10326 [/i] else
10327 [/i] {
10328 [/i] if (parenthesized_p)
10329 [/i] *parenthesized_p = cp_lexer_next_token_is (parser->lexer,
10330 [/i] CPP_OPEN_PAREN);
10331 [/i] declarator = cp_parser_direct_declarator (parser, dcl_kind,
10332 [/i] ctor_dtor_or_conv_p,
10333 [/i] member_p);
10334 [/i] }
10335 [/i]
10336 [/i] if (attributes && declarator != error_mark_node)
10337 [/i] declarator = tree_cons (attributes, declarator, NULL_TREE);
10338 [/i]
10339 [/i] return declarator;
10340 [/i]}

Declarator及abstract-declarator的语法如下:
declarator[/b]
├ ptr-operator declarator
├ direct-declarator
GNU Ext ├ attributes [opt] ptr-operator declarator
GNU Ext Ⅼ attributes [opt] director-declarator

abstract-declarator[/b]
├ ptr-operator abstract-declarator [opt]
├ direct-abstract-declarator
GNU Ext ├ attributes [opt] ptr-operator abstract-declarator [opt]
GNU Ext Ⅼ attributes [opt] direct-abstract-declarator
声明符可以是一个标识符,例如:“int j;”,或者direct- declarator,例如:“int (*pf)()”(跟在int[/i]后面的符号构成了一个direct-declarator,int[/i]本身是type-specifier);或者abstract- declarator,例如:“int (*)()”(跟在int[/i]后面的符号构成一个abstract-declarator,int[/i]本身是type-specifier,它们放在一起形成type-id)。
这里ptr-operator部分不出现。在10287行,cp_parser_ptr_operator[/i]使得在10291行的测试失败。

10378 [/i]static tree
10379 [/i]cp_parser_direct_declarator (cp_parser* parser, in parser.c[/i]
10380 [/i] cp_parser_declarator_kind dcl_kind,
10381 [/i] int* ctor_dtor_or_conv_p,
10382 [/i] bool member_p)
10383 [/i]{
10384 [/i] cp_token *token;
10385 [/i] tree declarator = NULL_TREE;
10386 [/i] tree scope = NULL_TREE;
10387 [/i] bool saved_default_arg_ok_p = parser->default_arg_ok_p;
10388 [/i] bool saved_in_declarator_p = parser->in_declarator_p;
10389 [/i] bool first = true;
10390 [/i] bool pop_p = false;
10391 [/i]
10392 [/i] while (true)
10393 [/i] {
10394 [/i] /* Peek at the next token. */
10395 [/i] token = cp_lexer_peek_token (parser->lexer);
10396 [/i] if (token->type == CPP_OPEN_PAREN)
10397 [/i] {

10537 [/i] }
10538 [/i] else if ((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
10539 [/i] && token->type == CPP_OPEN_SQUARE)
10540 [/i] {

10577 [/i] }
10578 [/i] else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
10579 [/i] {
10580 [/i] /* Parse a declarator-id */
10581 [/i] if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
10582 [/i] cp_parser_parse_tentatively (parser);
10583 [/i] declarator = cp_parser_declarator_id (parser);
10584 [/i] if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
10585 [/i] {

10593 [/i] }
10594 [/i]
10595 [/i] if (declarator == error_mark_node)
10596 [/i] break;
10597 [/i]
10598 [/i] if (TREE_CODE (declarator) == SCOPE_REF
10599 [/i] && !current_scope ())
10600 [/i] {

10636 [/i] }

注意到dcl_kind[/i]是CP_PARSER_DECLARATOR_NAMED,而第一次进入WHILE[/b]块时,first[/i]是true。亦即,如果第一个符号是CPP_NAME,应该表示是一个declarator-id。

10882 [/i]static tree
10883 [/i]cp_parser_declarator_id (cp_parser* parser) in parser.c[/i]
10884 [/i]{
10885 [/i] tree id_expression;
10886 [/i]
10887 [/i] /* The expression must be an id-expression. Assume that qualified
10888 [/i] names are the names of types so that:
10889 [/i]
10890 [/i] template <class T>
10891 [/i] int S<T>::R::i = 3;
10892 [/i]
10893 [/i] will work; we must treat `S<T>::R' as the name of a type.
10894 [/i] Similarly, assume that qualified names are templates, where
10895 [/i] required, so that:
10896 [/i]
10897 [/i] template <class T>
10898 [/i] int S<T>::R<T>::i = 3;
10899 [/i]
10900 [/i] will work, too. */
10901 [/i] id_expression = cp_parser_id_expression (parser,
10902 [/i] /*template_keyword_p=*/false,
10903 [/i] /*check_dependency_p=*/false,
10904 [/i] /*template_p=*/NULL,
10905 [/i] /*declarator_p=*/true);
10906 [/i] /* If the name was qualified, create a SCOPE_REF to represent
10907 [/i] that. */
10908 [/i] if (parser->scope && id_expression != error_mark_node)
10909 [/i] {
10910 [/i] id_expression = build_nt (SCOPE_REF, parser->scope, id_expression);
10911 [/i] parser->scope = NULL_TREE;
10912 [/i] }
10913 [/i]
10914 [/i] return id_expression;
10915 [/i]}

declarator-id[/b]
├ ::[opt][/i] nested-name-specifier [opt] type-name[/b]
id-expression[/b] ├ class-name[/b]
├ unqualified-id | ├ identifier[/i]
qualifier-id[/b] | Ⅼ template-id
├ ::[/i] identifier[/i] ├ enum-name[/b] --- identifier[/i]
├ ::[/i] operator-function-id Ⅼ typedef-name[/b] --- identifier[/i]
├ :: [opt][/i] nested-name-specifier [opt] template [opt][/i] unqualified-id
Ⅼ ::[/i] template-id[/b]
template-name[/b] <[/i]template-argument-list[/b] [opt]>[/i]
Ⅼ identifier[/i] ├ template-argument-list, template-argument
template-argument[/b]
├ assignment-expression
├ type-id
Ⅼ id-expression
从这个语法树,可以看到id-expression可能与其他规则中的declarator-id共享相同的前缀“::[opt] nested-name-specifier [opt]”。另外,id-expresion与type-name的多个规则重叠。看到前端首先尝试按id-expression来解析declarator-id。
unqualified-id[/b]
├ identifier[/i]
├ operator-function-id
├ conversion-function-id
├ template-id
Ⅼ ~[/i]class-name

2685 [/i]static tree
2686 [/i]cp_parser_id_expression (cp_parser *parser, in parser.c[/i]
2687 [/i] bool template_keyword_p,
2688 [/i] bool check_dependency_p,
2689 [/i] bool *template_p,
2690 [/i] bool declarator_p)
2691 [/i]{
2692 [/i] bool global_scope_p;
2693 [/i] bool nested_name_specifier_p;
2694 [/i]
2695 [/i] /* Assume the `template' keyword was not used. */
2696 [/i] if (template_p)
2697 [/i] *template_p = false;
2698 [/i]
2699 [/i] /* Look for the optional `::' operator. */
2700 [/i] global_scope_p
2701 [/i] = (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false)
2702 [/i] != NULL_TREE);
2703 [/i] /* Look for the optional nested-name-specifier. */
2704 [/i] nested_name_specifier_p
2705 [/i] = (cp_parser_nested_name_specifier_opt (parser,
2706 [/i] /*typename_keyword_p=*/false,
2707 [/i] check_dependency_p,
2708 [/i] /*type_p=*/false,
2709 [/i] declarator_p)
2710 [/i] != NULL_TREE);
2711 [/i] /* If there is a nested-name-specifier, then we are looking at
2712 [/i] the first qualified-id production. */
2713 [/i] if (nested_name_specifier_p)
2714 [/i] {

2740 [/i] }
2741 [/i] /* Otherwise, if we are in global scope, then we are looking at one
2742 [/i] of the other qualified-id productions. */
2743 [/i] else if (global_scope_p)
2744 [/i] {

2787 [/i] }
2788 [/i] else
2789 [/i] return cp_parser_unqualified_id (parser, template_keyword_p,
2790 [/i] /*check_dependency_p=*/true,
2791 [/i] declarator_p);
2792 [/i]}

对于例子中的构造函数,这个unqualifier-id是一个简单的标识符。

2816 [/i]static tree
2817 [/i]cp_parser_unqualified_id (cp_parser* parser, in parser.c[/i]
2818 [/i] bool template_keyword_p,
2819 [/i] bool check_dependency_p,
2820 [/i] bool declarator_p)
2821 [/i]{
2822 [/i] cp_token *token;
2823 [/i]
2824 [/i] /* Peek at the next token. */
2825 [/i] token = cp_lexer_peek_token (parser->lexer);
2826 [/i]
2827 [/i] switch (token->type)
2828 [/i] {
2829 [/i] case CPP_NAME:
2830 [/i] {
2831 [/i] tree id;
2832 [/i]
2833 [/i] /* We don't know yet whether or not this will be a
2834 [/i] template-id. */
2835 [/i] cp_parser_parse_tentatively (parser);
2836 [/i] /* Try a template-id. */
2837 [/i] id = cp_parser_template_id (parser, template_keyword_p,
2838 [/i] check_dependency_p,
2839 [/i] declarator_p);
2840 [/i] /* If it worked, we're done. */
2841 [/i] if (cp_parser_parse_definitely (parser))
2842 [/i] return id;
2843 [/i] /* Otherwise, it's an ordinary identifier. */
2844 [/i] return cp_parser_identifier (parser);
2845 [/i] }

3033 [/i] }
3034 [/i]}

在10583行,标识符“Lock”作为声明符取入declarator[/i]中。注意到在下面的10640行,ctor_dtor_or_conv_p[/i]是一个指针,现在它指向在cp_parser_member_declaration[/i]中12668行的变量ctor_dtor_or_conv_p[/i]。因为我们现在在类“Lock”中,满足10643行的条件。

cp_parser_direct_declarator (continue)

10638 [/i] /* Check to see whether the declarator-id names a constructor,
10639 [/i] destructor, or conversion. */
10640 [/i] if (declarator && ctor_dtor_or_conv_p
10641 [/i] && ((TREE_CODE (declarator) == SCOPE_REF
10642 [/i] && CLASS_TYPE_P (TREE_OPERAND (declarator, 0)))
10643 [/i] || (TREE_CODE (declarator) != SCOPE_REF
10644 [/i] && at_class_scope_p ())))
10645 [/i] {
10646 [/i] tree unqualified_name;
10647 [/i] tree class_type;
10648 [/i]
10649 [/i] /* Get the unqualified part of the name. */
10650 [/i] if (TREE_CODE (declarator) == SCOPE_REF)
10651 [/i] {
10652 [/i] class_type = TREE_OPERAND (declarator, 0);
10653 [/i] unqualified_name = TREE_OPERAND (declarator, 1);
10654 [/i] }
10655 [/i] else
10656 [/i] {
10657 [/i] class_type = current_class_type[/i];
10658 [/i] unqualified_name = declarator;
10659 [/i] }
10660 [/i]
10661 [/i] /* See if it names ctor, dtor or conv. */
10662 [/i] if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR
10663 [/i] || IDENTIFIER_TYPENAME_P (unqualified_name)
10664 [/i] || constructor_name_p (unqualified_name, class_type)
10665 [/i] || (TREE_CODE (unqualified_name) == TYPE_DECL
10666 [/i] && same_type_p (TREE_TYPE (unqualified_name),
10667 [/i] class_type)))
10668 [/i] *ctor_dtor_or_conv_p = -1;
10669 [/i] }
10670 [/i]
10671 [/i]handle_declarator:;
10672 [/i] scope = get_scope_of_declarator (declarator);
10673 [/i] if (scope)
10674 [/i] /* Any names that appear after the declarator-id for a
10675 [/i] member are looked up in the containing scope. */
10676 [/i] pop_p = push_scope (scope);
10677 [/i] parser->in_declarator_p = true;
10678 [/i] if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
10679 [/i] || (declarator
10680 [/i] && (TREE_CODE (declarator) == SCOPE_REF
10681 [/i] || TREE_CODE (declarator) == IDENTIFIER_NODE)))
10682 [/i] /* Default args are only allowed on function
10683 [/i] declarations. */
10684 [/i] parser->default_arg_ok_p = saved_default_arg_ok_p;
10685 [/i] else
10686 [/i] parser->default_arg_ok_p = false;
10687 [/i]
10688 [/i] first = false;
10689 [/i] }
10690 [/i] /* We're done. */
10691 [/i] else
10692 [/i] break;
10693 [/i] }
10694 [/i]
10695 [/i] /* For an abstract declarator, we might wind up with nothing at this
10696 [/i] point. That's an error; the declarator is not optional. */
10697 [/i] if (!declarator)
10698 [/i] cp_parser_error (parser, "expected declarator");
10699 [/i]
10700 [/i] /* If we entered a scope, we must exit it now. */
10701 [/i] if (pop_p)
10702 [/i] pop_scope (scope);
10703 [/i]
10704 [/i] parser->default_arg_ok_p = saved_default_arg_ok_p;
10705 [/i] parser->in_declarator_p = saved_in_declarator_p;
10706 [/i]
10707 [/i] return declarator;
10708 [/i]}

在这里ctor_dtor_or_conv_p[/i]用于检测构造函数,析构函数或转换操作符。如果该声明符是一个名字,它被设置为-1,如果是一个函数则是+1,否则就被设置为0。因此在10668行,ctor_dtor_or_conv_p[/i]被设置为-1。
进一步的,如果获得的声明符是SCOPE_REF,它指出了其后符号的绑定作用域,在处理后续符号之前,需要使得这个域成为当前作用域。在10672行,函数get_scope_of_declarator[/i] 检查是否有任何一个这样的域能从declarator[/i]获取,如果有,该函数返回相应的树节点。
注意在10677行的赋值,因为我们已经见到声明符,设置parser中的标记in_declarator_p[/i]来表明这个事实。这个标记将影响声明符后续符号的解析过程。对于我们的例子“Lock() {}”,“Lock”后面的符号是“(”。它将回到10392行的WHILE[/b]循环,并执行下面的代码。注意这里的member_p[/i]是true。

cp_parser_direct_declarator (continue)

10392 [/i] while (true)
10393 [/i] {
10394 [/i] /* Peek at the next token. */
10395 [/i] token = cp_lexer_peek_token (parser->lexer);
10396 [/i] if (token->type == CPP_OPEN_PAREN)
10397 [/i] {
10398 [/i] /* This is either a parameter-declaration-clause, or a
10399 [/i] parenthesized declarator. When we know we are parsing a
10400 [/i] named declarator, it must be a parenthesized declarator
10401 [/i] if FIRST is true. For instance, `(int)' is a
10402 [/i] parameter-declaration-clause, with an omitted
10403 [/i] direct-abstract-declarator. But `((*))', is a
10404 [/i] parenthesized abstract declarator. Finally, when T is a
10405 [/i] template parameter `(T)' is a
10406 [/i] parameter-declaration-clause, and not a parenthesized
10407 [/i] named declarator.
10408 [/i]
10409 [/i] We first try and parse a parameter-declaration-clause,
10410 [/i] and then try a nested declarator (if FIRST is true).
10411 [/i]
10412 [/i] It is not an error for it not to be a
10413 [/i] parameter-declaration-clause, even when FIRST is
10414 [/i] false. Consider,
10415 [/i]
10416 [/i] int i (int);
10417 [/i] int i (3);
10418 [/i]
10419 [/i] The first is the declaration of a function while the
10420 [/i] second is a the definition of a variable, including its
10421 [/i] initializer.
10422 [/i]
10423 [/i] Having seen only the parenthesis, we cannot know which of
10424 [/i] these two alternatives should be selected. Even more
10425 [/i] complex are examples like:
10426 [/i]
10427 [/i] int i (int (a));
10428 [/i] int i (int (3));
10429 [/i]
10430 [/i] The former is a function-declaration; the latter is a
10431 [/i] variable initialization.
10432 [/i]
10433 [/i] Thus again, we try a parameter-declaration-clause, and if
10434 [/i] that fails, we back out and return. */
10435 [/i]
10436 [/i] if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
10437 [/i] {
10438 [/i] tree params;
10439 [/i] unsigned saved_num_template_parameter_lists;
10440 [/i]
10441 [/i] /* In a member-declarator, the only valid interpretation
10442 [/i] of a parenthesis is the start of a
10443 [/i] parameter-declaration-clause. (It is invalid to
10444 [/i] initialize a static data member with a parenthesized
10445 [/i] initializer; only the "=" form of initialization is
10446 [/i] permitted.) */
10447 [/i] if (!member_p)
10448 [/i] cp_parser_parse_tentatively (parser);
10449 [/i]
10450 [/i] /* Consume the `('. */
10451 [/i] cp_lexer_consume_token (parser->lexer);
10452 [/i] if (first)
10453 [/i] {
10454 [/i] /* If this is going to be an abstract declarator, we're
10455 [/i] in a declarator and we can't have default args. */
10456 [/i] parser->default_arg_ok_p = false;
10457 [/i] parser->in_declarator_p = true;
10458 [/i] }
10459 [/i]
10460 [/i] /* Inside the function parameter list, surrounding
10461 [/i] template-parameter-lists do not apply. */
10462 [/i] saved_num_template_parameter_lists
10463 [/i] = parser->num_template_parameter_lists;
10464 [/i] parser->num_template_parameter_lists = 0;
10465 [/i]
10466 [/i] /* Parse the parameter-declaration-clause. */
10467 [/i] params = cp_parser_parameter_declaration_clause (parser);
10468 [/i]
10469 [/i] parser->num_template_parameter_lists
10470 [/i] = saved_num_template_parameter_lists;
10471 [/i]
10472 [/i] /* If all went well, parse the cv-qualifier-seq and the
10473 [/i] exception-specification. */
10474 [/i] if (member_p || cp_parser_parse_definitely (parser))
10475 [/i] {
10476 [/i] tree cv_qualifiers;
10477 [/i] tree exception_specification;
10478 [/i]
10479 [/i] if (ctor_dtor_or_conv_p)
10480 [/i] *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
10481 [/i] first = false;
10482 [/i] /* Consume the `)'. */
10483 [/i] cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
10484 [/i]
10485 [/i] /* Parse the cv-qualifier-seq. */
10486 [/i] cv_qualifiers = cp_parser_cv_qualifier_seq_opt (parser);
10487 [/i] /* And the exception-specification. */
10488 [/i] exception_specification
10489 [/i] = cp_parser_exception_specification_opt (parser);
10490 [/i]
10491 [/i] /* Create the function-declarator. */
10492 [/i] declarator = make_call_declarator (declarator,
10493 [/i] params,
10494 [/i] cv_qualifiers,
10495 [/i] exception_specification);
10496 [/i] /* Any subsequent parameter lists are to do with
10497 [/i] return type, so are not those of the declared
10498 [/i] function. */
10499 [/i] parser->default_arg_ok_p = false;
10500 [/i]
10501 [/i] /* Repeat the main loop. */
10502 [/i] continue;
10503 [/i] }
10504 [/i] }

看到后面的符号中没有参数,cv-qualifier-seq及exception-specification出现,仅执行make_call_declarator[/i]。

121 [/i]tree
122 [/i]make_call_declarator (tree target, tree parms, tree cv_qualifiers, in lex.c[/i]
123 [/i] tree exception_specification)
124 [/i]{
125 [/i] target = build_nt (CALL_EXPR, target,
126 [/i] tree_cons (parms, cv_qualifiers, NULL_TREE),
127 [/i] /* The third operand is really RTL. We
128 [/i] shouldn't put anything there. */
129 [/i] NULL_TREE);
130 [/i] CALL_DECLARATOR_EXCEPTION_SPEC (target) = exception_specification;
131 [/i] return target;
132 [/i]}

通过这个函数,为声明符创建了树节点CALL_EXPR。那么返回到cp_parser_declarator[/i]进一步把它连同可能出现的属性封装入另一个tree_list节点。当返回到cp_parser_member_declaration[/i]时,如下的节点将得到创建。
点此打开
图67:类“Lock”构造函数的CALL_EXPR
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: