cp-tree.h (make_ptrmem_cst): New function.

* cp-tree.h (make_ptrmem_cst): New function.
	* expr.c (cplus_expand_constant): Split out from ...
	(cplus_expand_expr): Here.  Use cplus_expand_constant.
	(init_cplus_expand): Set lang_expand_constant.
	* pt.c (convert_nontype_argument): Use make_ptrmem_cst.
	* tree.c (make_ptrmem_cst): Define.
	* typeck.c (unary_complex_lvalue): Use make_ptrmem_cst.
	* typeck2.c (initializer_constant_valid_p): Use make_ptrmem_cst.

From-SVN: r27060
This commit is contained in:
Mark Mitchell 1999-05-20 10:44:47 +00:00 committed by Mark Mitchell
parent e697e20a89
commit 87533b37c7
7 changed files with 100 additions and 56 deletions

View File

@ -1,3 +1,14 @@
1999-05-20 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (make_ptrmem_cst): New function.
* expr.c (cplus_expand_constant): Split out from ...
(cplus_expand_expr): Here. Use cplus_expand_constant.
(init_cplus_expand): Set lang_expand_constant.
* pt.c (convert_nontype_argument): Use make_ptrmem_cst.
* tree.c (make_ptrmem_cst): Define.
* typeck.c (unary_complex_lvalue): Use make_ptrmem_cst.
* typeck2.c (initializer_constant_valid_p): Use make_ptrmem_cst.
1999-05-19 Mark Mitchell <mark@codesourcery.com>
* pt.c (build_template_decl): Copy DECL_NONCONVERTING_P.

View File

@ -3386,6 +3386,7 @@ extern tree maybe_dummy_object PROTO((tree, tree *));
extern int is_dummy_object PROTO((tree));
extern tree search_tree PROTO((tree, tree (*)(tree)));
extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree));
extern tree make_ptrmem_cst PROTO((tree, tree));
#define scratchalloc expralloc
#define scratch_tree_cons expr_tree_cons

View File

@ -36,6 +36,62 @@ static tree extract_scalar_init PROTO((tree, tree));
static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode,
enum expand_modifier));
/* Hook used by output_constant to expand language-specific
constants. */
static tree
cplus_expand_constant (cst)
tree cst;
{
switch (TREE_CODE (cst))
{
case PTRMEM_CST:
{
tree type = TREE_TYPE (cst);
tree member;
tree offset;
/* Find the member. */
member = PTRMEM_CST_MEMBER (cst);
if (TREE_CODE (member) == FIELD_DECL)
{
/* Find the offset for the field. */
offset = convert (sizetype,
size_binop (EASY_DIV_EXPR,
DECL_FIELD_BITPOS (member),
size_int (BITS_PER_UNIT)));
/* We offset all pointer to data members by 1 so that we
can distinguish between a null pointer to data member
and the first data member of a structure. */
offset = size_binop (PLUS_EXPR, offset, size_int (1));
cst = cp_convert (type, offset);
}
else
{
tree delta;
tree idx;
tree pfn;
tree delta2;
expand_ptrmemfunc_cst (cst, &delta, &idx, &pfn, &delta2);
cst = build_ptrmemfunc1 (type, delta, idx,
pfn, delta2);
}
}
break;
default:
/* There's nothing to do. */
break;
}
return cst;
}
/* Hook used by expand_expr to expand language-specific tree codes. */
static rtx
@ -163,43 +219,8 @@ cplus_expand_expr (exp, target, tmode, modifier)
}
case PTRMEM_CST:
{
tree member;
tree offset;
/* Find the member. */
member = PTRMEM_CST_MEMBER (exp);
if (TREE_CODE (member) == FIELD_DECL)
{
/* Find the offset for the field. */
offset = convert (sizetype,
size_binop (EASY_DIV_EXPR,
DECL_FIELD_BITPOS (member),
size_int (BITS_PER_UNIT)));
/* We offset all pointer to data members by 1 so that we
can distinguish between a null pointer to data member
and the first data member of a structure. */
offset = size_binop (PLUS_EXPR, offset, size_int (1));
return expand_expr (cp_convert (type, offset), target, tmode,
modifier);
}
else
{
tree delta;
tree idx;
tree pfn;
tree delta2;
expand_ptrmemfunc_cst (exp, &delta, &idx, &pfn, &delta2);
return expand_expr (build_ptrmemfunc1 (type, delta, idx,
pfn, delta2),
target, tmode, modifier);
}
}
return expand_expr (cplus_expand_constant (exp),
target, tmode, modifier);
case OFFSET_REF:
{
@ -237,6 +258,7 @@ void
init_cplus_expand ()
{
lang_expand_expr = cplus_expand_expr;
lang_expand_constant = cplus_expand_constant;
}
/* If DECL had its rtl moved from where callers expect it

View File

@ -2782,18 +2782,14 @@ convert_nontype_argument (type, expr)
applied. */
e = perform_qualification_conversions (type, expr);
if (TREE_CODE (e) == NOP_EXPR)
{
/* The call to perform_qualification_conversions will
insert a NOP_EXPR over EXPR to do express
conversion, if necessary. But, that will confuse
us if we use this (converted) template parameter to
instantiate another template; then the thing will
not look like a valid template argument. So, just
make a new constant, of the appropriate type. */
e = make_node (PTRMEM_CST);
TREE_TYPE (e) = type;
PTRMEM_CST_MEMBER (e) = PTRMEM_CST_MEMBER (expr);
}
/* The call to perform_qualification_conversions will
insert a NOP_EXPR over EXPR to do express conversion,
if necessary. But, that will confuse us if we use
this (converted) template parameter to instantiate
another template; then the thing will not look like a
valid template argument. So, just make a new
constant, of the appropriate type. */
e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr));
return e;
}
else if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE)

View File

@ -2795,3 +2795,21 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
return 0;
}
/* Return a new PTRMEM_CST of the indicated TYPE. The MEMBER is the
thing pointed to by the constant. */
tree
make_ptrmem_cst (type, member)
tree type;
tree member;
{
tree ptrmem_cst = make_node (PTRMEM_CST);
/* If would seem a great convenience if make_node would set
TREE_CONSTANT for things of class `c', but it does not. */
TREE_CONSTANT (ptrmem_cst) = 1;
TREE_TYPE (ptrmem_cst) = type;
PTRMEM_CST_MEMBER (ptrmem_cst) = member;
return ptrmem_cst;
}

View File

@ -4912,9 +4912,7 @@ unary_complex_lvalue (code, arg)
type = build_offset_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t));
type = build_pointer_type (type);
t = make_node (PTRMEM_CST);
TREE_TYPE (t) = type;
PTRMEM_CST_MEMBER (t) = TREE_OPERAND (arg, 1);
t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
return t;
}
}
@ -6574,10 +6572,7 @@ build_ptrmemfunc (type, pfn, force)
fn = TREE_OPERAND (pfn, 0);
my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
npfn = make_node (PTRMEM_CST);
TREE_TYPE (npfn) = build_ptrmemfunc_type (type);
PTRMEM_CST_MEMBER (npfn) = fn;
return npfn;
return make_ptrmem_cst (build_ptrmemfunc_type (type), fn);
}
/* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST

View File

@ -400,6 +400,7 @@ initializer_constant_valid_p (value, endtype)
case REAL_CST:
case STRING_CST:
case COMPLEX_CST:
case PTRMEM_CST:
return null_pointer_node;
case ADDR_EXPR: