summaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 5ed55c1d372..92f16e7a88f 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5696,6 +5696,57 @@ build_range_type (tree type, tree lowval, tree highval)
return itype;
}
+/* Return true if the debug information for TYPE, a subtype, should be emitted
+ as a subrange type. If so, set LOWVAL to the low bound and HIGHVAL to the
+ high bound, respectively. Sometimes doing so unnecessarily obfuscates the
+ debug info and doesn't reflect the source code. */
+
+bool
+subrange_type_for_debug_p (const_tree type, tree *lowval, tree *highval)
+{
+ tree base_type = TREE_TYPE (type), low, high;
+
+ /* Subrange types have a base type which is an integral type. */
+ if (!INTEGRAL_TYPE_P (base_type))
+ return false;
+
+ /* Get the real bounds of the subtype. */
+ if (lang_hooks.types.get_subrange_bounds)
+ lang_hooks.types.get_subrange_bounds (type, &low, &high);
+ else
+ {
+ low = TYPE_MIN_VALUE (type);
+ high = TYPE_MAX_VALUE (type);
+ }
+
+ /* If the type and its base type have the same representation and the same
+ name, then the type is not a subrange but a copy of the base type. */
+ if ((TREE_CODE (base_type) == INTEGER_TYPE
+ || TREE_CODE (base_type) == BOOLEAN_TYPE)
+ && int_size_in_bytes (type) == int_size_in_bytes (base_type)
+ && tree_int_cst_equal (low, TYPE_MIN_VALUE (base_type))
+ && tree_int_cst_equal (high, TYPE_MAX_VALUE (base_type)))
+ {
+ tree type_name = TYPE_NAME (type);
+ tree base_type_name = TYPE_NAME (base_type);
+
+ if (type_name && TREE_CODE (type_name) == TYPE_DECL)
+ type_name = DECL_NAME (type_name);
+
+ if (base_type_name && TREE_CODE (base_type_name) == TYPE_DECL)
+ base_type_name = DECL_NAME (base_type_name);
+
+ if (type_name == base_type_name)
+ return false;
+ }
+
+ if (lowval)
+ *lowval = low;
+ if (highval)
+ *highval = high;
+ return true;
+}
+
/* Just like build_index_type, but takes lowval and highval instead
of just highval (maxval). */