diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/call.c | 34 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 19 | ||||
-rw-r--r-- | gcc/cp/parse.y | 21 | ||||
-rw-r--r-- | gcc/cp/pt.c | 5 | ||||
-rw-r--r-- | gcc/cp/repo.c | 2 |
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) |