aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2002-10-23 17:13:18 +0000
committerZack Weinberg <zack@gcc.gnu.org>2002-10-23 17:13:18 +0000
commit8bcefb43ccfaf402c35312dd06c234e2ec975656 (patch)
tree8f64273fe292a54b0d5d5c23aa635d97a7aba7d7 /gcc/tree.c
parent09c68baa38cc66400b8bdb86137d8c6e1b0e663e (diff)
downloadgcc-8bcefb43ccfaf402c35312dd06c234e2ec975656.zip
gcc-8bcefb43ccfaf402c35312dd06c234e2ec975656.tar.gz
gcc-8bcefb43ccfaf402c35312dd06c234e2ec975656.tar.bz2
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
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c59
1 files changed, 59 insertions, 0 deletions
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. */