aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/call.c34
-rw-r--r--gcc/cp/decl2.c19
-rw-r--r--gcc/cp/parse.y21
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/cp/repo.c2
6 files changed, 82 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e54eb9d..78e52d5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+Tue Aug 19 02:26:07 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (is_subseq): New fn.
+ (compare_ics): Use it.
+
+ * repo.c (finish_repo): Don't crash on no args.
+
+ * parse.y (named_complex_class_head_sans_basetype): Handle
+ explicit global scope.
+ * decl2.c (handle_class_head): New fn.
+
+ * pt.c (unify): Add CONST_DECL case.
+
Thu Aug 14 10:05:13 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* rtti.c (permanent_obstack): Fix decl to not be a pointer.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ba313aa..7180adc 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5452,6 +5452,31 @@ compare_qual (ics1, ics2)
return 0;
}
+/* Determine whether standard conversion sequence ICS1 is a proper
+ subsequence of ICS2. We assume that a conversion of the same code
+ between the same types indicates a subsequence. */
+
+static int
+is_subseq (ics1, ics2)
+ tree ics1, ics2;
+{
+ for (;;)
+ {
+ ics2 = TREE_OPERAND (ics2, 0));
+
+ if (TREE_CODE (ics2) == TREE_CODE (ics1)
+ && comptypes (TREE_TYPE (ics2), TREE_TYPE (ics1), 1)
+ && comptypes (TREE_TYPE (TREE_OPERAND (ics2, 0)),
+ TREE_TYPE (TREE_OPERAND (ics1, 0)), 1))
+ return 1;
+
+ if (TREE_CODE (ics2) == USER_CONV
+ || TREE_CODE (ics2) == AMBIG_CONV
+ || TREE_CODE (ics2) == IDENTITY_CONV)
+ return 0;
+ }
+}
+
/* Compare two implicit conversion sequences according to the rules set out in
[over.ics.rank]. Return values:
@@ -5549,7 +5574,14 @@ compare_ics (ics1, ics2)
#endif
if (TREE_CODE (main1) != TREE_CODE (main2))
- return 0;
+ {
+ /* ...if S1 is a proper subsequence of S2 */
+ if (is_subseq (main1, main2))
+ return 1;
+ if (is_subseq (main2, main1))
+ return -1;
+ return 0;
+ }
if (TREE_CODE (main1) == PTR_CONV || TREE_CODE (main1) == PMEM_CONV
|| TREE_CODE (main1) == REF_BIND || TREE_CODE (main1) == BASE_CONV)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 5af605a..0bfd43d 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3710,3 +3710,22 @@ mark_used (decl)
if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
instantiate_decl (decl);
}
+
+/* Helper function for named_class_head_sans_basetype nonterminal. */
+
+tree
+handle_class_head (aggr, scope, id)
+ tree aggr, scope, id;
+{
+ if (TREE_CODE (id) == TYPE_DECL)
+ return id;
+
+ if (scope)
+ cp_error ("`%T' does not have a nested type named `%D'", scope, id);
+ else
+ cp_error ("no file-scope type named `%D'", id);
+
+ id = xref_tag
+ (aggr, make_anon_name (), NULL_TREE, 1);
+ return TYPE_MAIN_DECL (id);
+}
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 8514148..3b40336 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -2280,16 +2280,17 @@ named_complex_class_head_sans_basetype:
aggr nested_name_specifier identifier
{
current_aggr = $1;
- if (TREE_CODE ($3) == TYPE_DECL)
- $$ = $3;
- else
- {
- cp_error ("`%T' does not have a nested type named `%D'",
- $2, $3);
- $$ = xref_tag
- (current_aggr, make_anon_name (), NULL_TREE, 1);
- $$ = TYPE_MAIN_DECL ($$);
- }
+ $$ = handle_class_head ($1, $2, $3);
+ }
+ | aggr global_scope nested_name_specifier identifier
+ {
+ current_aggr = $1;
+ $$ = handle_class_head ($1, $3, $4);
+ }
+ | aggr global_scope identifier
+ {
+ current_aggr = $1;
+ $$ = handle_class_head ($1, NULL_TREE, $3);
}
| aggr template_type
{ current_aggr = $$; $$ = $2; }
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f43488d..799b774 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2945,6 +2945,11 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
return unify (tparms, targs, ntparms, TREE_TYPE (parm),
TREE_TYPE (arg), nsubsts, strict);
+ case CONST_DECL:
+ if (arg != decl_constant_value (parm))
+ return 1;
+ return 0;
+
default:
sorry ("use of `%s' in template type unification",
tree_code_name [(int) TREE_CODE (parm)]);
diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c
index c9406f2..b979da7 100644
--- a/gcc/cp/repo.c
+++ b/gcc/cp/repo.c
@@ -420,7 +420,7 @@ finish_repo ()
if (strcmp (old_main, main_input_filename) != 0
|| strcmp (old_dir, dir) != 0
|| (args == NULL) != (old_args == NULL)
- || strcmp (old_args, args) != 0)
+ || (args && strcmp (old_args, args) != 0))
repo_changed = 1;
if (! repo_changed || errorcount || sorrycount)