📄 typeck2.c
字号:
{ cp_error ("variable-sized object of type `%T' may not be initialized", type); return error_mark_node; } if (code == ARRAY_TYPE || code == RECORD_TYPE || code == UNION_TYPE) { if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)) { cp_error ("subobject of type `%T' must be initialized by constructor, not by `%E'", type, init); return error_mark_node; } else if (raw_constructor) return process_init_constructor (type, init, (tree *)0); else if (can_convert_arg (type, TREE_TYPE (init), init) || TYPE_NON_AGGREGATE_CLASS (type)) /* These are never initialized from multiple constructor elements. */; else if (tail != 0) { *tail = old_tail_contents; return process_init_constructor (type, 0, tail); } if (code != ARRAY_TYPE) { int flags = LOOKUP_NORMAL; /* Initialization from { } is copy-initialization. */ if (tail) flags |= LOOKUP_ONLYCONVERTING; return convert_for_initialization (NULL_TREE, type, init, flags, "initialization", NULL_TREE, 0); } } error ("invalid initializer"); return error_mark_node;}/* Process a constructor for a variable of type TYPE. The constructor elements may be specified either with INIT or with ELTS, only one of which should be non-null. If INIT is specified, it is a CONSTRUCTOR node which is specifically and solely for initializing this datum. If ELTS is specified, it is the address of a variable containing a list of expressions. We take as many elements as we need from the head of the list and update the list. In the resulting constructor, TREE_CONSTANT is set if all elts are constant, and TREE_STATIC is set if, in addition, all elts are simple enough constants that the assembler and linker can compute them. */static treeprocess_init_constructor (type, init, elts) tree type, init, *elts;{ register tree tail; /* List of the elements of the result constructor, in reverse order. */ register tree members = NULL; register tree next1; tree result; int allconstant = 1; int allsimple = 1; int erroneous = 0; /* Make TAIL be the list of elements to use for the initialization, no matter how the data was given to us. */ if (elts) { if (warn_missing_braces) warning ("aggregate has a partly bracketed initializer"); tail = *elts; } else tail = CONSTRUCTOR_ELTS (init); /* Gobble as many elements as needed, and make a constructor or initial value for each element of this aggregate. Chain them together in result. If there are too few, use 0 for each scalar ultimate component. */ if (TREE_CODE (type) == ARRAY_TYPE) { tree domain = TYPE_DOMAIN (type); register long len; register int i; if (domain) len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain)) - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain)) + 1); else len = -1; /* Take as many as there are */ for (i = 0; len < 0 || i < len; i++) { if (tail) { if (TREE_PURPOSE (tail) && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST || TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i)) sorry ("non-trivial labeled initializers"); if (TREE_VALUE (tail) != 0) { tree tail1 = tail; next1 = digest_init (TREE_TYPE (type), TREE_VALUE (tail), &tail1); if (next1 == error_mark_node) return next1; my_friendly_assert (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)), TYPE_MAIN_VARIANT (TREE_TYPE (next1))), 981123); my_friendly_assert (tail1 == 0 || TREE_CODE (tail1) == TREE_LIST, 319); if (tail == tail1 && len < 0) { error ("non-empty initializer for array of empty elements"); /* Just ignore what we were supposed to use. */ tail1 = NULL_TREE; } tail = tail1; } else { next1 = error_mark_node; tail = TREE_CHAIN (tail); } } else if (len < 0) /* We're done. */ break; else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))) { /* If this type needs constructors run for default-initialization, we can't rely on the backend to do it for us, so build up TARGET_EXPRs. If the type in question is a class, just build one up; if it's an array, recurse. */ if (IS_AGGR_TYPE (TREE_TYPE (type))) next1 = build_functional_cast (TREE_TYPE (type), NULL_TREE); else next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE); next1 = digest_init (TREE_TYPE (type), next1, 0); } else /* The default zero-initialization is fine for us; don't add anything to the CONSTRUCTOR. */ break; if (next1 == error_mark_node) erroneous = 1; else if (!TREE_CONSTANT (next1)) allconstant = 0; else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1))) allsimple = 0; members = expr_tree_cons (NULL_TREE, next1, members); } } else if (TREE_CODE (type) == RECORD_TYPE) { register tree field; if (tail) { if (TYPE_USES_VIRTUAL_BASECLASSES (type)) { sorry ("initializer list for object of class with virtual baseclasses"); return error_mark_node; } if (TYPE_BINFO_BASETYPES (type)) { sorry ("initializer list for object of class with baseclasses"); return error_mark_node; } if (TYPE_VIRTUAL_P (type)) { sorry ("initializer list for object using virtual functions"); return error_mark_node; } } for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { if (! DECL_NAME (field) && DECL_C_BIT_FIELD (field)) { members = expr_tree_cons (field, integer_zero_node, members); continue; } if (TREE_CODE (field) != FIELD_DECL) continue; if (tail) { if (TREE_PURPOSE (tail) && TREE_PURPOSE (tail) != field && TREE_PURPOSE (tail) != DECL_NAME (field)) sorry ("non-trivial labeled initializers"); if (TREE_VALUE (tail) != 0) { tree tail1 = tail; next1 = digest_init (TREE_TYPE (field), TREE_VALUE (tail), &tail1); my_friendly_assert (tail1 == 0 || TREE_CODE (tail1) == TREE_LIST, 320); tail = tail1; } else { next1 = error_mark_node; tail = TREE_CHAIN (tail); } } else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field))) { /* If this type needs constructors run for default-initialization, we can't rely on the backend to do it for us, so build up TARGET_EXPRs. If the type in question is a class, just build one up; if it's an array, recurse. */ if (IS_AGGR_TYPE (TREE_TYPE (field))) next1 = build_functional_cast (TREE_TYPE (field), NULL_TREE); else next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE); next1 = digest_init (TREE_TYPE (field), next1, 0); /* Warn when some struct elements are implicitly initialized. */ if (extra_warnings) cp_warning ("missing initializer for member `%D'", field); } else { if (TREE_READONLY (field)) cp_error ("uninitialized const member `%D'", field); else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field)) && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field))) cp_error ("member `%D' with uninitialized const fields", field); else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) cp_error ("member `%D' is uninitialized reference", field); /* Warn when some struct elements are implicitly initialized to zero. */ if (extra_warnings) cp_warning ("missing initializer for member `%D'", field); /* The default zero-initialization is fine for us; don't add anything to the CONSTRUCTOR. */ continue; } if (next1 == error_mark_node) erroneous = 1; else if (!TREE_CONSTANT (next1)) allconstant = 0; else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1))) allsimple = 0; members = expr_tree_cons (field, next1, members); } } else if (TREE_CODE (type) == UNION_TYPE) { register tree field = TYPE_FIELDS (type); /* Find the first named field. ANSI decided in September 1990 that only named fields count here. */ while (field && (DECL_NAME (field) == 0 || TREE_CODE (field) != FIELD_DECL)) field = TREE_CHAIN (field); /* If this element specifies a field, initialize via that field. */ if (TREE_PURPOSE (tail) != NULL_TREE) { int win = 0; if (TREE_CODE (TREE_PURPOSE (tail)) == FIELD_DECL) /* Handle the case of a call by build_c_cast. */ field = TREE_PURPOSE (tail), win = 1; else if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE) error ("index value instead of field name in union initializer"); else { tree temp; for (temp = TYPE_FIELDS (type); temp; temp = TREE_CHAIN (temp)) if (DECL_NAME (temp) == TREE_PURPOSE (tail)) break; if (temp) field = temp, win = 1; else cp_error ("no field `%D' in union being initialized", TREE_PURPOSE (tail)); } if (!win) TREE_VALUE (tail) = error_mark_node; } else if (field == 0) { cp_error ("union `%T' with no named members cannot be initialized", type); TREE_VALUE (tail) = error_mark_node; } if (TREE_VALUE (tail) != 0) { tree tail1 = tail; next1 = digest_init (TREE_TYPE (field), TREE_VALUE (tail), &tail1); if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) my_friendly_abort (357); tail = tail1; } else { next1 = error_mark_node; tail = TREE_CHAIN (tail); } if (next1 == error_mark_node) erroneous = 1; else if (!TREE_CONSTANT (next1)) allconstant = 0; else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) allsimple = 0; members = expr_tree_cons (field, next1, members); } /* If arguments were specified as a list, just remove the ones we used. */ if (elts) *elts = tail; /* If arguments were specified as a constructor, complain unless we used all the elements of the constructor. */ else if (tail) pedwarn ("excess elements in aggregate initializer"); if (erroneous) return error_mark_node; result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members)); if (init) TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init); if (allconstant) TREE_CONSTANT (result) = 1; if (allconstant && allsimple) TREE_STATIC (result) = 1; return result;}/* Given a structure or union value DATUM, construct and return the structure or union component which results from narrowing that value by the type specified in BASETYPE. For example, given the hierarchy class L { int ii; }; class A : L { ... }; class B : L { ... }; class C : A, B { ... }; and the declaration C x; then the expression x.A::ii refers to the ii member of the L part of the A part of the C object named by X. In this case, DATUM would be x, and BASETYPE would be A. */treebuild_scoped_ref (datum, basetype) tree datum; tree basetype;{ tree ref; tree type = TREE_TYPE (datum); if (datum == error_mark_node) return error_mark_node; if (TREE_CODE (type) == REFERENCE_TYPE) type = TREE_TYPE (type); type = TYPE_MAIN_VARIANT (type); /* This is an easy conversion. */ if (is_aggr_type (basetype, 1)) { tree binfo = TYPE_BINFO (basetype); if (binfo != TYPE_BINFO (type)) { binfo = get_binfo (binfo, type, 1); if (binfo == error_mark_node) return error_mark_node; if (binfo == 0) return error_not_base_type (basetype, type); } switch (TREE_CODE (datum)) { case NOP_EXPR: case CONVERT_EXPR: case FLOAT_EXPR:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -