static tree count_trees_r (tree *, int *, void *);
static tree verify_stmt_tree_r (tree *, int *, void *);
static tree find_tree_r (tree *, int *, void *);
+static tree build_local_temp (tree);
static tree handle_java_interface_attribute (tree *, tree, tree, int, bool *);
static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *);
/* Clear the ordinary bit. If this object was a class
rvalue we want to preserve that information. */
op1_lvalue_kind &= ~clk_ordinary;
- /* The lvalue is for a btifield. */
+ /* The lvalue is for a bitfield. */
op1_lvalue_kind |= clk_bitfield;
}
else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
return t;
}
+/* Return an undeclared local temporary of type TYPE for use in building a
+ TARGET_EXPR. */
+
+static tree
+build_local_temp (tree type)
+{
+ tree slot = build_decl (VAR_DECL, NULL_TREE, type);
+ DECL_ARTIFICIAL (slot) = 1;
+ DECL_CONTEXT (slot) = current_function_decl;
+ layout_decl (slot, 0);
+ return slot;
+}
+
/* INIT is a CALL_EXPR which needs info about its target.
TYPE is the type that this initialization should appear to have.
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
- slot = build (VAR_DECL, type);
- DECL_ARTIFICIAL (slot) = 1;
- DECL_CONTEXT (slot) = current_function_decl;
- layout_decl (slot, 0);
+ slot = build_local_temp (type);
/* We split the CALL_EXPR into its function and its arguments here.
Then, in expand_expr, we put them back together. The reason for
build_target_expr_with_type (tree init, tree type)
{
tree slot;
- tree rval;
+
+ my_friendly_assert (!VOID_TYPE_P (type), 20040130);
if (TREE_CODE (init) == TARGET_EXPR)
return init;
+ else if (CLASS_TYPE_P (type) && !TYPE_HAS_TRIVIAL_INIT_REF (type)
+ && TREE_CODE (init) != COND_EXPR
+ && TREE_CODE (init) != CONSTRUCTOR
+ && TREE_CODE (init) != VA_ARG_EXPR)
+ /* We need to build up a copy constructor call. COND_EXPR is a special
+ case because we already have copies on the arms and we don't want
+ another one here. A CONSTRUCTOR is aggregate initialization, which
+ is handled separately. A VA_ARG_EXPR is magic creation of an
+ aggregate; there's no additional work to be done. */
+ return force_rvalue (init);
- slot = build (VAR_DECL, type);
- DECL_ARTIFICIAL (slot) = 1;
- DECL_CONTEXT (slot) = current_function_decl;
- layout_decl (slot, 0);
- rval = build_target_expr (slot, init);
+ slot = build_local_temp (type);
+ return build_target_expr (slot, init);
+}
- return rval;
+/* Like the above function, but without the checking. This function should
+ only be used by code which is deliberately trying to subvert the type
+ system, such as call_builtin_trap. */
+
+tree
+force_target_expr (tree type, tree init)
+{
+ tree slot;
+
+ my_friendly_assert (!VOID_TYPE_P (type), 20040130);
+
+ slot = build_local_temp (type);
+ return build_target_expr (slot, init);
}
/* Like build_target_expr_with_type, but use the type of INIT. */
if (elt_type == error_mark_node || index_type == error_mark_node)
return error_mark_node;
- /* Don't do the minimal thing just because processing_template_decl is
- set; we want to give string constants the right type immediately, so
- we don't have to fix them up at instantiation time. */
- if ((processing_template_decl
- && index_type && TYPE_MAX_VALUE (index_type)
- && TREE_CODE (TYPE_MAX_VALUE (index_type)) != INTEGER_CST)
- || uses_template_parms (elt_type)
- || (index_type && uses_template_parms (index_type)))
+ if (dependent_type_p (elt_type)
+ || (index_type
+ && value_dependent_expression_p (TYPE_MAX_VALUE (index_type))))
{
t = make_node (ARRAY_TYPE);
TREE_TYPE (t) = elt_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 (cv_quals)
- elt_type = cp_build_qualified_type (elt_type, other_quals);
+ if (type_quals != TYPE_UNQUALIFIED)
+ elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED);
t = build_cplus_array_type_1 (elt_type, index_type);
- if (cv_quals)
- t = cp_build_qualified_type (t, cv_quals);
+ if (type_quals != TYPE_UNQUALIFIED)
+ t = cp_build_qualified_type (t, type_quals);
return t;
}
if (type_quals == cp_type_quals (type))
return type;
- /* A reference, fucntion or method type shall not be cv qualified.
- [dcl.ref], [dct.fct] */
- if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
- && (TREE_CODE (type) == REFERENCE_TYPE
- || TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE))
- {
- bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- if (TREE_CODE (type) != REFERENCE_TYPE)
- bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- }
-
- /* A restrict-qualified type must be a pointer (or reference)
- to object or incomplete type. */
- if ((type_quals & TYPE_QUAL_RESTRICT)
- && TREE_CODE (type) != TEMPLATE_TYPE_PARM
- && TREE_CODE (type) != TYPENAME_TYPE
- && !POINTER_TYPE_P (type))
- {
- bad_quals |= TYPE_QUAL_RESTRICT;
- type_quals &= ~TYPE_QUAL_RESTRICT;
- }
-
- if (bad_quals == TYPE_UNQUALIFIED)
- /*OK*/;
- else if (!(complain & (tf_error | tf_ignore_bad_quals)))
- return error_mark_node;
- else if (bad_func_quals && !(complain & tf_error))
- return error_mark_node;
- else
- {
- if (complain & tf_ignore_bad_quals)
- /* We're not going to warn about constifying things that can't
- be constified. */
- bad_quals &= ~TYPE_QUAL_CONST;
- bad_quals |= bad_func_quals;
- if (bad_quals)
- {
- tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
-
- if (!(complain & tf_ignore_bad_quals)
- || bad_func_quals)
- error ("`%V' qualifiers cannot be applied to `%T'",
- bad_type, type);
- }
- }
-
if (TREE_CODE (type) == ARRAY_TYPE)
{
/* In C++, the qualification really applies to the array element
return build_ptrmemfunc_type (t);
}
+ /* A reference, function or method type shall not be cv qualified.
+ [dcl.ref], [dct.fct] */
+ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
+ && (TREE_CODE (type) == REFERENCE_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE))
+ {
+ bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ }
+
+ /* A restrict-qualified type must be a pointer (or reference)
+ to object or incomplete type. */
+ if ((type_quals & TYPE_QUAL_RESTRICT)
+ && TREE_CODE (type) != TEMPLATE_TYPE_PARM
+ && TREE_CODE (type) != TYPENAME_TYPE
+ && !POINTER_TYPE_P (type))
+ {
+ bad_quals |= TYPE_QUAL_RESTRICT;
+ type_quals &= ~TYPE_QUAL_RESTRICT;
+ }
+
+ if (bad_quals == TYPE_UNQUALIFIED)
+ /*OK*/;
+ else if (!(complain & (tf_error | tf_ignore_bad_quals)))
+ return error_mark_node;
+ else if (bad_func_quals && !(complain & tf_error))
+ return error_mark_node;
+ else
+ {
+ if (complain & tf_ignore_bad_quals)
+ /* We're not going to warn about constifying things that can't
+ be constified. */
+ bad_quals &= ~TYPE_QUAL_CONST;
+ bad_quals |= bad_func_quals;
+ if (bad_quals)
+ {
+ tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
+
+ if (!(complain & tf_ignore_bad_quals)
+ || bad_func_quals)
+ error ("`%V' qualifiers cannot be applied to `%T'",
+ bad_type, type);
+ }
+ }
+
/* Retrieve (or create) the appropriately qualified variant. */
result = build_qualified_type (type, type_quals);
tree
build_min_nt (enum tree_code code, ...)
{
- register tree t;
- register int length;
- register int i;
+ tree t;
+ int length;
+ int i;
va_list p;
va_start (p, code);
tree
build_min (enum tree_code code, tree tt, ...)
{
- register tree t;
- register int length;
- register int i;
+ tree t;
+ int length;
+ int i;
va_list p;
va_start (p, tt);
tree
build_min_non_dep (enum tree_code code, tree non_dep, ...)
{
- register tree t;
- register int length;
- register int i;
+ tree t;
+ int length;
+ int i;
va_list p;
va_start (p, non_dep);
if (code == COMPOUND_EXPR && TREE_CODE (non_dep) != COMPOUND_EXPR)
/* This should not be considered a COMPOUND_EXPR, because it
- resolves to an overload. */
+ resolves to an overload. */
COMPOUND_EXPR_OVERLOADED (t) = 1;
va_end (p);
bool
cp_tree_equal (tree t1, tree t2)
{
- register enum tree_code code1, code2;
+ enum tree_code code1, code2;
if (t1 == t2)
return true;
case TYPENAME_TYPE:
case TYPEOF_TYPE:
case BASELINK:
- /* None of thse have subtrees other than those already walked
+ /* None of these have subtrees other than those already walked
above. */
*walk_subtrees_p = 0;
break;
(template_for_substitution (fn))))
return 1;
- /* Our caller does not expect us to call ggc_collect, but
- instantiate_decl can call rest_of_compilation so we must
- protect our caller. */
- ggc_push_context();
-
fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0);
- ggc_pop_context();
-
if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
return 1;
}
return var;
}
-/* 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
-cp_start_inlining (tree fn)
-{
- if (DECL_TEMPLATE_INSTANTIATION (fn))
- return push_tinst_level (fn);
- else
- return 1;
-}
-
-/* Record that we're done inlining FN. Used for
- lang_hooks.tree_inlining.end_inlining. */
-
-void
-cp_end_inlining (tree fn ATTRIBUTE_UNUSED )
-{
- if (DECL_TEMPLATE_INSTANTIATION (fn))
- pop_tinst_level ();
-}
-
/* Initialize tree.c. */
void