diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-29 12:37:05 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-29 12:37:05 +0000 |
commit | 12cb78d1cca1387a092ec0bd49c250340bff4afc (patch) | |
tree | 1eab97da96906e0a2786d51d9f25f20de02befcf /gcc/cp/tree.c | |
parent | 31879e18aea3222fe3e56f2c0319c9f230645ff3 (diff) | |
download | gcc-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.c | 222 |
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 |