From c90e0199d03bba2ef8fd4bcc14e0318e11a1f0e0 Mon Sep 17 00:00:00 2001
From: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 19 Aug 1997 22:49:24 +0000
Subject: [PATCH] merge

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14853 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cp/ChangeLog | 13 +++++++++++++
 gcc/cp/call.c    | 34 +++++++++++++++++++++++++++++++++-
 gcc/cp/decl2.c   | 19 +++++++++++++++++++
 gcc/cp/parse.y   | 21 +++++++++++----------
 gcc/cp/pt.c      |  5 +++++
 gcc/cp/repo.c    |  2 +-
 6 files changed, 82 insertions(+), 12 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e54eb9d88884..78e52d5deb4a 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 ba313aaea48c..7180adc40e9f 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 5af605a83e14..0bfd43de33bb 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 8514148604d7..3b4033646084 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 f43488d62cfe..799b774a0519 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 c9406f23820a..b979da78b2c3 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)
-- 
GitLab