OSDN Git Service

Handle multi-level typenames and implicit typename in base list.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Sep 1997 18:56:40 +0000 (18:56 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Sep 1997 18:56:40 +0000 (18:56 +0000)
* parse.y (typename_sub{,[0-2]}): New rules.
(structsp, rule TYPENAME_KEYWORD): Use typename_sub.
(nonnested_type): New rule.
(complete_type_name): Use it.
(base_class.1): Use typename_sub and nonnested_type.
(nested_name_specifier): Don't elide std:: here.
* decl.c (make_typename_type): Handle getting a type for NAME.
(lookup_name_real): Turn std:: into :: here.

Rvalue conversions were removed in London.
* call.c (is_subseq): Don't consider lvalue transformations.
(build_conv): LVALUE_CONV and RVALUE_CONV get IDENTITY_RANK.
(joust): Reenable ?: kludge.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@15715 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/parse.y

index b33c996..c5e34ac 100644 (file)
@@ -1,3 +1,20 @@
+Thu Sep 25 11:11:13 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       Handle multi-level typenames and implicit typename in base list.
+       * parse.y (typename_sub{,[0-2]}): New rules.
+       (structsp, rule TYPENAME_KEYWORD): Use typename_sub.
+       (nonnested_type): New rule.
+       (complete_type_name): Use it.
+       (base_class.1): Use typename_sub and nonnested_type.
+       (nested_name_specifier): Don't elide std:: here.
+       * decl.c (make_typename_type): Handle getting a type for NAME.
+       (lookup_name_real): Turn std:: into :: here.
+
+       Rvalue conversions were removed in London.
+       * call.c (is_subseq): Don't consider lvalue transformations.
+       (build_conv): LVALUE_CONV and RVALUE_CONV get IDENTITY_RANK.
+       (joust): Reenable ?: kludge.
+
 1997-09-22  Brendan Kehoe  <brendan@lisa.cygnus.com>
 
        * decl.c (start_function): Up warning of no return type to be a
index a080c04..6855181 100644 (file)
@@ -3021,9 +3021,7 @@ build_conv (code, type, from)
        rank = STD_RANK;
       break;
 
-    case LVALUE_CONV:
     case QUAL_CONV:
-    case RVALUE_CONV:
       if (rank < EXACT_RANK)
        rank = EXACT_RANK;
 
@@ -5649,6 +5647,11 @@ static int
 is_subseq (ics1, ics2)
      tree ics1, ics2;
 {
+  /* Do not consider lvalue transformations here.  */
+  if (TREE_CODE (ics2) == RVALUE_CONV
+      || TREE_CODE (ics2) == LVALUE_CONV)
+    return 0;
+
   for (;; ics2 = TREE_OPERAND (ics2, 0))
     {
       if (TREE_CODE (ics2) == TREE_CODE (ics1)
@@ -6084,10 +6087,10 @@ joust (cand1, cand2)
          break;
       if (i == TREE_VEC_LENGTH (cand1->convs))
        return 1;
-#if 0
+
       /* Kludge around broken overloading rules whereby
-        bool ? void *const & : void *const & is ambiguous.  */
-      /* Huh?  Explain the problem better.  */
+        Integer a, b; test ? a : b; is ambiguous, since there's a builtin
+        that takes references and another that takes values.  */
       if (cand1->fn == ansi_opname[COND_EXPR])
        {
          tree c1 = TREE_VEC_ELT (cand1->convs, 1);
@@ -6103,7 +6106,6 @@ joust (cand1, cand2)
                return -1;
            }
        }
-#endif
     }
 
 tweak:
index e60cef6..df8066b 100644 (file)
@@ -4317,7 +4317,9 @@ make_typename_type (context, name)
 {
   tree t, d;
 
-  if (TREE_CODE (name) == TYPE_DECL)
+  if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
+    name = TYPE_IDENTIFIER (name);
+  else if (TREE_CODE (name) == TYPE_DECL)
     name = DECL_NAME (name);
   else if (TREE_CODE (name) != IDENTIFIER_NODE)
     my_friendly_abort (2000);
@@ -4378,6 +4380,10 @@ lookup_name_real (name, prefer_type, nonclass)
       yylex = 1;
       prefer_type = looking_for_typename;
 
+      /* std:: becomes :: for now.  */
+      if (got_scope == std_node)
+       got_scope = void_type_node;
+
       if (got_scope)
        type = got_scope;
       else if (got_object != error_mark_node)
index 7d9d5db..16e5db9 100644 (file)
@@ -258,12 +258,12 @@ empty_parms ()
 %type <ttype> template_type template_arg_list template_arg
 %type <ttype> condition xcond paren_cond_or_null
 %type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
-%type <ttype> complete_type_name notype_identifier
+%type <ttype> complete_type_name notype_identifier nonnested_type
 %type <ttype> complex_type_name nested_name_specifier_1
 %type <itype> nomods_initdecls nomods_initdcl0
 %type <ttype> new_initializer new_placement
 %type <ttype> using_decl .poplevel
-
+%type <ttype> typename_sub typename_sub0 typename_sub1 typename_sub2
 /* in order to recognize aggr tags as defining and thus shadowing.  */
 %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
 %type <ttype> named_class_head_sans_basetype_defn
@@ -2190,11 +2190,8 @@ structsp:
        | ENUM complex_type_name
                { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); 
                  $$.new_type_flag = 0; }
-       | TYPENAME_KEYWORD nested_name_specifier identifier
-               { $$.t = make_typename_type ($2, $3); 
-                 $$.new_type_flag = 0; }
-       | TYPENAME_KEYWORD global_scope nested_name_specifier identifier
-               { $$.t = make_typename_type ($3, $4); 
+       | TYPENAME_KEYWORD typename_sub
+               { $$.t = $2;
                  $$.new_type_flag = 0; }
        /* C++ extensions, merged with C to avoid shift/reduce conflicts */
        | class_head left_curly opt.component_decl_list '}' maybe_attribute
@@ -2437,11 +2434,8 @@ base_class:
        ;
 
 base_class.1:
-         complete_type_name
-       | TYPENAME_KEYWORD nested_name_specifier identifier
-               { $$ = TYPE_MAIN_DECL (make_typename_type ($2, $3)); }
-       | TYPENAME_KEYWORD global_scope nested_name_specifier identifier
-               { $$ = TYPE_MAIN_DECL (make_typename_type ($3, $4)); }
+         typename_sub
+       | nonnested_type
        | SIGOF '(' expr ')'
                {
                  if (current_aggr == signature_type_node)
@@ -2945,7 +2939,7 @@ after_type_declarator:
        | direct_after_type_declarator
        ;
 
-complete_type_name:
+nonnested_type:
          type_name  %prec EMPTY
                {
                  if (TREE_CODE ($1) == IDENTIFIER_NODE)
@@ -2974,6 +2968,10 @@ complete_type_name:
                    $$ = $2;
                  got_scope = NULL_TREE;
                }
+       ;
+
+complete_type_name:
+         nonnested_type
        | nested_type
        | global_scope nested_type
                { $$ = $2; }
@@ -3119,11 +3117,7 @@ nested_name_specifier_1:
                {
                  if (TREE_CODE ($$) == IDENTIFIER_NODE)
                    $$ = lastiddecl;
-                 if (TREE_CODE ($$) == NAMESPACE_DECL
-                     && DECL_NAME ($$) == get_identifier ("std"))
-                   got_scope = void_type_node;
-                 else
-                   got_scope = $$;
+                 got_scope = $$;
                }
        | template_type SCOPE
                { got_scope = $$ = complete_type (TREE_TYPE ($1)); }
@@ -3139,6 +3133,66 @@ nested_name_specifier_1:
                { goto failed_scope; } */
        ;
 
+typename_sub:
+         typename_sub0
+       | global_scope typename_sub0
+               { $$ = $2; }
+       ;
+
+typename_sub0:
+         typename_sub1 identifier
+               {
+                 if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't')
+                   $$ = make_typename_type ($1, $2);
+                 else if (TREE_CODE ($2) == IDENTIFIER_NODE)
+                   cp_error ("`%T' is not a class or namespace", $2);
+                 else
+                   $$ = $2;
+               }
+       ;
+
+typename_sub1:
+         typename_sub2
+               {
+                 if (TREE_CODE ($1) == IDENTIFIER_NODE)
+                   cp_error ("`%T' is not a class or namespace", $1);
+               }
+       | typename_sub1 typename_sub2
+               {
+                 if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't')
+                   $$ = make_typename_type ($1, $2);
+                 else if (TREE_CODE ($2) == IDENTIFIER_NODE)
+                   cp_error ("`%T' is not a class or namespace", $2);
+                 else
+                   $$ = $2;
+               }
+       ;
+
+typename_sub2:
+         TYPENAME SCOPE
+               {
+                 if (TREE_CODE ($1) != IDENTIFIER_NODE)
+                   $$ = lastiddecl;
+                 got_scope = $$ = complete_type (TREE_TYPE ($$));
+               }
+       | SELFNAME SCOPE
+               {
+                 if (TREE_CODE ($1) != IDENTIFIER_NODE)
+                   $$ = lastiddecl;
+                 got_scope = $$ = complete_type (TREE_TYPE ($$));
+               }
+       | template_type SCOPE
+               { got_scope = $$ = complete_type (TREE_TYPE ($$)); }
+       | PTYPENAME SCOPE
+       | IDENTIFIER SCOPE
+       | NSNAME SCOPE
+               {
+                 if (TREE_CODE ($$) == IDENTIFIER_NODE)
+                   $$ = lastiddecl;
+                 got_scope = $$;
+               }
+       ;
+
 complex_type_name:
          global_scope type_name
                {