📄 decl2.c
字号:
error ("field declaration not allowed in signature"); return void_type_node; } if (DECL_IN_AGGR_P (value)) { cp_error ("`%D' is already defined in `%T'", value, DECL_CONTEXT (value)); return void_type_node; } if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); if (init) { if (IS_SIGNATURE (current_class_type) && TREE_CODE (value) == FUNCTION_DECL) { error ("function declarations cannot have initializers in signature"); init = NULL_TREE; } else if (TREE_CODE (value) == FUNCTION_DECL) { grok_function_init (value, init); init = NULL_TREE; } else if (pedantic && TREE_CODE (value) != VAR_DECL) /* Already complained in grokdeclarator. */ init = NULL_TREE; else { /* We allow initializers to become parameters to base initializers. */ if (TREE_CODE (init) == TREE_LIST) { if (TREE_CHAIN (init) == NULL_TREE) init = TREE_VALUE (init); else init = digest_init (TREE_TYPE (value), init, (tree *)0); } if (TREE_CODE (init) == CONST_DECL) init = DECL_INITIAL (init); else if (TREE_READONLY_DECL_P (init)) init = decl_constant_value (init); else if (TREE_CODE (init) == CONSTRUCTOR) init = digest_init (TREE_TYPE (value), init, (tree *)0); my_friendly_assert (TREE_PERMANENT (init), 192); if (init == error_mark_node) /* We must make this look different than `error_mark_node' because `decl_const_value' would mis-interpret it as only meaning that this VAR_DECL is defined. */ init = build1 (NOP_EXPR, TREE_TYPE (value), init); else if (processing_template_decl) ; else if (! TREE_CONSTANT (init)) { /* We can allow references to things that are effectively static, since references are initialized with the address. */ if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE || (TREE_STATIC (init) == 0 && (TREE_CODE_CLASS (TREE_CODE (init)) != 'd' || DECL_EXTERNAL (init) == 0))) { error ("field initializer is not constant"); init = error_mark_node; } } } } /* The corresponding pop_obstacks is in cp_finish_decl. */ push_obstacks_nochange (); if (processing_template_decl && ! current_function_decl && (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL)) value = push_template_decl (value); if (attrlist) cplus_decl_attributes (value, TREE_PURPOSE (attrlist), TREE_VALUE (attrlist)); if (TREE_CODE (value) == VAR_DECL) { finish_static_data_member_decl (value, init, asmspec_tree, /*need_pop=*/1, flags); return value; } if (TREE_CODE (value) == FIELD_DECL) { if (asmspec) { /* This must override the asm specifier which was placed by grokclassfn. Lay this out fresh. */ DECL_RTL (value) = NULL_RTX; DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); } if (DECL_INITIAL (value) == error_mark_node) init = error_mark_node; cp_finish_decl (value, init, asmspec_tree, 1, flags); DECL_INITIAL (value) = init; DECL_IN_AGGR_P (value) = 1; return value; } if (TREE_CODE (value) == FUNCTION_DECL) { if (asmspec) { /* This must override the asm specifier which was placed by grokclassfn. Lay this out fresh. */ DECL_RTL (value) = NULL_RTX; DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); } cp_finish_decl (value, init, asmspec_tree, 1, flags); /* Pass friends back this way. */ if (DECL_FRIEND_P (value)) return void_type_node;#if 0 /* Just because a fn is declared doesn't mean we'll try to define it. */ if (current_function_decl && ! IS_SIGNATURE (current_class_type)) cp_error ("method `%#D' of local class must be defined in class body", value);#endif DECL_IN_AGGR_P (value) = 1; return value; } my_friendly_abort (21); /* NOTREACHED */ return NULL_TREE;}/* Like `grokfield', but for bitfields. WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */treegrokbitfield (declarator, declspecs, width) tree declarator, declspecs, width;{ register tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL_TREE); if (! value) return NULL_TREE; /* friends went bad. */ /* Pass friendly classes back. */ if (TREE_CODE (value) == VOID_TYPE) return void_type_node; if (TREE_CODE (value) == TYPE_DECL) { cp_error ("cannot declare `%D' to be a bitfield type", value); return NULL_TREE; } /* Usually, finish_struct_1 catches bitifields with invalid types. But, in the case of bitfields with function type, we confuse ourselves into thinking they are member functions, so we must check here. */ if (TREE_CODE (value) == FUNCTION_DECL) { cp_error ("cannot declare bitfield `%D' with funcion type", DECL_NAME (value)); return NULL_TREE; } if (IS_SIGNATURE (current_class_type)) { error ("field declaration not allowed in signature"); return void_type_node; } if (DECL_IN_AGGR_P (value)) { cp_error ("`%D' is already defined in the class %T", value, DECL_CONTEXT (value)); return void_type_node; } GNU_xref_member (current_class_name, value); if (TREE_STATIC (value)) { cp_error ("static member `%D' cannot be a bitfield", value); return NULL_TREE; } cp_finish_decl (value, NULL_TREE, NULL_TREE, 0, 0); if (width != error_mark_node) { constant_expression_warning (width); DECL_INITIAL (value) = width; SET_DECL_C_BIT_FIELD (value); } DECL_IN_AGGR_P (value) = 1; return value;}treegrokoptypename (declspecs, declarator) tree declspecs, declarator;{ tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE); return build_typename_overload (t);}/* When a function is declared with an initializer, do the right thing. Currently, there are two possibilities: class B { public: // initialization possibility #1. virtual void f () = 0; int g (); }; class D1 : B { public: int d1; // error, no f (); }; class D2 : B { public: int d2; void f (); }; class D3 : B { public: int d3; // initialization possibility #2 void f () = B::f; };*/intcopy_assignment_arg_p (parmtype, virtualp) tree parmtype; int virtualp ATTRIBUTE_UNUSED;{ if (current_class_type == NULL_TREE) return 0; if (TREE_CODE (parmtype) == REFERENCE_TYPE) parmtype = TREE_TYPE (parmtype); if ((TYPE_MAIN_VARIANT (parmtype) == current_class_type)#if 0 /* Non-standard hack to support old Booch components. */ || (! virtualp && DERIVED_FROM_P (parmtype, current_class_type))#endif ) return 1; return 0;}static voidgrok_function_init (decl, init) tree decl; tree init;{ /* An initializer for a function tells how this function should be inherited. */ tree type = TREE_TYPE (decl); if (TREE_CODE (type) == FUNCTION_TYPE) cp_error ("initializer specified for non-member function `%D'", decl);#if 0 /* We'll check for this in finish_struct_1. */ else if (DECL_VINDEX (decl) == NULL_TREE) cp_error ("initializer specified for non-virtual method `%D'", decl);#endif else if (integer_zerop (init)) {#if 0 /* Mark this function as being "defined". */ DECL_INITIAL (decl) = error_mark_node; /* pure virtual destructors must be defined. */ /* pure virtual needs to be defined (as abort) only when put in vtbl. For wellformed call, it should be itself. pr4737 */ if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))) { extern tree abort_fndecl; /* Give this node rtl from `abort'. */ DECL_RTL (decl) = DECL_RTL (abort_fndecl); }#endif DECL_ABSTRACT_VIRTUAL_P (decl) = 1; if (DECL_NAME (decl) == ansi_opname [(int) MODIFY_EXPR]) { tree parmtype = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))); if (copy_assignment_arg_p (parmtype, 1)) TYPE_HAS_ABSTRACT_ASSIGN_REF (current_class_type) = 1; } } else cp_error ("invalid initializer for virtual method `%D'", decl);}voidcplus_decl_attributes (decl, attributes, prefix_attributes) tree decl, attributes, prefix_attributes;{ if (decl == NULL_TREE || decl == void_type_node) return; if (TREE_CODE (decl) == TEMPLATE_DECL) decl = DECL_TEMPLATE_RESULT (decl); decl_attributes (decl, attributes, prefix_attributes); if (TREE_CODE (decl) == TYPE_DECL) SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl), TREE_TYPE (decl));}/* CONSTRUCTOR_NAME: Return the name for the constructor (or destructor) for the specified class. Argument can be RECORD_TYPE, TYPE_DECL, or IDENTIFIER_NODE. When given a template, this routine doesn't lose the specialization. */treeconstructor_name_full (thing) tree thing;{ if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM || TREE_CODE (thing) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (thing) == TYPENAME_TYPE) thing = TYPE_NAME (thing); else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing))) { if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing)) thing = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0))); else thing = TYPE_NAME (thing); } if (TREE_CODE (thing) == TYPE_DECL || (TREE_CODE (thing) == TEMPLATE_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (thing)) == TYPE_DECL)) thing = DECL_NAME (thing); my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197); return thing;}/* CONSTRUCTOR_NAME: Return the name for the constructor (or destructor) for the specified class. Argument can be RECORD_TYPE, TYPE_DECL, or IDENTIFIER_NODE. When given a template, return the plain unspecialized name. */treeconstructor_name (thing) tree thing;{ tree t; thing = constructor_name_full (thing); t = IDENTIFIER_TEMPLATE (thing); if (!t) return thing; return t;}/* Cache the value of this class's main virtual function table pointer in a register variable. This will save one indirection if a more than one virtual function call is made this function. */voidsetup_vtbl_ptr (){ extern tree base_init_expr; if (base_init_expr == 0 && DECL_CONSTRUCTOR_P (current_function_decl)) { if (processing_template_decl) add_tree (build_min_nt (CTOR_INITIALIZER, current_member_init_list, current_base_init_list)); else emit_base_init (current_class_type, 0); }}/* Record the existence of an addressable inline function. */voidmark_inline_for_output (decl) tree decl;{ decl = DECL_MAIN_VARIANT (decl); if (DECL_SAVED_INLINE (decl)) return; my_friendly_assert (TREE_PERMANENT (decl), 363); DECL_SAVED_INLINE (decl) = 1; if (!saved_inlines) VARRAY_TREE_INIT (saved_inlines, 32, "saved_inlines"); if (saved_inlines_used == saved_inlines->num_elements) VARRAY_GROW (saved_inlines, 2 * saved_inlines->num_elements); VARRAY_TREE (saved_inlines, saved_inlines_used) = decl; ++saved_inlines_used;}voidclear_temp_name (){ temp_name_counter = 0;}/* Hand off a unique name which can be used for variable we don't really want to know about anyway, for example, the anonymous variables which are needed to make references work. Declare this thing so we can use it. The variable created will be of type TYPE. STATICP is nonzero if this variable should be static. */treeget_temp_name (typ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -