📄 parse.y
字号:
else $$ = do_identifier ($$); } | CONSTANT | boolean.literal | string { $$ = combine_strings ($$); } | '(' expr ')' { char class; $$ = $2; class = TREE_CODE_CLASS (TREE_CODE ($$)); if (class == 'e' || class == '1' || class == '2' || class == '<') /* This inhibits warnings in truthvalue_conversion. */ C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); } | '(' expr_or_declarator ')' { char class; $$ = reparse_decl_as_expr (NULL_TREE, $2); class = TREE_CODE_CLASS (TREE_CODE ($$)); if (class == 'e' || class == '1' || class == '2' || class == '<') /* This inhibits warnings in truthvalue_conversion. */ C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); } | '(' error ')' { $$ = error_mark_node; } | '(' { if (current_function_decl == 0) { error ("braced-group within expression allowed only inside a function"); YYERROR; } keep_next_level (); $<ttype>$ = expand_start_stmt_expr (); } compstmt ')' { tree rtl_exp; if (pedantic) pedwarn ("ANSI C++ forbids braced-groups within expressions"); rtl_exp = expand_end_stmt_expr ($<ttype>2); /* The statements have side effects, so the group does. */ TREE_SIDE_EFFECTS (rtl_exp) = 1; if (TREE_CODE ($3) == BLOCK) { /* Make a BIND_EXPR for the BLOCK already made. */ $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp), NULL_TREE, rtl_exp, $3); /* Remove the block from the tree at this point. It gets put back at the proper place when the BIND_EXPR is expanded. */ delete_block ($3); } else $$ = $3; } | primary '(' nonnull_exprlist ')' { /* [eichin:19911016.1902EST] */ $<ttype>$ = build_x_function_call ($1, $3, current_class_decl); /* here we instantiate_class_template as needed... */ do_pending_templates (); } template_instantiate_some { if (TREE_CODE ($<ttype>5) == CALL_EXPR && TREE_TYPE ($<ttype>5) != void_type_node) $$ = require_complete_type ($<ttype>5); else $$ = $<ttype>5; } | primary LEFT_RIGHT { $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); if (TREE_CODE ($$) == CALL_EXPR && TREE_TYPE ($$) != void_type_node) $$ = require_complete_type ($$); } | primary '[' expr ']' { $$ = grok_array_decl ($$, $3); } | primary PLUSPLUS { /* If we get an OFFSET_REF, turn it into what it really means (e.g., a COMPONENT_REF). This way if we've got, say, a reference to a static member that's being operated on, we don't end up trying to find a member operator for the class it's in. */ if (TREE_CODE ($$) == OFFSET_REF) $$ = resolve_offset_ref ($$); $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } | primary MINUSMINUS { if (TREE_CODE ($$) == OFFSET_REF) $$ = resolve_offset_ref ($$); $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } /* C++ extensions */ | THIS { if (current_class_decl) {#ifdef WARNING_ABOUT_CCD TREE_USED (current_class_decl) = 1;#endif $$ = current_class_decl; } else if (current_function_decl && DECL_STATIC_FUNCTION_P (current_function_decl)) { error ("`this' is unavailable for static member functions"); $$ = error_mark_node; } else { if (current_function_decl) error ("invalid use of `this' in non-member function"); else error ("invalid use of `this' at top level"); $$ = error_mark_node; } } | TYPE_QUAL '(' nonnull_exprlist ')' { tree type; tree id = $$; /* This is a C cast in C++'s `functional' notation. */ if ($3 == error_mark_node) { $$ = error_mark_node; break; }#if 0 if ($3 == NULL_TREE) { error ("cannot cast null list to type `%s'", IDENTIFIER_POINTER (TYPE_NAME (id))); $$ = error_mark_node; break; }#endif#if 0 /* type is not set! (mrs) */ if (type == error_mark_node) $$ = error_mark_node; else#endif { if (id == ridpointers[(int) RID_CONST]) type = build_type_variant (integer_type_node, 1, 0); else if (id == ridpointers[(int) RID_VOLATILE]) type = build_type_variant (integer_type_node, 0, 1);#if 0 /* should not be able to get here (mrs) */ else if (id == ridpointers[(int) RID_FRIEND]) { error ("cannot cast expression to `friend' type"); $$ = error_mark_node; break; }#endif else my_friendly_abort (79); $$ = build_c_cast (type, build_compound_expr ($3), 1); } } | functional_cast | DYNAMIC_CAST '<' { dont_allow_type_definitions = "inside dynamic_cast"; } type_id '>' { dont_allow_type_definitions = 0; } '(' expr ')' { tree type = groktypename ($4); $$ = build_dynamic_cast (type, $8); } | STATIC_CAST '<' { dont_allow_type_definitions = "inside static_cast"; } type_id '>' { dont_allow_type_definitions = 0; } '(' expr ')' { tree type = groktypename ($4); $$ = build_static_cast (type, $8); } | REINTERPRET_CAST '<' { dont_allow_type_definitions = "inside reinterpret_cast"; } type_id '>' { dont_allow_type_definitions = 0; } '(' expr ')' { tree type = groktypename ($4); $$ = build_reinterpret_cast (type, $8); } | CONST_CAST '<' { dont_allow_type_definitions = "inside const_cast"; } type_id '>' { dont_allow_type_definitions = 0; } '(' expr ')' { tree type = groktypename ($4); $$ = build_const_cast (type, $8); } | TYPEID '(' expr ')' { $$ = build_typeid ($3); } | TYPEID '(' type_id ')' { tree type = groktypename ($3); $$ = get_typeid (TYPE_MAIN_VARIANT (type)); } | global_scope IDENTIFIER { do_scoped_id: $$ = IDENTIFIER_GLOBAL_VALUE ($2); if (yychar == YYEMPTY) yychar = YYLEX; if (! $$) { if (yychar == '(' || yychar == LEFT_RIGHT) $$ = implicitly_declare ($2); else { if (IDENTIFIER_GLOBAL_VALUE ($2) != error_mark_node) error ("undeclared variable `%s' (first use here)", IDENTIFIER_POINTER ($2)); $$ = error_mark_node; /* Prevent repeated error messages. */ IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node; } } else { if (TREE_CODE ($$) == ADDR_EXPR) assemble_external (TREE_OPERAND ($$, 0)); else assemble_external ($$); TREE_USED ($$) = 1; } if (TREE_CODE ($$) == CONST_DECL) { /* XXX CHS - should we set TREE_USED of the constant? */ $$ = DECL_INITIAL ($$); /* This is to prevent an enum whose value is 0 from being considered a null pointer constant. */ $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$); TREE_CONSTANT ($$) = 1; } } | global_scope operator_name { got_scope = NULL_TREE; if (TREE_CODE ($2) == IDENTIFIER_NODE) goto do_scoped_id; $$ = $2; } | overqualified_id %prec HYPERUNARY { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); } | overqualified_id '(' nonnull_exprlist ')' { $$ = build_member_call (OP0 ($$), OP1 ($$), $3); } | overqualified_id LEFT_RIGHT { $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); } | object unqualified_id %prec UNARY { got_object = NULL_TREE; $$ = build_component_ref ($$, $2, NULL_TREE, 1); } | object overqualified_id %prec UNARY { got_object = NULL_TREE; $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); } | object unqualified_id '(' nonnull_exprlist ')' { got_object = NULL_TREE;#if 0 /* This is a future direction of this code, but because build_x_function_call cannot always undo what is done in build_component_ref entirely yet, we cannot do this. */ $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4, $$); if (TREE_CODE ($$) == CALL_EXPR && TREE_TYPE ($$) != void_type_node) $$ = require_complete_type ($$);#else $$ = build_method_call ($$, $2, $4, NULL_TREE, (LOOKUP_NORMAL|LOOKUP_AGGR));#endif } | object unqualified_id LEFT_RIGHT { got_object = NULL_TREE;#if 0 /* This is a future direction of this code, but because build_x_function_call cannot always undo what is done in build_component_ref entirely yet, we cannot do this. */ $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE, $$); if (TREE_CODE ($$) == CALL_EXPR && TREE_TYPE ($$) != void_type_node) $$ = require_complete_type ($$);#else $$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE, (LOOKUP_NORMAL|LOOKUP_AGGR));#endif } | object overqualified_id '(' nonnull_exprlist ')' { got_object = NULL_TREE; if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2)))) { warning ("signature name in scope resolution ignored"); $$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE, (LOOKUP_NORMAL|LOOKUP_AGGR)); } else $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4); } | object overqualified_id LEFT_RIGHT { got_object = NULL_TREE; if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2)))) { warning ("signature name in scope resolution ignored"); $$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE, (LOOKUP_NORMAL|LOOKUP_AGGR)); } else $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), NULL_TREE); } /* p->int::~int() is valid -- 12.4 */ | object '~' TYPESPEC LEFT_RIGHT { got_object = NULL_TREE; if (IDENTIFIER_GLOBAL_VALUE ($3) && (TREE_CODE (TREE_TYPE ($1)) != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3))))) cp_error ("`%E' is not of type `%T'", $1, $3); $$ = convert (void_type_node, $1); } | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT { got_object = NULL_TREE; if ($2 != $5) cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5); if (TREE_CODE (TREE_TYPE ($1)) != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2)))) cp_error ("`%E' is not of type `%T'", $1, $2); $$ = convert (void_type_node, $1); } | object error { got_object = NULL_TREE; $$ = error_mark_node; } ;/* Not needed for now.primary_no_id: '(' expr ')' { $$ = $2; } | '(' error ')' { $$ = error_mark_node; } | '(' { if (current_function_decl == 0) { error ("braced-group within expression allowed only inside a function"); YYERROR; } $<ttype>$ = expand_start_stmt_expr (); } compstmt ')' { if (pedantic) pedwarn ("ANSI C++ forbids braced-groups within expressions"); $$ = expand_end_stmt_expr ($<ttype>2); } | primary_no_id '(' nonnull_exprlist ')' { $$ = build_x_function_call ($$, $3, current_class_decl); } | primary_no_id LEFT_RIGHT { $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); } | primary_no_id '[' expr ']' { goto do_array; } | primary_no_id PLUSPLUS { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } | primary_no_id MINUSMINUS { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } | SCOPE IDENTIFIER { goto do_scoped_id; } | SCOPE operator_name { if (TREE_CODE ($2) == IDENTIFIER_NODE) goto do_scoped_id; goto do_scoped_operator; } ;*/new: NEW { $$ = 0; } | global_scope NEW { got_scope = NULL_TREE; $$ = 1; } ;delete: DELETE { $$ = 0; } | global_scope delete { got_scope = NULL_TREE; $$ = 1; } ;boolean.literal: CXX_TRUE { $$ = boolean_true_node; } | CXX_FALSE { $$ = boolean_false_node; } ;/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */string: STRING | string STRING { $$ = chainon ($$, $2); } ;nodecls: /* empty */ { if (! current_function_parms_stored) store_parm_decls (); setup_vtbl_ptr (); /* Always keep the BLOCK node associated with the outermost pair of curley braces of a function. These are needed for correct operation of dwarfout.c. */ keep_next_level (); } ;object: primary '.' { got_object = TREE_TYPE ($$); } | primary POINTSAT { $$ = build_x_arrow ($$); got_object = TREE_TYPE ($$); } ;decl: /* Normal case: make this fast. */ typespec declarator ';' { tree d = get_decl_list ($1); int yes = suspend_momentary (); d = start_decl ($2, d, 0, NULL_TREE); cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); resume_momentary (yes); if (IS_AGGR_TYPE_CODE (TREE_CODE ($1))) note_got_semicolon ($1); } | typed_declspecs declarator ';' { tree d, specs, attrs; int yes; split_specs_attrs ($1, &specs, &attrs); yes = suspend_momentary (); d = start_decl ($2, specs, 0, NULL_TREE); cplus_decl_attributes (d, NULL_TREE, attrs); cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); resume_momentary (yes); note_list_got_semicolon ($1); } | typespec initdecls ';'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -