Commit 2adeacc9 by Mark Mitchell Committed by Mark Mitchell

error.c (dump_expr): Handle EXACT_DIV_EXPR.

	* error.c (dump_expr): Handle EXACT_DIV_EXPR.
	(dump_binary_op): Bulletproof.
	* lex.c (init_parse): Set opname_tab[EXACT_DIV_EXPR].
	* tree.c (search_tree): Don't enumerate all the nodes of classes
	`1', `2', and `<'; handle them generically.  Don't be sorry about
	"unrecognized tree codes"; just abort.
	(no_linkage_check): Don't do linkage checks for templates.

	* tree.c (cp_build_qualified_type_real): Handle
	pointer-to-member-function types correctly.

From-SVN: r28550
parent e7eacc8e
1999-08-06 Mark Mitchell <mark@codesourcery.com>
* error.c (dump_expr): Handle EXACT_DIV_EXPR.
(dump_binary_op): Bulletproof.
* lex.c (init_parse): Set opname_tab[EXACT_DIV_EXPR].
* tree.c (search_tree): Don't enumerate all the nodes of classes
`1', `2', and `<'; handle them generically. Don't be sorry about
"unrecognized tree codes"; just abort.
(no_linkage_check): Don't do linkage checks for templates.
* tree.c (cp_build_qualified_type_real): Handle
pointer-to-member-function types correctly.
1999-08-05 Jason Merrill <jason@yorick.cygnus.com> 1999-08-05 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (pushdecl): Only give an error for shadowing a parm * decl.c (pushdecl): Only give an error for shadowing a parm
......
...@@ -1521,6 +1521,7 @@ dump_expr (t, nop) ...@@ -1521,6 +1521,7 @@ dump_expr (t, nop)
case GE_EXPR: case GE_EXPR:
case EQ_EXPR: case EQ_EXPR:
case NE_EXPR: case NE_EXPR:
case EXACT_DIV_EXPR:
dump_binary_op (opname_tab[(int) TREE_CODE (t)], t); dump_binary_op (opname_tab[(int) TREE_CODE (t)], t);
break; break;
...@@ -1847,7 +1848,10 @@ dump_binary_op (opstring, t) ...@@ -1847,7 +1848,10 @@ dump_binary_op (opstring, t)
OB_PUTC ('('); OB_PUTC ('(');
dump_expr (TREE_OPERAND (t, 0), 1); dump_expr (TREE_OPERAND (t, 0), 1);
OB_PUTC (' '); OB_PUTC (' ');
OB_PUTCP (opstring); if (opstring)
OB_PUTCP (opstring);
else
OB_PUTS ("<unknown operator>");
OB_PUTC (' '); OB_PUTC (' ');
dump_expr (TREE_OPERAND (t, 1), 1); dump_expr (TREE_OPERAND (t, 1), 1);
OB_PUTC (')'); OB_PUTC (')');
......
...@@ -761,6 +761,7 @@ init_parse (filename) ...@@ -761,6 +761,7 @@ init_parse (filename)
opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)"; opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)"; opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
opname_tab[(int) ROUND_MOD_EXPR] = "(round %)"; opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
opname_tab[(int) EXACT_DIV_EXPR] = "/";
opname_tab[(int) NEGATE_EXPR] = "-"; opname_tab[(int) NEGATE_EXPR] = "-";
opname_tab[(int) MIN_EXPR] = "<?"; opname_tab[(int) MIN_EXPR] = "<?";
opname_tab[(int) MAX_EXPR] = ">?"; opname_tab[(int) MAX_EXPR] = ">?";
......
...@@ -503,6 +503,8 @@ cp_build_qualified_type_real (type, type_quals, complain) ...@@ -503,6 +503,8 @@ cp_build_qualified_type_real (type, type_quals, complain)
int type_quals; int type_quals;
int complain; int complain;
{ {
tree result;
if (type == error_mark_node) if (type == error_mark_node)
return type; return type;
...@@ -571,7 +573,32 @@ cp_build_qualified_type_real (type, type_quals, complain) ...@@ -571,7 +573,32 @@ cp_build_qualified_type_real (type, type_quals, complain)
= TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (element_type)); = TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (element_type));
return t; return t;
} }
return build_qualified_type (type, type_quals); else if (TYPE_PTRMEMFUNC_P (type))
{
/* For a pointer-to-member type, we can't just return a
cv-qualified version of the RECORD_TYPE. If we do, we
haven't change the field that contains the actual pointer to
a method, and so TYPE_PTRMEMFUNC_FN_TYPE will be wrong. */
tree t;
t = TYPE_PTRMEMFUNC_FN_TYPE (type);
t = cp_build_qualified_type_real (t, type_quals, complain);
return build_ptrmemfunc_type (t);
}
/* Retrieve (or create) the appropriately qualified variant. */
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. */
if (result != type
&& TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
TYPE_SET_PTRMEMFUNC_TYPE (result, NULL_TREE);
return result;
} }
/* Returns the canonical version of TYPE. In other words, if TYPE is /* Returns the canonical version of TYPE. In other words, if TYPE is
...@@ -1540,14 +1567,30 @@ search_tree (t, func) ...@@ -1540,14 +1567,30 @@ search_tree (t, func)
#define TRY(ARG) if (tmp=search_tree (ARG, func), tmp != NULL_TREE) return tmp #define TRY(ARG) if (tmp=search_tree (ARG, func), tmp != NULL_TREE) return tmp
tree tmp; tree tmp;
enum tree_code code;
if (t == NULL_TREE) if (t == NULL_TREE)
return t; return t;
if (tmp = func (t), tmp != NULL_TREE) tmp = func (t);
if (tmp)
return tmp; return tmp;
switch (TREE_CODE (t)) /* Handle some common cases up front. */
code = TREE_CODE (t);
if (TREE_CODE_CLASS (code) == '1')
{
TRY (TREE_OPERAND (t, 0));
return NULL_TREE;
}
else if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<')
{
TRY (TREE_OPERAND (t, 0));
TRY (TREE_OPERAND (t, 1));
return NULL_TREE;
}
switch (code)
{ {
case ERROR_MARK: case ERROR_MARK:
break; break;
...@@ -1611,35 +1654,8 @@ search_tree (t, func) ...@@ -1611,35 +1654,8 @@ search_tree (t, func)
TRY (TREE_OPERAND (t, 2)); TRY (TREE_OPERAND (t, 2));
break; break;
case MODIFY_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
case MIN_EXPR:
case MAX_EXPR:
case LSHIFT_EXPR:
case RSHIFT_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case BIT_AND_EXPR:
case BIT_ANDTC_EXPR:
case TRUTH_ANDIF_EXPR: case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR: case TRUTH_ORIF_EXPR:
case LT_EXPR:
case LE_EXPR:
case GT_EXPR:
case GE_EXPR:
case EQ_EXPR:
case NE_EXPR:
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case CEIL_MOD_EXPR:
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
case COMPOUND_EXPR:
case PREDECREMENT_EXPR: case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR: case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR: case POSTDECREMENT_EXPR:
...@@ -1654,28 +1670,16 @@ search_tree (t, func) ...@@ -1654,28 +1670,16 @@ search_tree (t, func)
break; break;
case SAVE_EXPR: case SAVE_EXPR:
case CONVERT_EXPR:
case ADDR_EXPR: case ADDR_EXPR:
case INDIRECT_REF: case INDIRECT_REF:
case NEGATE_EXPR:
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR: case TRUTH_NOT_EXPR:
case NOP_EXPR:
case NON_LVALUE_EXPR:
case COMPONENT_REF: case COMPONENT_REF:
case CLEANUP_POINT_EXPR: case CLEANUP_POINT_EXPR:
case LOOKUP_EXPR: case LOOKUP_EXPR:
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
TRY (TREE_OPERAND (t, 0)); TRY (TREE_OPERAND (t, 0));
break; break;
case MODOP_EXPR: case MODOP_EXPR:
case CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
case STATIC_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
case ARROW_EXPR: case ARROW_EXPR:
case DOTSTAR_EXPR: case DOTSTAR_EXPR:
case TYPEID_EXPR: case TYPEID_EXPR:
...@@ -1738,13 +1742,8 @@ search_tree (t, func) ...@@ -1738,13 +1742,8 @@ search_tree (t, func)
TRY (TYPE_PTRMEMFUNC_FN_TYPE (t)); TRY (TYPE_PTRMEMFUNC_FN_TYPE (t));
break; break;
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' not call
`report_error_function'. That could cause an infinite loop. */
default: default:
sorry ("initializer contains unrecognized tree code"); my_friendly_abort (19990803);
return error_mark_node;
} }
return NULL_TREE; return NULL_TREE;
...@@ -1773,6 +1772,11 @@ tree ...@@ -1773,6 +1772,11 @@ tree
no_linkage_check (t) no_linkage_check (t)
tree t; tree t;
{ {
/* There's no point in checking linkage on template functions; we
can't know their complete types. */
if (processing_template_decl)
return NULL_TREE;
t = search_tree (t, no_linkage_helper); t = search_tree (t, no_linkage_helper);
if (t != error_mark_node) if (t != error_mark_node)
return t; return t;
......
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
int* hp;
int* jp;
void f (int *ip, int kp = hp - jp)
{
}
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
template <class T>
struct S
{
void f (const T&);
void f (T&);
};
class C
{
};
typedef int (C::*cp)();
template struct S<cp>;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment