diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -4151,6 +4151,65 @@ int_fits_type_p (c, type) } } +/* Returns true if T is, contains, or refers to a type with variable + size. This concept is more general than that of C99 'variably + modified types': in C99, a struct type is never variably modified + because a VLA may not appear as a structure member. However, in + GNU C code like: + + struct S { int i[f()]; }; + + is valid, and other languages may define similar constructs. */ + +bool +variably_modified_type_p (type) + tree type; +{ + /* If TYPE itself has variable size, it is variably modified. + + We do not yet have a representation of the C99 '[*]' syntax. + When a representation is chosen, this function should be modified + to test for that case as well. */ + if (TYPE_SIZE (type) + && TYPE_SIZE (type) != error_mark_node + && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + return true; + + /* If TYPE is a pointer or reference, it is variably modified if + the type pointed to is variably modified. */ + if ((TREE_CODE (type) == POINTER_TYPE + || TREE_CODE (type) == REFERENCE_TYPE) + && variably_modified_type_p (TREE_TYPE (type))) + return true; + + /* If TYPE is an array, it is variably modified if the array + elements are. (Note that the VLA case has already been checked + above.) */ + if (TREE_CODE (type) == ARRAY_TYPE + && variably_modified_type_p (TREE_TYPE (type))) + return true; + + /* If TYPE is a function type, it is variably modified if any of the + parameters or the return type are variably modified. */ + if (TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE) + { + tree parm; + + if (variably_modified_type_p (TREE_TYPE (type))) + return true; + for (parm = TYPE_ARG_TYPES (type); + parm && parm != void_list_node; + parm = TREE_CHAIN (parm)) + if (variably_modified_type_p (TREE_VALUE (parm))) + return true; + } + + /* The current language may have other cases to check, but in general, + all other types are not variably modified. */ + return (*lang_hooks.tree_inlining.var_mod_type_p) (type); +} + /* Given a DECL or TYPE, return the scope in which it was declared, or NULL_TREE if there is no containing scope. */ |