diff options
Diffstat (limited to 'contrib/gcc/cp/tree.c')
-rw-r--r-- | contrib/gcc/cp/tree.c | 341 |
1 files changed, 240 insertions, 101 deletions
diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c index cdfa49c..ce6137e 100644 --- a/contrib/gcc/cp/tree.c +++ b/contrib/gcc/cp/tree.c @@ -22,16 +22,17 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" -#include "obstack.h" #include "tree.h" #include "cp-tree.h" #include "flags.h" +#include "real.h" #include "rtl.h" #include "toplev.h" #include "ggc.h" #include "insn-config.h" #include "integrate.h" #include "tree-inline.h" +#include "target.h" static tree bot_manip PARAMS ((tree *, int *, void *)); static tree bot_replace PARAMS ((tree *, int *, void *)); @@ -39,12 +40,11 @@ static tree build_cplus_array_type_1 PARAMS ((tree, tree)); static int list_hash_eq PARAMS ((const void *, const void *)); static hashval_t list_hash_pieces PARAMS ((tree, tree, tree)); static hashval_t list_hash PARAMS ((const void *)); -static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int)); +static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int, int)); static tree no_linkage_helper PARAMS ((tree *, int *, void *)); static tree build_srcloc PARAMS ((const char *, int)); static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *)); static tree cp_unsave_r PARAMS ((tree *, int *, void *)); -static void cp_unsave PARAMS ((tree *)); static tree build_target_expr PARAMS ((tree, tree)); static tree count_trees_r PARAMS ((tree *, int *, void *)); static tree verify_stmt_tree_r PARAMS ((tree *, int *, void *)); @@ -57,12 +57,13 @@ static tree handle_init_priority_attribute PARAMS ((tree *, tree, tree, int, boo /* If REF is an lvalue, returns the kind of lvalue that REF is. Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is - non-zero, rvalues of class type are considered lvalues. */ + nonzero, rvalues of class type are considered lvalues. */ static cp_lvalue_kind -lvalue_p_1 (ref, treat_class_rvalues_as_lvalues) +lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue) tree ref; int treat_class_rvalues_as_lvalues; + int allow_cast_as_lvalue; { cp_lvalue_kind op1_lvalue_kind = clk_none; cp_lvalue_kind op2_lvalue_kind = clk_none; @@ -85,16 +86,28 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues) case WITH_CLEANUP_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: - /* This shouldn't be here, but there are lots of places in the compiler - that are sloppy about tacking on NOP_EXPRs to the same type when - no actual conversion is happening. */ - case NOP_EXPR: return lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); + treat_class_rvalues_as_lvalues, + allow_cast_as_lvalue); + + case NOP_EXPR: + /* If expression doesn't change the type, we consider it as an + lvalue even when cast_as_lvalue extension isn't selected. + That's because parts of the compiler are alleged to be sloppy + about sticking in NOP_EXPR node for no good reason. */ + if (allow_cast_as_lvalue || + same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ref)), + TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (ref, 0))))) + return lvalue_p_1 (TREE_OPERAND (ref, 0), + treat_class_rvalues_as_lvalues, + allow_cast_as_lvalue); + else + return clk_none; case COMPONENT_REF: op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); + treat_class_rvalues_as_lvalues, + allow_cast_as_lvalue); if (op1_lvalue_kind /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some situations. */ @@ -135,16 +148,20 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues) case MAX_EXPR: case MIN_EXPR: op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); + treat_class_rvalues_as_lvalues, + allow_cast_as_lvalue); op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues); + treat_class_rvalues_as_lvalues, + allow_cast_as_lvalue); break; case COND_EXPR: op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues); + treat_class_rvalues_as_lvalues, + allow_cast_as_lvalue); op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2), - treat_class_rvalues_as_lvalues); + treat_class_rvalues_as_lvalues, + allow_cast_as_lvalue); break; case MODIFY_EXPR: @@ -152,7 +169,8 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues) case COMPOUND_EXPR: return lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues); + treat_class_rvalues_as_lvalues, + allow_cast_as_lvalue); case TARGET_EXPR: return treat_class_rvalues_as_lvalues ? clk_class : clk_none; @@ -197,7 +215,19 @@ cp_lvalue_kind real_lvalue_p (ref) tree ref; { - return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/0); + return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/ 0, /*cast*/ 1); +} + +/* Returns the kind of lvalue that REF is, in the sense of + [basic.lval]. This function should really be named lvalue_p; it + computes the C++ definition of lvalue. */ + +cp_lvalue_kind +real_non_cast_lvalue_p (tree ref) +{ + return lvalue_p_1 (ref, + /*treat_class_rvalues_as_lvalues=*/0, + /*allow_cast_as_lvalue=*/0); } /* This differs from real_lvalue_p in that class rvalues are @@ -208,7 +238,15 @@ lvalue_p (ref) tree ref; { return - (lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/1) != clk_none); + (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 1) != clk_none); +} + +int +non_cast_lvalue_p (ref) + tree ref; +{ + return + (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 0) != clk_none); } /* Return nonzero if REF is an lvalue valid for this language; @@ -219,7 +257,20 @@ lvalue_or_else (ref, string) tree ref; const char *string; { - int win = lvalue_p (ref); + int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 1); + int win = (ret != clk_none); + if (! win) + error ("non-lvalue in %s", string); + return win; +} + +int +non_cast_lvalue_or_else (ref, string) + tree ref; + const char *string; +{ + int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 0); + int win = (ret != clk_none); if (! win) error ("non-lvalue in %s", string); return win; @@ -235,7 +286,7 @@ build_target_expr (decl, value) tree t; t = build (TARGET_EXPR, TREE_TYPE (decl), decl, value, - maybe_build_cleanup (decl), NULL_TREE); + cxx_maybe_build_cleanup (decl), NULL_TREE); /* We always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the TARGET_EXPR. If there really turn out to be no side-effects, then the optimizer should be able to get rid of @@ -293,7 +344,7 @@ build_cplus_new (type, init) return rval; } -/* Buidl a TARGET_EXPR using INIT to initialize a new temporary of the +/* Build a TARGET_EXPR using INIT to initialize a new temporary of the indicated TYPE. */ tree @@ -471,7 +522,7 @@ build_cplus_array_type_1 (elt_type, index_type) && index_type && TYPE_MAX_VALUE (index_type) && TREE_CODE (TYPE_MAX_VALUE (index_type)) != INTEGER_CST) || uses_template_parms (elt_type) - || uses_template_parms (index_type)) + || (index_type && uses_template_parms (index_type))) { t = make_node (ARRAY_TYPE); TREE_TYPE (t) = elt_type; @@ -496,14 +547,16 @@ build_cplus_array_type (elt_type, index_type) { tree t; int type_quals = cp_type_quals (elt_type); + int cv_quals = type_quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE); + int other_quals = type_quals & ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE); - if (type_quals != TYPE_UNQUALIFIED) - elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED); + if (cv_quals) + elt_type = cp_build_qualified_type (elt_type, other_quals); t = build_cplus_array_type_1 (elt_type, index_type); - if (type_quals != TYPE_UNQUALIFIED) - t = cp_build_qualified_type (t, type_quals); + if (cv_quals) + t = cp_build_qualified_type (t, cv_quals); return t; } @@ -610,9 +663,12 @@ cp_build_qualified_type_real (type, type_quals, complain) return error_mark_node; /* See if we already have an identically qualified type. */ - t = get_qualified_type (type, type_quals); - - /* If we didn't already have it, create it now. */ + for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) + if (cp_type_quals (t) == type_quals + && TYPE_NAME (t) == TYPE_NAME (type) + && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)) + break; + if (!t) { /* Make a new array type, just like the old one, but with the @@ -651,13 +707,13 @@ cp_build_qualified_type_real (type, type_quals, complain) result = build_qualified_type (type, type_quals); /* If this was a pointer-to-method type, and we just made a copy, - then we need to clear the cached associated - pointer-to-member-function type; it is not valid for the new - type. */ + then we need to unshare the record that holds the cached + pointer-to-member-function type, because these will be distinct + between the unqualified and qualified types. */ if (result != type && TREE_CODE (type) == POINTER_TYPE && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE) - TYPE_SET_PTRMEMFUNC_TYPE (result, NULL_TREE); + TYPE_LANG_SPECIFIC (result) = NULL; return result; } @@ -717,7 +773,7 @@ unshare_base_binfos (binfo) While all these live in the same table, they are completely independent, and the hash code is computed differently for each of these. */ -static htab_t list_hash_table; +static GTY ((param_is (union tree_node))) htab_t list_hash_table; struct list_proxy { @@ -955,7 +1011,7 @@ is_overloaded_fn (x) if (TREE_CODE (x) == OFFSET_REF) x = TREE_OPERAND (x, 1); if (BASELINK_P (x)) - x = TREE_VALUE (x); + x = BASELINK_FUNCTIONS (x); return (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == TEMPLATE_ID_EXPR || DECL_FUNCTION_TEMPLATE_P (x) @@ -970,10 +1026,25 @@ really_overloaded_fn (x) if (TREE_CODE (x) == OFFSET_REF) x = TREE_OPERAND (x, 1); if (BASELINK_P (x)) - x = TREE_VALUE (x); - return (TREE_CODE (x) == OVERLOAD - && (TREE_CHAIN (x) != NULL_TREE - || DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (x)))); + x = BASELINK_FUNCTIONS (x); + + return ((TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x)) + || DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x)) + || TREE_CODE (x) == TEMPLATE_ID_EXPR); +} + +/* Return the OVERLOAD or FUNCTION_DECL inside FNS. FNS can be an + OVERLOAD, FUNCTION_DECL, TEMPLATE_ID_EXPR, or baselink. */ + +tree +get_overloaded_fn (fns) + tree fns; +{ + if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) + fns = TREE_OPERAND (fns, 0); + if (BASELINK_P (fns)) + fns = BASELINK_FUNCTIONS (fns); + return fns; } tree @@ -981,9 +1052,9 @@ get_first_fn (from) tree from; { my_friendly_assert (is_overloaded_fn (from), 9); - /* A baselink is also considered an overloaded function. */ + /* A baselink is also considered an overloaded function. */ if (BASELINK_P (from)) - from = TREE_VALUE (from); + from = BASELINK_FUNCTIONS (from); return OVL_CURRENT (from); } @@ -998,7 +1069,7 @@ bound_pmf_p (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (t, 1)))); } -/* Return a new OVL node, concatenating it with the old one. */ +/* Return a new OVL node, concatenating it with the old one. */ tree ovl_cons (decl, chain) @@ -1037,7 +1108,7 @@ is_aggr_type_2 (t1, t2) return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2); } -/* Returns non-zero if CODE is the code for a statement. */ +/* Returns nonzero if CODE is the code for a statement. */ int cp_statement_code_p (code) @@ -1045,8 +1116,6 @@ cp_statement_code_p (code) { switch (code) { - case SUBOBJECT: - case CTOR_STMT: case CTOR_INITIALIZER: case RETURN_INIT: case TRY_BLOCK: @@ -1064,7 +1133,7 @@ cp_statement_code_p (code) #define PRINT_RING_SIZE 4 const char * -lang_printable_name (decl, v) +cxx_printable_name (decl, v) tree decl; int v; { @@ -1500,19 +1569,19 @@ build_min VPARAMS ((enum tree_code code, tree tt, ...)) same node; therefore, callers should never modify the node returned. */ +static GTY(()) tree shared_int_cache[256]; + tree build_shared_int_cst (i) int i; { - static tree cache[256]; - if (i >= 256) return build_int_2 (i, 0); - if (!cache[i]) - cache[i] = build_int_2 (i, 0); + if (!shared_int_cache[i]) + shared_int_cache[i] = build_int_2 (i, 0); - return cache[i]; + return shared_int_cache[i]; } tree @@ -1680,8 +1749,10 @@ cp_tree_equal (t1, t2) return 0; case TEMPLATE_PARM_INDEX: - return TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2) - && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2); + return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2) + && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2) + && same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)), + TREE_TYPE (TEMPLATE_PARM_DECL (t2)))); case SIZEOF_EXPR: case ALIGNOF_EXPR: @@ -1729,25 +1800,15 @@ cp_tree_equal (t1, t2) return -1; } -/* Build a wrapper around some pointer PTR so we can use it as a tree. */ +/* Build a wrapper around a 'struct z_candidate' so we can use it as a + tree. */ tree -build_ptr_wrapper (ptr) - void *ptr; +build_zc_wrapper (ptr) + struct z_candidate *ptr; { tree t = make_node (WRAPPER); - WRAPPER_PTR (t) = ptr; - return t; -} - -/* Build a wrapper around some integer I so we can use it as a tree. */ - -tree -build_int_wrapper (i) - int i; -{ - tree t = make_node (WRAPPER); - WRAPPER_INT (t) = i; + WRAPPER_ZC (t) = ptr; return t; } @@ -1861,7 +1922,12 @@ maybe_dummy_object (type, binfop) if (binfop) *binfop = binfo; - if (current_class_ref && context == current_class_type) + if (current_class_ref && context == current_class_type + /* Kludge: Make sure that current_class_type is actually + correct. It might not be if we're in the middle of + tsubst_default_argument. */ + && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)), + current_class_type)) decl = current_class_ref; else decl = build_dummy_object (context); @@ -1889,6 +1955,8 @@ pod_type_p (t) { t = strip_array_types (t); + if (t == error_mark_node) + return 1; if (INTEGRAL_TYPE_P (t)) return 1; /* integral, character or enumeral type */ if (FLOAT_TYPE_P (t)) @@ -1912,24 +1980,27 @@ pod_type_p (t) int zero_init_p (t) - tree t ATTRIBUTE_UNUSED; + tree t; { - /* This is not a correct implementation of this function. As a - result, pointers-to-members will not be correctly - zero-initialized. + t = strip_array_types (t); + + if (t == error_mark_node) + return 1; - However, using a correct implementation of this function results - in many other failures. Correcting these other failures required - a major infrastructure improvement, which was undertaken in the - GCC 3.3 source base. + /* NULL pointers to data members are initialized with -1. */ + if (TYPE_PTRMEM_P (t)) + return 0; + + /* Classes that contain types that can't be zero-initialized, cannot + be zero-initialized themselves. */ + if (CLASS_TYPE_P (t) && CLASSTYPE_NON_ZERO_INIT_P (t)) + return 0; - In order to reduce risk, these changes were not ported to the GCC - 3.2 source base. */ return 1; } /* Table of valid C++ attributes. */ -const struct attribute_spec cp_attribute_table[] = +const struct attribute_spec cxx_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ { "java_interface", 0, 0, false, false, false, handle_java_interface_attribute }, @@ -2031,7 +2102,7 @@ handle_init_priority_attribute (node, name, args, flags, no_add_attrs) /* Static objects in functions are initialized the first time control passes through that function. This is not precise enough to pin down an - init_priority value, so don't allow it. */ + init_priority value, so don't allow it. */ || current_function_decl) { error ("can only use `%s' attribute on file-scope definitions of objects of class type", @@ -2181,6 +2252,14 @@ cp_cannot_inline_tree_fn (fnp) return 1; } + /* Don't auto-inline anything that might not be bound within + this unit of translation. */ + if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn)) + { + DECL_UNINLINABLE (fn) = 1; + return 1; + } + if (varargs_function_p (fn)) { DECL_UNINLINABLE (fn) = 1; @@ -2290,8 +2369,7 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_, position so we can get reasonable debugging information, and register the return variable as its equivalent. */ DECL_NAME (var) = DECL_NAME (nrv); - DECL_SOURCE_FILE (var) = DECL_SOURCE_FILE (nrv); - DECL_SOURCE_LINE (var) = DECL_SOURCE_LINE (nrv); + DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv); DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv); /* Don't lose initialization info. */ DECL_INITIAL (var) = DECL_INITIAL (nrv); @@ -2307,7 +2385,7 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_, return var; } -/* Record that we're about to start inlining FN, and return non-zero if +/* Record that we're about to start inlining FN, and return nonzero if that's OK. Used for lang_hooks.tree_inlining.start_inlining. */ int @@ -2336,14 +2414,8 @@ cp_end_inlining (fn) void init_tree () { - make_lang_type_fn = cp_make_lang_type; - lang_unsave = cp_unsave; lang_statement_code_p = cp_statement_code_p; - lang_set_decl_assembler_name = mangle_decl; - list_hash_table = htab_create (31, list_hash, list_hash_eq, NULL); - ggc_add_root (&list_hash_table, 1, - sizeof (list_hash_table), - mark_tree_hashtable); + list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL); } /* Called via walk_tree. If *TP points to a DECL_STMT for a local @@ -2429,12 +2501,11 @@ cp_unsave_r (tp, walk_subtrees, data) return NULL_TREE; } -/* Called by unsave_expr_now whenever an expression (*TP) needs to be - unsaved. */ +/* Called whenever an expression needs to be unsaved. */ -static void -cp_unsave (tp) - tree *tp; +tree +cxx_unsave_expr_now (tp) + tree tp; { splay_tree st; @@ -2443,18 +2514,20 @@ cp_unsave (tp) st = splay_tree_new (splay_tree_compare_pointers, NULL, NULL); /* Walk the tree once figuring out what needs to be remapped. */ - walk_tree (tp, mark_local_for_remap_r, st, NULL); + walk_tree (&tp, mark_local_for_remap_r, st, NULL); /* Walk the tree again, copying, remapping, and unsaving. */ - walk_tree (tp, cp_unsave_r, st, NULL); + walk_tree (&tp, cp_unsave_r, st, NULL); /* Clean up. */ splay_tree_delete (st); + + return tp; } /* Returns the kind of special function that DECL (a FUNCTION_DECL) - is. Note that this sfk_none is zero, so this function can be used - as a predicate to test whether or not DECL is a special function. */ + is. Note that sfk_none is zero, so this function can be used as a + predicate to test whether or not DECL is a special function. */ special_function_kind special_function_p (decl) @@ -2483,7 +2556,23 @@ special_function_p (decl) return sfk_none; } -/* Returns non-zero if TYPE is a character type, including wchar_t. */ +/* Returns true if and only if NODE is a name, i.e., a node created + by the parser when processing an id-expression. */ + +bool +name_p (tree node) +{ + if (TREE_CODE (node) == TEMPLATE_ID_EXPR) + node = TREE_OPERAND (node, 0); + return (/* An ordinary unqualified name. */ + TREE_CODE (node) == IDENTIFIER_NODE + /* A destructor name. */ + || TREE_CODE (node) == BIT_NOT_EXPR + /* A qualified name. */ + || TREE_CODE (node) == SCOPE_REF); +} + +/* Returns nonzero if TYPE is a character type, including wchar_t. */ int char_type_p (type) @@ -2537,3 +2626,53 @@ decl_linkage (decl) /* Everything else has internal linkage. */ return lk_internal; } + +/* EXP is an expression that we want to pre-evaluate. Returns via INITP an + expression to perform the pre-evaluation, and returns directly an + expression to use the precalculated result. */ + +tree +stabilize_expr (exp, initp) + tree exp; + tree *initp; +{ + tree init_expr; + + if (!TREE_SIDE_EFFECTS (exp)) + { + init_expr = void_zero_node; + } + else if (!real_lvalue_p (exp) + || !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp))) + { + init_expr = get_target_expr (exp); + exp = TARGET_EXPR_SLOT (init_expr); + } + else + { + exp = build_unary_op (ADDR_EXPR, exp, 1); + init_expr = get_target_expr (exp); + exp = TARGET_EXPR_SLOT (init_expr); + exp = build_indirect_ref (exp, 0); + } + + *initp = init_expr; + return exp; +} + +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) +/* Complain that some language-specific thing hanging off a tree + node has been accessed improperly. */ + +void +lang_check_failed (file, line, function) + const char *file; + int line; + const char *function; +{ + internal_error ("lang_* check: failed in %s, at %s:%d", + function, trim_filename (file), line); +} +#endif /* ENABLE_TREE_CHECKING */ + +#include "gt-cp-tree.h" |