From 8bcefb43ccfaf402c35312dd06c234e2ec975656 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Wed, 23 Oct 2002 17:13:18 +0000 Subject: langhooks.h (struct lang_hooks_for_tree_inlining): Add var_mod_type_p. * langhooks.h (struct lang_hooks_for_tree_inlining): Add var_mod_type_p. * langhooks-def.h: Default for tree_inlining.var_mod_type_p is hook_tree_bool_false. * tree.c (variably_modified_type_p): Moved here from cp/tree.c. Use lang_hooks.tree_inlining.var_mod_type_p for language-specific cases. Due to this, must weaken some 'if and only if' checks to merely 'if'. * tree.h: Prototype variably_modified_type_p. * tree-inline.c (walk_tree): #undef WALK_SUBTREE_TAIL at end. cp: * cp-lang.c (cp_var_mod_type_p): New: C++ hook for variably_modified_type_p. * cp-tree.h: Remove prototype of variably_modified_type_p. * tree.c (variably_modified_type_p): Remove; now implemented in language-independent code. From-SVN: r58460 --- gcc/tree.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 53f46f3..a70b1b2 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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. */ -- cgit v1.1