]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/8442, c++/8806
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Fri, 1 Aug 2003 15:06:02 +0000 (15:06 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Fri, 1 Aug 2003 15:06:02 +0000 (15:06 +0000)
PR c++/8442, c++/8806
* decl.c (qualify_lookup): Accept TEMPLATE_DECL if types are
preferred.
(check_elaborated_type_specifier): Add allow_template_p
parameter.  Check tag mismatch and class template.
(xref_tag): Add template_header_p parameter.  Add assertion
that name is an IDENTIFIER_NODE.  Remove implicit typename
warning.  Simplify lookup process if globalize is true.
(cxx_init_decl_processing): Adjust call to xref_tag.
(xref_tag_from_type): Likewise.
* decl2.c (handle_class_head): Likewise.
* parser.c (cp_parser_elaborated_type_specifier,
cp_parser_class_head): Likewise.
* rtti.c (init_rtti_processing, build_dynamic_cast1,
tinfo_base_init, emit_support_tinfos): Likewise.
* class.c (is_base_of_enclosing_class): Remove.
* pt.c (convert_template_argument): Don't accept RECORD_TYPE as
template template argument.
* cp-tree.h (xref_tag): Adjust declaration.
(is_base_of_enclosing_class): Remove.
* NEWS: Document template template argument change.

* g++.dg/template/elab1.C: Likewise.
* g++.dg/template/type2.C: Likewise.
* g++.dg/template/ttp3.C: Adjust expected error message.
* g++.old-deja/g++.law/visibility13.C: Likewise.
* g++.old-deja/g++.niklas/t135.C: Likewise.
* g++.old-deja/g++.pt/ttp41.C: Likewise.
* g++.old-deja/g++.pt/ttp43.C: Use qualified name for template
template argument.
* g++.old-deja/g++.pt/ttp44.C: Likewise.

From-SVN: r70048

18 files changed:
gcc/cp/ChangeLog
gcc/cp/NEWS
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/elab1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ttp3.C
gcc/testsuite/g++.dg/template/type2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.law/visibility13.C
gcc/testsuite/g++.old-deja/g++.niklas/t135.C
gcc/testsuite/g++.old-deja/g++.pt/ttp41.C
gcc/testsuite/g++.old-deja/g++.pt/ttp43.C
gcc/testsuite/g++.old-deja/g++.pt/ttp44.C

index 83b901e36dfe7deba46d9edb209b68e5598212fe..c50f99f6fb3c2fceab644c7899484f2ecee0f20c 100644 (file)
@@ -1,3 +1,27 @@
+2003-08-01  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/8442, c++/8806
+       * decl.c (qualify_lookup): Accept TEMPLATE_DECL if types are
+       preferred.
+       (check_elaborated_type_specifier): Add allow_template_p
+       parameter.  Check tag mismatch and class template.
+       (xref_tag): Add template_header_p parameter.  Add assertion
+       that name is an IDENTIFIER_NODE.  Remove implicit typename
+       warning.  Simplify lookup process if globalize is true.
+       (cxx_init_decl_processing): Adjust call to xref_tag.
+       (xref_tag_from_type): Likewise.
+       * decl2.c (handle_class_head): Likewise.
+       * parser.c (cp_parser_elaborated_type_specifier,
+       cp_parser_class_head): Likewise.
+       * rtti.c (init_rtti_processing, build_dynamic_cast1,
+       tinfo_base_init, emit_support_tinfos): Likewise.
+       * class.c (is_base_of_enclosing_class): Remove.
+       * pt.c (convert_template_argument): Don't accept RECORD_TYPE as
+       template template argument.
+       * cp-tree.h (xref_tag): Adjust declaration.
+       (is_base_of_enclosing_class): Remove.
+       * NEWS: Document template template argument change.
+
 2003-08-01  Nathan Sidwell  <nathan@codesourcery.com>
 
        * parser.c (cp_parser_init_declarator,
index 2642aeda0eb0ff9ec2ebd45542b932d23a563391..00a50e4cd82a8880f2862f3882322280d1ba7eb0 100644 (file)
@@ -76,6 +76,19 @@ removed.
 * Covariant returns are implemented for all but varadic functions that
   require an adjustment.
 
+* Inside the scope of a template class, the name of the class itself
+  is no longer a valid template template argument.  Instead, you now have
+  to qualify the name by its scope.  For example:
+
+    template <template <class> class TT> class X {};
+    template <class T> class Y {
+      X<Y> x; // Invalid.
+    };
+
+  The valid code for the above example is:
+
+      X< ::Y> x; // Valid.  Note that `<:' is a digraph and means `['.
+
 *** Changes in GCC 3.3:
 
 * The "new X = 3" extension has been removed; you must now use "new X(3)".
index 527eae4611cf8299129202e585f1ae68efd4bdfb..4ff41fbe49ae6c79ca37dba1fbaadb95aa605808 100644 (file)
@@ -6333,21 +6333,6 @@ get_enclosing_class (tree type)
   return NULL_TREE;
 }
 
-/* Return 1 if TYPE or one of its enclosing classes is derived from BASE.  */
-
-int
-is_base_of_enclosing_class (tree base, tree type)
-{
-  while (type)
-    {
-      if (lookup_base (type, base, ba_any, NULL))
-       return 1;
-
-      type = get_enclosing_class (type);
-    }
-  return 0;
-}
-
 /* Note that NAME was looked up while the current class was being
    defined and that the result of that lookup was DECL.  */
 
index f62255b2f39c6ee6c4a3771509b309885d7c4fff..cfb765af753147404b15b2e418e606ee9a2caeac 100644 (file)
@@ -3603,7 +3603,6 @@ extern int same_signature_p                       (tree, tree);
 extern void warn_hidden                                (tree);
 extern void maybe_add_class_template_decl_list (tree, tree, int);
 extern tree get_enclosing_class                        (tree);
-int is_base_of_enclosing_class                 (tree, tree);
 extern void unreverse_member_declarations       (tree);
 extern void invalidate_class_lookup_cache       (void);
 extern void maybe_note_name_used_in_class       (tree, tree);
@@ -3731,7 +3730,7 @@ extern tree get_scope_of_declarator             (tree);
 extern void grok_special_member_properties     (tree);
 extern int grok_ctor_properties                        (tree, tree);
 extern void grok_op_properties                 (tree, int);
-extern tree xref_tag                           (enum tag_types, tree, tree, bool);
+extern tree xref_tag                           (enum tag_types, tree, tree, bool, bool);
 extern tree xref_tag_from_type                 (tree, tree, int);
 extern void xref_basetypes                     (tree, tree);
 extern tree start_enum                         (tree);
index 3ed6744a9e0685c7babe7f9ea2ef4be0862ce18b..95984c9be06ea8abcbba1e2e115269dcf63708cf 100644 (file)
@@ -5753,7 +5753,8 @@ qualify_lookup (tree val, int flags)
     return val;
   if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
     return val;
-  if ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) == TYPE_DECL)
+  if ((flags & LOOKUP_PREFER_TYPES)
+      && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
     return val;
   if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
     return NULL_TREE;
@@ -6339,7 +6340,7 @@ cxx_init_decl_processing (void)
     push_namespace (std_identifier);
     bad_alloc_type_node 
       = xref_tag (class_type, get_identifier ("bad_alloc"), 
-                 /*attributes=*/NULL_TREE, 1);
+                 /*attributes=*/NULL_TREE, true, false);
     pop_namespace ();
     ptr_ftype_sizetype 
       = build_function_type (ptr_type_node,
@@ -12553,15 +12554,15 @@ tag_name (enum tag_types code)
 /* Name lookup in an elaborated-type-specifier (after the keyword
    indicated by TAG_CODE) has found TYPE.  If the
    elaborated-type-specifier is invalid, issue a diagnostic and return
-   error_mark_node; otherwise, return TYPE itself.  */
+   error_mark_node; otherwise, return TYPE itself.  
+   If ALLOW_TEMPLATE_P is true, TYPE may be a class template.  */
 
 static tree
 check_elaborated_type_specifier (enum tag_types tag_code,
-                                tree type)
+                                tree type,
+                                bool allow_template_p)
 {
-  tree t;
-
-  t = follow_tag_typedef (type);
+  tree t = follow_tag_typedef (type);
 
   /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
      template type-parameter, the elaborated-type-specifier is
@@ -12578,30 +12579,67 @@ check_elaborated_type_specifier (enum tag_types tag_code,
             type, tag_name (tag_code));
       t = error_mark_node;
     }
+  else if (TREE_CODE (type) != RECORD_TYPE
+          && TREE_CODE (type) != UNION_TYPE
+          && tag_code != enum_type)
+    {
+      error ("`%T' referred to as `%s'", type, tag_name (tag_code));
+      t = error_mark_node;
+    }
+  else if (TREE_CODE (type) != ENUMERAL_TYPE
+          && tag_code == enum_type)
+    {
+      error ("`%T' referred to as enum", type);
+      t = error_mark_node;
+    }
+  else if (!allow_template_p
+          && TREE_CODE (type) == RECORD_TYPE
+          && CLASSTYPE_IS_TEMPLATE (type))
+    {
+      /* If a class template appears as elaborated type specifier
+        without a template header such as:
+
+          template <class T> class C {};
+          void f(class C);             // No template header here
+
+        then the required template argument is missing.  */
+
+      error ("template argument required for `%s %T'",
+            tag_name (tag_code),
+            DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
+      t = error_mark_node;
+    }
 
   return t;
 }
 
-/* Get the struct, enum or union (CODE says which) with tag NAME.
+/* Get the struct, enum or union (TAG_CODE says which) with tag NAME.
    Define the tag as a forward-reference if it is not defined.
 
-   C++: If a class derivation is given, process it here, and report
-   an error if multiple derivation declarations are not identical.
+   If a declaration is given, process it here, and report an error if
+   multiple declarations are not identical.  ATTRIBUTE is the attribute
+   appeared in this declaration.
 
-   If this is a definition, come in through xref_tag and only look in
+   GLOBALIZE is false when this is also a definition.  Only look in
    the current frame for the name (since C++ allows new names in any
-   scope.)  */
+   scope.)
+
+   TEMPLATE_HEADER_P is true when this declaration is preceded by
+   a set of template parameters.  */
 
 tree
 xref_tag (enum tag_types tag_code, tree name, tree attributes, 
-         bool globalize)
+         bool globalize, bool template_header_p)
 {
   enum tree_code code;
-  register tree ref, t;
+  register tree t;
   struct cp_binding_level *b = current_binding_level;
   tree context = NULL_TREE;
 
   timevar_push (TV_NAME_LOOKUP);
+
+  my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
+
   switch (tag_code)
     {
     case record_type:
@@ -12618,93 +12656,50 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
       abort ();
     }
 
-  /* If a cross reference is requested, look up the type
-     already defined for this tag and return it.  */
-  if (TYPE_P (name))
-    {
-      t = name;
-      name = TYPE_IDENTIFIER (t);
-    }
-  else
-    t = IDENTIFIER_TYPE_VALUE (name);
-
-  /* Warn about 'friend struct Inherited;' doing the wrong thing.  */
-  if (t && globalize && TREE_CODE (t) == TYPENAME_TYPE)
-    {
-      static int explained;
-      tree shadowed;
-
-      warning ("`%s %T' declares a new type at namespace scope",
-                 tag_name (tag_code), name);
-      if (!explained++)
-       warning ("  names from dependent base classes are not visible to unqualified name lookup - to refer to the inherited type, say `%s %T::%T'",
-                   tag_name (tag_code),
-                   constructor_name (current_class_type),
-                   TYPE_IDENTIFIER (t));
-
-      /* We need to remove the class scope binding for the
-         TYPENAME_TYPE as otherwise poplevel_class gets confused.  */
-      for (shadowed = b->class_shadowed;
-          shadowed;
-          shadowed = TREE_CHAIN (shadowed))
-       if (TREE_TYPE (shadowed) == TYPE_NAME (t))
-         {
-           TREE_PURPOSE (shadowed) = NULL_TREE;
-           break;
-         }
-    }
-
-  if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM
-      && TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM)
-    t = NULL_TREE;
-
   if (! globalize)
     {
       /* If we know we are defining this tag, only look it up in
         this scope and don't try to find it as a type.  */
-      ref = lookup_tag (code, name, b, 1);
+      t = lookup_tag (code, name, b, 1);
     }
   else
     {
-      if (t)
-       {
-         ref = check_elaborated_type_specifier (tag_code, t);
-         if (ref == error_mark_node)
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-       }
-      else
-       ref = lookup_tag (code, name, b, 0);
+      tree decl = lookup_name (name, 1);
+
+      if (decl && DECL_CLASS_TEMPLATE_P (decl))
+       decl = DECL_TEMPLATE_RESULT (decl);
 
-      if (! ref)
+      if (decl && TREE_CODE (decl) == TYPE_DECL)
        {
-         /* Try finding it as a type declaration.  If that wins,
-            use it.  */
-         ref = lookup_name (name, 1);
+         /* Two cases we need to consider when deciding if a class
+            template is allowed as an elaborated type specifier:
+            1. It is a self reference to its own class.
+            2. It comes with a template header.
 
-         if (ref != NULL_TREE
-             && processing_template_decl
-             && DECL_CLASS_TEMPLATE_P (ref)
-             && template_class_depth (current_class_type) == 0)
-           /* Since GLOBALIZE is true, we're declaring a global
-              template, so we want this type.  */
-           ref = DECL_TEMPLATE_RESULT (ref);
+            For example:
 
-         if (ref && TREE_CODE (ref) == TYPE_DECL)
-           {
-             ref = check_elaborated_type_specifier (tag_code, 
-                                                    TREE_TYPE (ref));
-             if (ref == error_mark_node)
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-             if (ref && TREE_CODE (ref) != code)
-               ref = NULL_TREE;
-           }
-         else
-           ref = NULL_TREE;
+              template <class T> class C {
+                class C *c1;           // DECL_SELF_REFERENCE_P is true
+                class D;
+              };
+              template <class U> class C; // template_header_p is true
+              template <class T> class C<T>::D {
+                class C *c2;           // DECL_SELF_REFERENCE_P is true
+              };  */
+
+         t = check_elaborated_type_specifier (tag_code, 
+                                              TREE_TYPE (decl),
+                                              template_header_p
+                                              | DECL_SELF_REFERENCE_P (decl));
+         if (t == error_mark_node)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
        }
+      else
+       t = NULL_TREE;
 
-      if (ref && current_class_type
+      if (t && current_class_type
          && template_class_depth (current_class_type)
-         && PROCESSING_REAL_TEMPLATE_DECL_P ())
+         && template_header_p)
        {
          /* Since GLOBALIZE is nonzero, we are not looking at a
             definition of this tag.  Since, in addition, we are currently
@@ -12742,12 +12737,12 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
              accomplish this by making sure that the new type we
              create to represent this declaration has the right
              TYPE_CONTEXT.  */
-         context = TYPE_CONTEXT (ref);
-         ref = NULL_TREE;
+         context = TYPE_CONTEXT (t);
+         t = NULL_TREE;
        }
     }
 
-  if (! ref)
+  if (! t)
     {
       /* If no such tag is yet defined, create a forward-reference node
         and record it as the "definition".
@@ -12757,44 +12752,41 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
        {
          error ("use of enum `%#D' without previous declaration", name);
 
-         ref = make_node (ENUMERAL_TYPE);
+         t = make_node (ENUMERAL_TYPE);
 
          /* Give the type a default layout like unsigned int
             to avoid crashing if it does not get defined.  */
-         TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
-         TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
-         TYPE_USER_ALIGN (ref) = 0;
-         TREE_UNSIGNED (ref) = 1;
-         TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
-         TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
-         TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
+         TYPE_MODE (t) = TYPE_MODE (unsigned_type_node);
+         TYPE_ALIGN (t) = TYPE_ALIGN (unsigned_type_node);
+         TYPE_USER_ALIGN (t) = 0;
+         TREE_UNSIGNED (t) = 1;
+         TYPE_PRECISION (t) = TYPE_PRECISION (unsigned_type_node);
+         TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (unsigned_type_node);
+         TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (unsigned_type_node);
 
          /* Enable us to recognize when a type is created in class context.
             To do nested classes correctly, this should probably be cleared
             out when we leave this classes scope.  Currently this in only
             done in `start_enum'.  */
 
-         pushtag (name, ref, globalize);
+         pushtag (name, t, globalize);
        }
       else
        {
-         struct cp_binding_level *old_b = class_binding_level;
-
-         ref = make_aggr_type (code);
-         TYPE_CONTEXT (ref) = context;
-         pushtag (name, ref, globalize);
-         class_binding_level = old_b;
+         t = make_aggr_type (code);
+         TYPE_CONTEXT (t) = context;
+         pushtag (name, t, globalize);
        }
     }
   else
     {
-      if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref))
-       redeclare_class_template (ref, current_template_parms);
+      if (!globalize && processing_template_decl && IS_AGGR_TYPE (t))
+       redeclare_class_template (t, current_template_parms);
     }
 
-  TYPE_ATTRIBUTES (ref) = attributes;
+  TYPE_ATTRIBUTES (t) = attributes;
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ref);
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 }
 
 tree
@@ -12810,7 +12802,7 @@ xref_tag_from_type (tree old, tree id, int globalize)
   if (id == NULL_TREE)
     id = TYPE_IDENTIFIER (old);
 
-  return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize);
+  return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false);
 }
 
 /* REF is a type (named NAME), for which we have just seen some
index a8c62634469ec081d5c6e564342c1a2c27de03f2..6f0686069e13d5db7a18cf127ab47d1fea3c1bcd 100644 (file)
@@ -4278,7 +4278,7 @@ handle_class_head (enum tag_types tag_kind, tree scope, tree id,
   
   if (!decl)
     {
-      decl = xref_tag (tag_kind, id, attributes, false);
+      decl = xref_tag (tag_kind, id, attributes, false, false);
       if (decl == error_mark_node)
        return error_mark_node;
       decl = TYPE_MAIN_DECL (decl);
index 63c81720caf94e992b57677714869250f8cd0798..fce69ca6fe68aef17eb255ef22c991cfa5f0fd95 100644 (file)
@@ -8553,7 +8553,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
                           (is_friend 
                            || !is_declaration
                            || cp_lexer_next_token_is_not (parser->lexer, 
-                                                          CPP_SEMICOLON)));
+                                                          CPP_SEMICOLON)),
+                          parser->num_template_parameter_lists);
        }
     }
   if (tag_type != enum_type)
@@ -11380,7 +11381,8 @@ cp_parser_class_head (cp_parser* parser,
       /* If the class was unnamed, create a dummy name.  */
       if (!id)
        id = make_anon_name ();
-      type = xref_tag (class_key, id, attributes, /*globalize=*/0);
+      type = xref_tag (class_key, id, attributes, /*globalize=*/false,
+                      parser->num_template_parameter_lists);
     }
   else
     {
index ef6592a7e48201c55b8bd2d18fba15f38cabcd23..d2e6bf33f81a0126b6cddb81f543ebc0ff4c4198 100644 (file)
@@ -3431,33 +3431,15 @@ convert_template_argument (tree parm,
   requires_type = (TREE_CODE (parm) == TYPE_DECL
                   || requires_tmpl_type);
 
-  if (TREE_CODE (arg) != RECORD_TYPE)
-    is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
-                    && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
-                   || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
-                   || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
-  else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg)
-          && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg)))
-    {
-      if (is_base_of_enclosing_class (arg, current_class_type))
-       /* This is a template name used within the scope of the
-          template. It could be the template, or it could be the
-          instantiation. Choose whichever makes sense.  */
-       is_tmpl_type = requires_tmpl_type;
-      else
-       is_tmpl_type = 1;
-    }
-  else
-    /* It is a non-template class, or a specialization of a template
-       class, or a non-template member of a template class.  */
-    is_tmpl_type = 0;
+  is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
+                  && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+                 || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+                 || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
   
   if (is_tmpl_type
       && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
          || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
     arg = TYPE_STUB_DECL (arg);
-  else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
-    arg = CLASSTYPE_TI_TEMPLATE (arg);
 
   is_type = TYPE_P (arg) || is_tmpl_type;
 
index baaff74d68b11df5f9844fcfc1b243d9fe59371f..5e3437fba74a062ffb9150419ed687402ce07bda 100644 (file)
@@ -120,7 +120,7 @@ init_rtti_processing (void)
   push_namespace (std_identifier);
   type_info_type_node 
     = xref_tag (class_type, get_identifier ("type_info"),
-               /*attributes=*/NULL_TREE, 1);
+               /*attributes=*/NULL_TREE, true, false);
   pop_namespace ();
   const_type_info_type = build_qualified_type (type_info_type_node, 
                                               TYPE_QUAL_CONST);
@@ -639,7 +639,7 @@ build_dynamic_cast_1 (tree type, tree expr)
              tinfo_ptr = xref_tag (class_type,
                                    get_identifier ("__class_type_info"),
                                    /*attributes=*/NULL_TREE,
-                                   1);
+                                   true, false);
              
              tinfo_ptr = build_pointer_type
                (build_qualified_type
@@ -774,7 +774,7 @@ tinfo_base_init (tree desc, tree target)
   
       push_nested_namespace (abi_node);
       real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
-                           /*attributes=*/NULL_TREE, 1);
+                           /*attributes=*/NULL_TREE, true, false);
       pop_nested_namespace (abi_node);
   
       if (!COMPLETE_TYPE_P (real_type))
@@ -1371,7 +1371,7 @@ emit_support_tinfos (void)
   bltn_type = xref_tag (class_type,
                        get_identifier ("__fundamental_type_info"), 
                        /*attributes=*/NULL_TREE,
-                       1);
+                       true, false);
   pop_nested_namespace (abi_node);
   if (!COMPLETE_TYPE_P (bltn_type))
     return;
index 28e6e20eb0b0289d161ac7cc6d60af39c234f292..8b96d845f0e8606931d31cf627bc1e2a08dfae84 100644 (file)
@@ -1,3 +1,16 @@
+2003-08-01  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/8442, c++/8806
+       * g++.dg/template/elab1.C: New test.
+       * g++.dg/template/type2.C: Likewise.
+       * g++.dg/template/ttp3.C: Adjust expected error message.
+       * g++.old-deja/g++.law/visibility13.C: Likewise.
+       * g++.old-deja/g++.niklas/t135.C: Likewise.
+       * g++.old-deja/g++.pt/ttp41.C: Likewise.
+       * g++.old-deja/g++.pt/ttp43.C: Use qualified name for template
+       template argument.
+       * g++.old-deja/g++.pt/ttp44.C: Likewise.
+
 2003-08-01  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/11295
diff --git a/gcc/testsuite/g++.dg/template/elab1.C b/gcc/testsuite/g++.dg/template/elab1.C
new file mode 100644 (file)
index 0000000..778150f
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright (C) 2003 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+// Elaborate type specifier of class template
+
+template <class T> class A {
+  class B;
+};
+
+template <class T> class A<T>::B {
+  friend class A;
+};
index 05bd44a172eaf8f4e942787c587d707b36b62e77..cc3128cfc95b32aa7d80cc8b8d1d40ea4eda2dc6 100644 (file)
@@ -14,13 +14,13 @@ class OUTER {
   template <class T>
   class List { };
   
-  vector<class List> data; // { dg-error "type/value mismatch|expected a type|ISO C" "" }
+  vector<class List> data; // { dg-error "invalid|required|ISO C" "" }
 };
 
 template <class T>
-class List { };                        // { dg-bogus "previous declaration" "" { xfail *-*-* } }
+class List { };
 
 // This next line should just do a lookup of 'class List', and then
 // get a type/value mismatch. Instead we try and push 'class List'
 // into the global namespace and get a redeclaration error.
-vector<class List > data;      // { dg-bogus "`struct List' redeclared|type/value mismatch" "" { xfail *-*-* } }
+vector<class List > data;      // { dg-error "invalid|required|expected" "" }
diff --git a/gcc/testsuite/g++.dg/template/type2.C b/gcc/testsuite/g++.dg/template/type2.C
new file mode 100644 (file)
index 0000000..509c482
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-do compile }
+// Origin: Juan Carlos Arevalo-Baeza <jcab@JCABs-Rumblings.com>
+
+// PR c++/8442
+// Type template parameter incorrectly treated as template template
+// parameter.
+
+template <typename T> struct A {};
+
+template <typename T> struct B
+{
+  template <typename U> struct C {};
+  template <typename U> A<C<U> > foo(U);
+};
+
+B<void> b;
index 4ea561bf02dcfdcbf7c33744ea43b0bd62dc4f90..025b0b1ef54035a8a814a0dc27fc6c95fe44fa46 100644 (file)
@@ -65,7 +65,7 @@ void Array<Type>::init(const Type *array, int sz)
 //     ---------------   Array_RC.h  &&  Array_RC.cc   ----------------
 
 template <class Type>
-class Array_RC : public Array<Type> {// { dg-error "" } previous declaration.*
+class Array_RC : public Array<Type> {
 public:
     Array_RC(const Type *ar, int sz);
     Type& operator[](int ix);
index 5e826f13248e88e7907cfaeca953e06ec0d91843..566b0ca1ba3cf1d851d996ad9af2f75cf141112f 100644 (file)
@@ -1,7 +1,7 @@
-// { dg-do assemble }
+// { dg-do compile }
 // GROUPS niklas pt friend
 template <class T> class C1
-{ // { dg-error "" }
+{
 public:
        void diddle_C2 ();
 };
index 18a3322721f2f1f9c24fab965c0ad6080bcb679b..b260961e813949d9a2f0af448186b5b9e2279837 100644 (file)
@@ -1,4 +1,4 @@
-// { dg-do run  }
+// { dg-do compile }
 template<template<class> class D,class E> class C
 {
        public:
@@ -13,8 +13,8 @@ template<class T> class D
 
 template<class T> int D<T>::f()
 {
-       C<D,D> c;
-       return c.g();
+       C<D,D> c;       // { dg-error "" }
+       return c.g();   // { dg-error "" }
 }
 
 int main()
index d18a4ebe6f7cda1e72f46a0391ba53627442197e..e1bc4cee6521224a6166e1a67c3b02c624cc5093 100644 (file)
@@ -20,11 +20,11 @@ struct Lit {
 
 template < class T >
 struct Id {
-  Add < T, Id, Lit > operator+(const T& t) const {
-    return Add < T, Id, Lit >(*this, Lit<T>(t));
+  Add < T, ::Id, Lit > operator+(const T& t) const {
+    return Add < T, ::Id, Lit >(*this, Lit<T>(t));
   }
 
-  Mul < T, Id, Lit > operator*(const T& t) const {
-    return Mul < T, Id, Lit >(*this, Lit<T>(t));
+  Mul < T, ::Id, Lit > operator*(const T& t) const {
+    return Mul < T, ::Id, Lit >(*this, Lit<T>(t));
   }
 };
index f977fcb415d1dd86f53ea4a760119ffb94bc5be3..08eb3077f024b96cf2142d3bfbda8a0f7e8490b3 100644 (file)
@@ -9,8 +9,8 @@ public:
 template < class T >
 struct Id {
   template < template < class > class E >
-  Add < T, Id, E > operator+(const E<T>& e) const {
-    return Add < T, Id, E >(*this, e);
+  Add < T, ::Id, E > operator+(const E<T>& e) const {
+    return Add < T, ::Id, E >(*this, e);
   }
 };