diff options
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index ec7b04d..5705f4d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -5756,5 +5756,94 @@ lvalue_error (enum lvalue_use use) gcc_unreachable (); } } + +/* *PTYPE is an incomplete array. Complete it with a domain based on + INITIAL_VALUE. If INITIAL_VALUE is not present, use 1 if DO_DEFAULT + is true. Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, + 2 if INITIAL_VALUE was NULL, and 3 if INITIAL_VALUE was empty. */ + +int +complete_array_type (tree *ptype, tree initial_value, bool do_default) +{ + tree maxindex, type, main_type, elt, unqual_elt; + int failure = 0, quals; + + maxindex = size_zero_node; + if (initial_value) + { + if (TREE_CODE (initial_value) == STRING_CST) + { + int eltsize + = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); + maxindex = size_int (TREE_STRING_LENGTH (initial_value)/eltsize - 1); + } + else if (TREE_CODE (initial_value) == CONSTRUCTOR) + { + tree elts = CONSTRUCTOR_ELTS (initial_value); + + if (elts == NULL) + { + if (pedantic) + failure = 3; + maxindex = integer_minus_one_node; + } + else + { + tree curindex; + + if (TREE_PURPOSE (elts)) + maxindex = fold_convert (sizetype, TREE_PURPOSE (elts)); + curindex = maxindex; + + for (elts = TREE_CHAIN (elts); elts; elts = TREE_CHAIN (elts)) + { + if (TREE_PURPOSE (elts)) + curindex = fold_convert (sizetype, TREE_PURPOSE (elts)); + else + curindex = size_binop (PLUS_EXPR, curindex, size_one_node); + + if (tree_int_cst_lt (maxindex, curindex)) + maxindex = curindex; + } + } + } + else + { + /* Make an error message unless that happened already. */ + if (initial_value != error_mark_node) + failure = 1; + } + } + else + { + failure = 2; + if (!do_default) + return failure; + } + + type = *ptype; + elt = TREE_TYPE (type); + quals = TYPE_QUALS (strip_array_types (elt)); + if (quals == 0) + unqual_elt = elt; + else + unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED); + + /* Using build_distinct_type_copy and modifying things afterward instead + of using build_array_type to create a new type preserves all of the + TYPE_LANG_FLAG_? bits that the front end may have set. */ + main_type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); + TREE_TYPE (main_type) = unqual_elt; + TYPE_DOMAIN (main_type) = build_index_type (maxindex); + layout_type (main_type); + + if (quals == 0) + type = main_type; + else + type = c_build_qualified_type (main_type, quals); + + *ptype = type; + return failure; +} #include "gt-c-common.h" |