summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cc/cc1plus/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/cc/cc1plus/tree.c')
-rw-r--r--gnu/usr.bin/cc/cc1plus/tree.c223
1 files changed, 125 insertions, 98 deletions
diff --git a/gnu/usr.bin/cc/cc1plus/tree.c b/gnu/usr.bin/cc/cc1plus/tree.c
index 88466b8..5db4a66 100644
--- a/gnu/usr.bin/cc/cc1plus/tree.c
+++ b/gnu/usr.bin/cc/cc1plus/tree.c
@@ -35,66 +35,75 @@ int
lvalue_p (ref)
tree ref;
{
- register enum tree_code code = TREE_CODE (ref);
+ if (! language_lvalue_valid (ref))
+ return 0;
+
+ if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
+ return 1;
+
+ if (ref == current_class_decl && flag_this_is_variable <= 0)
+ return 0;
- if (language_lvalue_valid (ref))
+ switch (TREE_CODE (ref))
{
- if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
+ /* preincrements and predecrements are valid lvals, provided
+ what they refer to are valid lvals. */
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case COMPONENT_REF:
+ case SAVE_EXPR:
+ return lvalue_p (TREE_OPERAND (ref, 0));
+
+ case STRING_CST:
+ return 1;
+
+ case VAR_DECL:
+ if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
+ && DECL_LANG_SPECIFIC (ref)
+ && DECL_IN_AGGR_P (ref))
+ return 0;
+ case INDIRECT_REF:
+ case ARRAY_REF:
+ case PARM_DECL:
+ case RESULT_DECL:
+ case ERROR_MARK:
+ if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
+ && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
return 1;
-
- switch (code)
- {
- /* preincrements and predecrements are valid lvals, provided
- what they refer to are valid lvals. */
- case PREINCREMENT_EXPR:
- case PREDECREMENT_EXPR:
- case COMPONENT_REF:
- case SAVE_EXPR:
- return lvalue_p (TREE_OPERAND (ref, 0));
-
- case STRING_CST:
- return 1;
-
- case VAR_DECL:
- if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
- && DECL_LANG_SPECIFIC (ref)
- && DECL_IN_AGGR_P (ref))
- return 0;
- case INDIRECT_REF:
- case ARRAY_REF:
- case PARM_DECL:
- case RESULT_DECL:
- case ERROR_MARK:
- if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
- && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
- return 1;
- break;
+ break;
- case TARGET_EXPR:
- case WITH_CLEANUP_EXPR:
- return 1;
-
- /* A currently unresolved scope ref. */
- case SCOPE_REF:
- my_friendly_abort (103);
- case OFFSET_REF:
- if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
- return 1;
- return lvalue_p (TREE_OPERAND (ref, 0))
- && lvalue_p (TREE_OPERAND (ref, 1));
- break;
+ case WITH_CLEANUP_EXPR:
+ return lvalue_p (TREE_OPERAND (ref, 0));
- case COND_EXPR:
- return (lvalue_p (TREE_OPERAND (ref, 1))
- && lvalue_p (TREE_OPERAND (ref, 2)));
+ case TARGET_EXPR:
+ return 1;
- case MODIFY_EXPR:
- return 1;
+ case CALL_EXPR:
+ if (TREE_ADDRESSABLE (TREE_TYPE (ref)))
+ return 1;
+ break;
- case COMPOUND_EXPR:
- return lvalue_p (TREE_OPERAND (ref, 1));
- }
+ /* A currently unresolved scope ref. */
+ case SCOPE_REF:
+ my_friendly_abort (103);
+ case OFFSET_REF:
+ if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
+ return 1;
+ return lvalue_p (TREE_OPERAND (ref, 0))
+ && lvalue_p (TREE_OPERAND (ref, 1));
+ break;
+
+ case COND_EXPR:
+ return (lvalue_p (TREE_OPERAND (ref, 1))
+ && lvalue_p (TREE_OPERAND (ref, 2)));
+
+ case MODIFY_EXPR:
+ return 1;
+
+ case COMPOUND_EXPR:
+ return lvalue_p (TREE_OPERAND (ref, 1));
}
+
return 0;
}
@@ -221,12 +230,15 @@ break_out_calls (exp)
return exp;
case 'd': /* A decl node */
+#if 0 /* This is bogus. jason 9/21/94 */
+
t1 = break_out_calls (DECL_INITIAL (exp));
if (t1 != DECL_INITIAL (exp))
{
exp = copy_node (exp);
DECL_INITIAL (exp) = t1;
}
+#endif
return exp;
case 'b': /* A block node */
@@ -379,6 +391,40 @@ build_cplus_array_type (elt_type, index_type)
return t;
}
+/* Make a variant type in the proper way for C/C++, propagating qualifiers
+ down to the element type of an array. */
+
+tree
+cp_build_type_variant (type, constp, volatilep)
+ tree type;
+ int constp, volatilep;
+{
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree real_main_variant = TYPE_MAIN_VARIANT (type);
+
+ push_obstacks (TYPE_OBSTACK (real_main_variant),
+ TYPE_OBSTACK (real_main_variant));
+ type = build_cplus_array_type (cp_build_type_variant (TREE_TYPE (type),
+ constp, volatilep),
+ TYPE_DOMAIN (type));
+
+ /* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not,
+ make a copy. (TYPE might have come from the hash table and
+ REAL_MAIN_VARIANT might be in some function's obstack.) */
+
+ if (TYPE_OBSTACK (type) != TYPE_OBSTACK (real_main_variant))
+ {
+ type = copy_node (type);
+ TYPE_POINTER_TO (type) = TYPE_REFERENCE_TO (type) = 0;
+ }
+
+ TYPE_MAIN_VARIANT (type) = real_main_variant;
+ pop_obstacks ();
+ }
+ return build_type_variant (type, constp, volatilep);
+}
+
/* Add OFFSET to all base types of T.
OFFSET, which is a type offset, is number of bytes.
@@ -1184,50 +1230,6 @@ virtual_member (elem, list)
return rval;
}
-/* Return the offset (as an INTEGER_CST) for ELEM in LIST.
- INITIAL_OFFSET is the value to add to the offset that ELEM's
- binfo entry in LIST provides.
-
- Returns NULL if ELEM does not have an binfo value in LIST. */
-
-tree
-virtual_offset (elem, list, initial_offset)
- tree elem;
- tree list;
- tree initial_offset;
-{
- tree vb, offset;
- tree rval, nval;
-
- for (vb = list; vb; vb = TREE_CHAIN (vb))
- if (elem == BINFO_TYPE (vb))
- return size_binop (PLUS_EXPR, initial_offset, BINFO_OFFSET (vb));
- rval = 0;
- for (vb = list; vb; vb = TREE_CHAIN (vb))
- {
- tree binfos = BINFO_BASETYPES (vb);
- int i;
-
- if (binfos == NULL_TREE)
- continue;
-
- for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--)
- {
- nval = binfo_value (elem, BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
- if (nval)
- {
- if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval))
- my_friendly_abort (105);
- offset = BINFO_OFFSET (vb);
- rval = nval;
- }
- }
- }
- if (rval == NULL_TREE)
- return rval;
- return size_binop (PLUS_EXPR, offset, BINFO_OFFSET (rval));
-}
-
void
debug_binfo (elem)
tree elem;
@@ -1661,6 +1663,31 @@ make_deep_copy (t)
TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0));
return t;
+ case POINTER_TYPE:
+ return build_pointer_type (make_deep_copy (TREE_TYPE (t)));
+ case REFERENCE_TYPE:
+ return build_reference_type (make_deep_copy (TREE_TYPE (t)));
+ case FUNCTION_TYPE:
+ return build_function_type (make_deep_copy (TREE_TYPE (t)),
+ make_deep_copy (TYPE_ARG_TYPES (t)));
+ case ARRAY_TYPE:
+ return build_array_type (make_deep_copy (TREE_TYPE (t)),
+ make_deep_copy (TYPE_DOMAIN (t)));
+ case OFFSET_TYPE:
+ return build_offset_type (make_deep_copy (TYPE_OFFSET_BASETYPE (t)),
+ make_deep_copy (TREE_TYPE (t)));
+ case METHOD_TYPE:
+ return build_method_type
+ (make_deep_copy (TYPE_METHOD_BASETYPE (t)),
+ build_function_type
+ (make_deep_copy (TREE_TYPE (t)),
+ make_deep_copy (TREE_CHAIN (TYPE_ARG_TYPES (t)))));
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ return build_ptrmemfunc_type
+ (make_deep_copy (TYPE_PTRMEMFUNC_FN_TYPE (t)));
+ /* else fall through */
+
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call
`report_error_function'. That could cause an infinite loop. */
@@ -1738,7 +1765,7 @@ tree
array_type_nelts_top (type)
tree type;
{
- return fold (build (PLUS_EXPR, integer_type_node,
+ return fold (build (PLUS_EXPR, sizetype,
array_type_nelts (type),
integer_one_node));
}
@@ -1756,7 +1783,7 @@ array_type_nelts_total (type)
while (TREE_CODE (type) == ARRAY_TYPE)
{
tree n = array_type_nelts_top (type);
- sz = fold (build (MULT_EXPR, integer_type_node, sz, n));
+ sz = fold (build (MULT_EXPR, sizetype, sz, n));
type = TREE_TYPE (type);
}
return sz;
OpenPOWER on IntegriCloud