summaryrefslogtreecommitdiff
path: root/gcc/cp/tree.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-29 12:37:05 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-29 12:37:05 +0000
commit12cb78d1cca1387a092ec0bd49c250340bff4afc (patch)
tree1eab97da96906e0a2786d51d9f25f20de02befcf /gcc/cp/tree.c
parent31879e18aea3222fe3e56f2c0319c9f230645ff3 (diff)
downloadgcc-12cb78d1cca1387a092ec0bd49c250340bff4afc.tar.gz
2012-08-29 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 190745 using svnmerge, notably C++ conversion. [gcc/] 2012-08-29 Basile Starynkevitch <basile@starynkevitch.net> {{merging with trunk, converted to C++}} * melt-runtime.h (MELT_FLEXIBLE_DIM): Set when C++. * melt-runtime.c (melt_tempdir_path): Don't use choose_tmpdir from libiberty. (meltgc_start_module_by_index): Use address-of & on VEC_index. (melt_really_initialize): When printing builtin settings, handle GCC 4.8 as with implicit ENABLE_BUILD_WITH_CXX. (meltgc_out_edge): Provide additional flag TDF_DETAILS for dump_edge_info. (melt_val2passflag): Handle PROP_referenced_vars only when defined. * melt-module.mk: Use GCCMELT_COMPILER instead of GCCMELT_CC. * melt-build-script.tpl: Transmit GCCMELT_COMPILER on every make using melt-module.mk and improve the error message. * melt-build-script.sh: Regenerate. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@190778 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r--gcc/cp/tree.c222
1 files changed, 209 insertions, 13 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 2b541cd5bd5..7cc2457e3b2 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -795,7 +795,18 @@ build_cplus_array_type (tree elt_type, tree index_type)
}
}
else
- t = build_array_type (elt_type, index_type);
+ {
+ if (!TYPE_STRUCTURAL_EQUALITY_P (elt_type)
+ && !(index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))
+ && (TYPE_CANONICAL (elt_type) != elt_type
+ || (index_type && TYPE_CANONICAL (index_type) != index_type)))
+ /* Make sure that the canonical type is on the appropriate
+ variants list. */
+ build_cplus_array_type
+ (TYPE_CANONICAL (elt_type),
+ index_type ? TYPE_CANONICAL (index_type) : index_type);
+ t = build_array_type (elt_type, index_type);
+ }
/* We want TYPE_MAIN_VARIANT of an array to strip cv-quals from the
element type as well, so fix it up if needed. */
@@ -803,6 +814,7 @@ build_cplus_array_type (tree elt_type, tree index_type)
{
tree m = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
index_type);
+
if (TYPE_MAIN_VARIANT (t) != m)
{
TYPE_MAIN_VARIANT (t) = m;
@@ -1094,7 +1106,7 @@ cv_unqualified (tree type)
* If T is a type that needs structural equality
its TYPE_CANONICAL (T) will be NULL.
* TYPE_CANONICAL (T) desn't carry type attributes
- and looses template parameter names. */
+ and loses template parameter names. */
tree
strip_typedefs (tree t)
@@ -1184,6 +1196,16 @@ strip_typedefs (tree t)
TYPENAME_TYPE_FULLNAME (t),
typename_type, tf_none);
break;
+ case DECLTYPE_TYPE:
+ result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t));
+ if (result == DECLTYPE_TYPE_EXPR (t))
+ return t;
+ else
+ result = (finish_decltype_type
+ (result,
+ DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t),
+ tf_none));
+ break;
default:
break;
}
@@ -1205,6 +1227,186 @@ strip_typedefs (tree t)
return cp_build_qualified_type (result, cp_type_quals (t));
}
+/* Like strip_typedefs above, but works on expressions, so that in
+
+ template<class T> struct A
+ {
+ typedef T TT;
+ B<sizeof(TT)> b;
+ };
+
+ sizeof(TT) is replaced by sizeof(T). */
+
+tree
+strip_typedefs_expr (tree t)
+{
+ unsigned i,n;
+ tree r, type, *ops;
+ enum tree_code code;
+
+ if (t == NULL_TREE || t == error_mark_node)
+ return t;
+
+ if (DECL_P (t) || CONSTANT_CLASS_P (t))
+ return t;
+
+ /* Some expressions have type operands, so let's handle types here rather
+ than check TYPE_P in multiple places below. */
+ if (TYPE_P (t))
+ return strip_typedefs (t);
+
+ code = TREE_CODE (t);
+ switch (code)
+ {
+ case IDENTIFIER_NODE:
+ case TEMPLATE_PARM_INDEX:
+ case OVERLOAD:
+ case BASELINK:
+ case ARGUMENT_PACK_SELECT:
+ return t;
+
+ case TRAIT_EXPR:
+ {
+ tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t));
+ tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t));
+ if (type1 == TRAIT_EXPR_TYPE1 (t)
+ && type2 == TRAIT_EXPR_TYPE2 (t))
+ return t;
+ r = copy_node (t);
+ TRAIT_EXPR_TYPE1 (t) = type1;
+ TRAIT_EXPR_TYPE2 (t) = type2;
+ return r;
+ }
+
+ case TREE_LIST:
+ {
+ VEC(tree,gc) *vec = make_tree_vector ();
+ bool changed = false;
+ tree it;
+ for (it = t; it; it = TREE_CHAIN (it))
+ {
+ tree val = strip_typedefs_expr (TREE_VALUE (t));
+ VEC_safe_push (tree, gc, vec, val);
+ if (val != TREE_VALUE (t))
+ changed = true;
+ gcc_assert (TREE_PURPOSE (it) == NULL_TREE);
+ }
+ if (changed)
+ {
+ r = NULL_TREE;
+ FOR_EACH_VEC_ELT_REVERSE (tree, vec, i, it)
+ r = tree_cons (NULL_TREE, it, r);
+ }
+ else
+ r = t;
+ release_tree_vector (vec);
+ return r;
+ }
+
+ case TREE_VEC:
+ {
+ bool changed = false;
+ VEC(tree,gc)* vec = make_tree_vector ();
+ n = TREE_VEC_LENGTH (t);
+ VEC_reserve (tree, gc, vec, n);
+ for (i = 0; i < n; ++i)
+ {
+ tree op = strip_typedefs_expr (TREE_VEC_ELT (t, i));
+ VEC_quick_push (tree, vec, op);
+ if (op != TREE_VEC_ELT (t, i))
+ changed = true;
+ }
+ if (changed)
+ {
+ r = copy_node (t);
+ for (i = 0; i < n; ++i)
+ TREE_VEC_ELT (r, i) = VEC_index (tree, vec, i);
+ }
+ else
+ r = t;
+ release_tree_vector (vec);
+ return r;
+ }
+
+ case CONSTRUCTOR:
+ {
+ bool changed = false;
+ VEC(constructor_elt,gc) *vec
+ = VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (t));
+ n = CONSTRUCTOR_NELTS (t);
+ type = strip_typedefs (TREE_TYPE (t));
+ for (i = 0; i < n; ++i)
+ {
+ constructor_elt *e = &VEC_index (constructor_elt, vec, i);
+ tree op = strip_typedefs_expr (e->value);
+ if (op != e->value)
+ {
+ changed = true;
+ e->value = op;
+ }
+ gcc_checking_assert (e->index == strip_typedefs_expr (e->index));
+ }
+
+ if (!changed && type == TREE_TYPE (t))
+ {
+ VEC_free (constructor_elt, gc, vec);
+ return t;
+ }
+ else
+ {
+ r = copy_node (t);
+ TREE_TYPE (r) = type;
+ CONSTRUCTOR_ELTS (r) = vec;
+ return r;
+ }
+ }
+
+ case LAMBDA_EXPR:
+ gcc_unreachable ();
+
+ default:
+ break;
+ }
+
+ gcc_assert (EXPR_P (t));
+
+ n = TREE_OPERAND_LENGTH (t);
+ ops = XALLOCAVEC (tree, n);
+ type = TREE_TYPE (t);
+
+ switch (code)
+ {
+ CASE_CONVERT:
+ case IMPLICIT_CONV_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CAST_EXPR:
+ case NEW_EXPR:
+ type = strip_typedefs (type);
+ /* fallthrough */
+
+ default:
+ for (i = 0; i < n; ++i)
+ ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i));
+ break;
+ }
+
+ /* If nothing changed, return t. */
+ for (i = 0; i < n; ++i)
+ if (ops[i] != TREE_OPERAND (t, i))
+ break;
+ if (i == n && type == TREE_TYPE (t))
+ return t;
+
+ r = copy_node (t);
+ TREE_TYPE (r) = type;
+ for (i = 0; i < n; ++i)
+ TREE_OPERAND (r, i) = ops[i];
+ return r;
+}
+
/* Makes a copy of BINFO and TYPE, which is to be inherited into a
graph dominated by T. If BINFO is NULL, TYPE is a dependent base,
and we do a shallow copy. If BINFO is non-NULL, we do a deep copy.
@@ -1842,9 +2044,7 @@ no_linkage_check (tree t, bool relaxed_p)
}
}
-#ifdef GATHER_STATISTICS
extern int depth_reached;
-#endif
void
cxx_print_statistics (void)
@@ -1852,10 +2052,9 @@ cxx_print_statistics (void)
print_search_statistics ();
print_class_statistics ();
print_template_statistics ();
-#ifdef GATHER_STATISTICS
- fprintf (stderr, "maximum template instantiation depth reached: %d\n",
- depth_reached);
-#endif
+ if (GATHER_STATISTICS)
+ fprintf (stderr, "maximum template instantiation depth reached: %d\n",
+ depth_reached);
}
/* Return, as an INTEGER_CST node, the number of elements for TYPE
@@ -2378,9 +2577,6 @@ cp_tree_equal (tree t1, tree t2)
BASELINK_FUNCTIONS (t2)));
case TEMPLATE_PARM_INDEX:
- if (TEMPLATE_PARM_NUM_SIBLINGS (t1)
- != TEMPLATE_PARM_NUM_SIBLINGS (t2))
- return false;
return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
&& TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
&& (TEMPLATE_PARM_PARAMETER_PACK (t1)
@@ -2622,7 +2818,7 @@ is_dummy_object (const_tree ob)
/* Returns 1 iff type T is something we want to treat as a scalar type for
the purpose of deciding whether it is trivial/POD/standard-layout. */
-static bool
+bool
scalarish_type_p (const_tree t)
{
if (t == error_mark_node)
@@ -3212,7 +3408,7 @@ decl_linkage (tree decl)
/* Linkage of a CONST_DECL depends on the linkage of the enumeration
type. */
if (TREE_CODE (decl) == CONST_DECL)
- return decl_linkage (TYPE_NAME (TREE_TYPE (decl)));
+ return decl_linkage (TYPE_NAME (DECL_CONTEXT (decl)));
/* Some things that are not TREE_PUBLIC have external linkage, too.
For example, on targets that don't have weak symbols, we make all