📄 parse.y
字号:
template_parm { $$ = process_template_parm (NULL_TREE, $1); } | template_parm_list ',' template_parm { $$ = process_template_parm ($1, $3); } ;template_type_parm: aggr { $$ = build_tree_list ($1, NULL_TREE); ttpa: if (TREE_PURPOSE ($$) == signature_type_node) sorry ("signature as template type parameter"); else if (TREE_PURPOSE ($$) != class_type_node) { pedwarn ("template type parameters must use the keyword `class'"); TREE_PURPOSE ($$) = class_type_node; } } | aggr identifier { $$ = build_tree_list ($1, $2); goto ttpa; } | TYPENAME_KEYWORD { $$ = build_tree_list (class_type_node, NULL_TREE); } | TYPENAME_KEYWORD identifier { $$ = build_tree_list (class_type_node, $2); } ;template_parm: /* The following rules introduce a new reduce/reduce conflict on the ',' and '>' input tokens: they are valid prefixes for a `structsp', which means they could match a nameless parameter. See 14.6, paragraph 3. By putting them before the `parm' rule, we get their match before considering them nameless parameter declarations. */ template_type_parm { $$ = build_tree_list (NULL_TREE, $1); } | template_type_parm '=' type_id { $$ = build_tree_list (groktypename ($3.t), $1); } | parm { $$ = build_tree_list (NULL_TREE, $1.t); } | parm '=' expr_no_commas %prec ARITHCOMPARE { $$ = build_tree_list ($3, $1.t); } ;template_def: template_header extdef { if ($1) end_template_decl (); else end_specialization (); } | template_header error %prec EMPTY { if ($1) end_template_decl (); else end_specialization (); } ;datadef: nomods_initdecls ';' {} | declmods notype_initdecls ';' {} | typed_declspecs initdecls ';' { note_list_got_semicolon ($1.t); } | declmods ';' { pedwarn ("empty declaration"); } | explicit_instantiation ';' | typed_declspecs ';' { tree t, attrs; split_specs_attrs ($1.t, &t, &attrs); shadow_tag (t); note_list_got_semicolon ($1.t); } | error ';' | error '}' | ';' ;ctor_initializer_opt: nodecls { $$ = 0; } | base_init { $$ = 1; } ;maybe_return_init: /* empty */ | return_init | return_init ';' ;eat_saved_input: /* empty */ | END_OF_SAVED_INPUT ;fndef: fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error { finish_function (lineno, (int)$3, 0); } | fn.def1 maybe_return_init function_try_block { } | fn.def1 maybe_return_init error { } ;constructor_declarator: nested_name_specifier SELFNAME '(' { $$ = build_parse_node (SCOPE_REF, $1, $2); if ($1 != current_class_type) { push_nested_class ($1, 3); TREE_COMPLEXITY ($$) = current_class_depth; } } parmlist ')' cv_qualifiers exception_specification_opt { $$ = make_call_declarator ($<ttype>4, $5, $7, $8); } | nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt { $$ = build_parse_node (SCOPE_REF, $1, $2); if ($1 != current_class_type) { push_nested_class ($1, 3); TREE_COMPLEXITY ($$) = current_class_depth; } $$ = make_call_declarator ($$, empty_parms (), $4, $5); } | global_scope nested_name_specifier SELFNAME '(' { $$ = build_parse_node (SCOPE_REF, $2, $3); if ($2 != current_class_type) { push_nested_class ($2, 3); TREE_COMPLEXITY ($$) = current_class_depth; } } parmlist ')' cv_qualifiers exception_specification_opt { $$ = make_call_declarator ($<ttype>5, $6, $8, $9); } | global_scope nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt { $$ = build_parse_node (SCOPE_REF, $2, $3); if ($2 != current_class_type) { push_nested_class ($2, 3); TREE_COMPLEXITY ($$) = current_class_depth; } $$ = make_call_declarator ($$, empty_parms (), $5, $6); } | nested_name_specifier self_template_type '(' { $$ = build_parse_node (SCOPE_REF, $1, $2); if ($1 != current_class_type) { push_nested_class ($1, 3); TREE_COMPLEXITY ($$) = current_class_depth; } } parmlist ')' cv_qualifiers exception_specification_opt { $$ = make_call_declarator ($<ttype>4, $5, $7, $8); } | nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt { $$ = build_parse_node (SCOPE_REF, $1, $2); if ($1 != current_class_type) { push_nested_class ($1, 3); TREE_COMPLEXITY ($$) = current_class_depth; } $$ = make_call_declarator ($$, empty_parms (), $4, $5); } | global_scope nested_name_specifier self_template_type '(' { $$ = build_parse_node (SCOPE_REF, $2, $3); if ($2 != current_class_type) { push_nested_class ($2, 3); TREE_COMPLEXITY ($$) = current_class_depth; } } parmlist ')' cv_qualifiers exception_specification_opt { $$ = make_call_declarator ($<ttype>5, $6, $8, $9); } | global_scope nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt { $$ = build_parse_node (SCOPE_REF, $2, $3); if ($2 != current_class_type) { push_nested_class ($2, 3); TREE_COMPLEXITY ($$) = current_class_depth; } $$ = make_call_declarator ($$, empty_parms (), $5, $6); } ;fn.def1: typed_declspecs declarator { tree specs, attrs; split_specs_attrs ($1.t, &specs, &attrs); if (! start_function (specs, $2, attrs, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } | declmods notype_declarator { tree specs, attrs; split_specs_attrs ($1, &specs, &attrs); if (! start_function (specs, $2, attrs, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } | notype_declarator { if (! start_function (NULL_TREE, $$, NULL_TREE, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } | declmods constructor_declarator { tree specs, attrs; split_specs_attrs ($1, &specs, &attrs); if (! start_function (specs, $2, attrs, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } | constructor_declarator { if (! start_function (NULL_TREE, $$, NULL_TREE, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } ;component_constructor_declarator: SELFNAME '(' parmlist ')' cv_qualifiers exception_specification_opt { $$ = make_call_declarator ($1, $3, $5, $6); } | SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt { $$ = make_call_declarator ($1, empty_parms (), $3, $4); } | self_template_type '(' parmlist ')' cv_qualifiers exception_specification_opt { $$ = make_call_declarator ($1, $3, $5, $6); } | self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt { $$ = make_call_declarator ($1, empty_parms (), $3, $4); } ;/* more C++ complexity. See component_decl for a comment on the reduce/reduce conflict introduced by these rules. */fn.def2: declmods component_constructor_declarator { tree specs = strip_attrs ($1); $$ = start_method (specs, $2); rest_of_mdef: if (! $$) YYERROR1; if (yychar == YYEMPTY) yychar = YYLEX; reinit_parse_for_method (yychar, $$); } | component_constructor_declarator { $$ = start_method (NULL_TREE, $1); goto rest_of_mdef; } | typed_declspecs declarator { tree specs = strip_attrs ($1.t); $$ = start_method (specs, $2); goto rest_of_mdef; } | declmods notype_declarator { tree specs = strip_attrs ($1); $$ = start_method (specs, $2); goto rest_of_mdef; } | notype_declarator { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } | declmods constructor_declarator { tree specs = strip_attrs ($1); $$ = start_method (specs, $2); goto rest_of_mdef; } | constructor_declarator { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } | template_header fn.def2 { if ($1) end_template_decl (); else end_specialization (); if ($2 && DECL_TEMPLATE_INFO ($2) && !DECL_TEMPLATE_SPECIALIZATION ($2)) { $$ = DECL_TI_TEMPLATE ($2); check_member_template ($$); } else if ($2) $$ = $2; else { cp_error("invalid member template declaration"); $$ = NULL_TREE; } } ;return_id: RETURN IDENTIFIER { if (! current_function_parms_stored) store_parm_decls (); $$ = $2; } ;return_init: return_id maybe_init { store_return_init ($<ttype>$, $2); } | return_id '(' nonnull_exprlist ')' { store_return_init ($<ttype>$, $3); } | return_id LEFT_RIGHT { store_return_init ($<ttype>$, NULL_TREE); } ;base_init: ':' .set_base_init member_init_list { if ($3 == 0) error ("no base initializers given following ':'"); setup_vtbl_ptr (); /* Always keep the BLOCK node associated with the outermost pair of curly braces of a function. These are needed for correct operation of dwarfout.c. */ keep_next_level (); } ;.set_base_init: /* empty */ { if (! current_function_parms_stored) store_parm_decls (); if (DECL_CONSTRUCTOR_P (current_function_decl)) { /* Make a contour for the initializer list. */ pushlevel (0); clear_last_expr (); expand_start_bindings (0); } else if (current_class_type == NULL_TREE) error ("base initializers not allowed for non-member functions"); else if (! DECL_CONSTRUCTOR_P (current_function_decl)) error ("only constructors take base initializers"); } ;member_init_list: /* empty */ { $$ = 0; } | member_init { $$ = 1; } | member_init_list ',' member_init | member_init_list error ;member_init: '(' nonnull_exprlist ')' { if (current_class_name) pedwarn ("anachronistic old style base class initializer"); expand_member_init (current_class_ref, NULL_TREE, $2); } | LEFT_RIGHT { if (current_class_name) pedwarn ("anachronistic old style base class initializer"); expand_member_init (current_class_ref, NULL_TREE, void_type_node); } | notype_identifier '(' nonnull_exprlist ')' { expand_member_init (current_class_ref, $1, $3); } | notype_identifier LEFT_RIGHT { expand_member_init (current_class_ref, $1, void_type_node); } | nonnested_type '(' nonnull_exprlist ')' { expand_member_init (current_class_ref, $1, $3); } | nonnested_type LEFT_RIGHT { expand_member_init (current_class_ref, $1, void_type_node); } | typename_sub '(' nonnull_exprlist ')' { expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1), $3); } | typename_sub LEFT_RIGHT { expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1), void_type_node); } ;identifier: IDENTIFIER | TYPENAME | SELFNAME | PTYPENAME | NSNAME ;notype_identifier: IDENTIFIER | PTYPENAME | NSNAME %prec EMPTY ;identifier_defn: IDENTIFIER_DEFN | TYPENAME_DEFN | PTYPENAME_DEFN ;explicit_instantiation: TEMPLATE typespec ';' { do_type_instantiation ($2.t, NULL_TREE); yyungetc (';', 1); } | TEMPLATE typed_declspecs declarator { tree specs = strip_attrs ($2.t); do_decl_instantiation (specs, $3, NULL_TREE); } | TEMPLATE notype_declarator { do_decl_instantiation (NULL_TREE, $2, NULL_TREE); } | TEMPLATE constructor_declarator { do_decl_instantiation (NULL_TREE, $2, NULL_TREE); } | SCSPEC TEMPLATE typespec ';' { do_type_instantiation ($3.t, $1); yyungetc (';', 1); } | SCSPEC TEMPLATE typed_declspecs declarator { tree specs = strip_attrs ($3.t); do_decl_instantiation (specs, $4, $1); } | SCSPEC TEMPLATE notype_declarator { do_decl_instantiation (NULL_TREE, $3, $1); } | SCSPEC TEMPLATE constructor_declarator { do_decl_instantiation (NULL_TREE, $3, $1); } ;/* The TYPENAME expansions are to deal with use of a template class name as a template within the class itself, where the template decl is hidden by a type decl. Got all that? */template_type: PTYPENAME '<' template_arg_list template_close_bracket { $$ = lookup_template_class ($1, $3, NULL_TREE); if ($$ != error_mark_node) $$ = TYPE_STUB_DECL ($$); } | PTYPENAME '<' template_close_bracket { $$ = lookup_template_class ($1, NULL_TREE, NULL_TREE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -