aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-08-06 18:20:27 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-08-06 18:20:27 +0000
commit2adeacc9b5d8a9e6b2fe2c328b914df559b65907 (patch)
tree095df14265db59289275bbcf68dc5206b26f72dd
parente7eacc8e2774b2457c625cb3b86e90d93af42382 (diff)
downloadgcc-2adeacc9b5d8a9e6b2fe2c328b914df559b65907.zip
gcc-2adeacc9b5d8a9e6b2fe2c328b914df559b65907.tar.gz
gcc-2adeacc9b5d8a9e6b2fe2c328b914df559b65907.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/error.c6
-rw-r--r--gcc/cp/lex.c1
-rw-r--r--gcc/cp/tree.c102
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/defarg3.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C18
6 files changed, 99 insertions, 50 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 19fe82d..aaa8ecf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+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>
* decl.c (pushdecl): Only give an error for shadowing a parm
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 22be201..c455e81 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1521,6 +1521,7 @@ dump_expr (t, nop)
case GE_EXPR:
case EQ_EXPR:
case NE_EXPR:
+ case EXACT_DIV_EXPR:
dump_binary_op (opname_tab[(int) TREE_CODE (t)], t);
break;
@@ -1847,7 +1848,10 @@ dump_binary_op (opstring, t)
OB_PUTC ('(');
dump_expr (TREE_OPERAND (t, 0), 1);
OB_PUTC (' ');
- OB_PUTCP (opstring);
+ if (opstring)
+ OB_PUTCP (opstring);
+ else
+ OB_PUTS ("<unknown operator>");
OB_PUTC (' ');
dump_expr (TREE_OPERAND (t, 1), 1);
OB_PUTC (')');
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 1bcb667..5afda55 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -761,6 +761,7 @@ init_parse (filename)
opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
+ opname_tab[(int) EXACT_DIV_EXPR] = "/";
opname_tab[(int) NEGATE_EXPR] = "-";
opname_tab[(int) MIN_EXPR] = "<?";
opname_tab[(int) MAX_EXPR] = ">?";
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index f40632a..7b5c16d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -503,6 +503,8 @@ cp_build_qualified_type_real (type, type_quals, complain)
int type_quals;
int complain;
{
+ tree result;
+
if (type == error_mark_node)
return type;
@@ -571,7 +573,32 @@ cp_build_qualified_type_real (type, type_quals, complain)
= TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (element_type));
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
@@ -1540,14 +1567,30 @@ search_tree (t, func)
#define TRY(ARG) if (tmp=search_tree (ARG, func), tmp != NULL_TREE) return tmp
tree tmp;
+ enum tree_code code;
if (t == NULL_TREE)
return t;
-
- if (tmp = func (t), tmp != NULL_TREE)
+
+ tmp = func (t);
+ if (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:
break;
@@ -1611,35 +1654,8 @@ search_tree (t, func)
TRY (TREE_OPERAND (t, 2));
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_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 PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
@@ -1654,28 +1670,16 @@ search_tree (t, func)
break;
case SAVE_EXPR:
- case CONVERT_EXPR:
case ADDR_EXPR:
case INDIRECT_REF:
- case NEGATE_EXPR:
- case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:
- case NOP_EXPR:
- case NON_LVALUE_EXPR:
case COMPONENT_REF:
case CLEANUP_POINT_EXPR:
case LOOKUP_EXPR:
- case SIZEOF_EXPR:
- case ALIGNOF_EXPR:
TRY (TREE_OPERAND (t, 0));
break;
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 DOTSTAR_EXPR:
case TYPEID_EXPR:
@@ -1738,13 +1742,8 @@ search_tree (t, func)
TRY (TYPE_PTRMEMFUNC_FN_TYPE (t));
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:
- sorry ("initializer contains unrecognized tree code");
- return error_mark_node;
-
+ my_friendly_abort (19990803);
}
return NULL_TREE;
@@ -1773,6 +1772,11 @@ tree
no_linkage_check (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);
if (t != error_mark_node)
return t;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/defarg3.C b/gcc/testsuite/g++.old-deja/g++.other/defarg3.C
new file mode 100644
index 0000000..84792c8
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/defarg3.C
@@ -0,0 +1,9 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+int* hp;
+int* jp;
+
+void f (int *ip, int kp = hp - jp)
+{
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C
new file mode 100644
index 0000000..f6125cd
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C
@@ -0,0 +1,18 @@
+// 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>;
+