Commit cbd63935 by Kriang Lerdsuwanakij Committed by Kriang Lerdsuwanakij

PR c++/8442, c++/8806

	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
parent ee3071ef
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> 2003-08-01 Nathan Sidwell <nathan@codesourcery.com>
* parser.c (cp_parser_init_declarator, * parser.c (cp_parser_init_declarator,
......
...@@ -76,6 +76,19 @@ removed. ...@@ -76,6 +76,19 @@ removed.
* Covariant returns are implemented for all but varadic functions that * Covariant returns are implemented for all but varadic functions that
require an adjustment. 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: *** Changes in GCC 3.3:
* The "new X = 3" extension has been removed; you must now use "new X(3)". * The "new X = 3" extension has been removed; you must now use "new X(3)".
......
...@@ -6333,21 +6333,6 @@ get_enclosing_class (tree type) ...@@ -6333,21 +6333,6 @@ get_enclosing_class (tree type)
return NULL_TREE; 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 /* Note that NAME was looked up while the current class was being
defined and that the result of that lookup was DECL. */ defined and that the result of that lookup was DECL. */
......
...@@ -3603,7 +3603,6 @@ extern int same_signature_p (tree, tree); ...@@ -3603,7 +3603,6 @@ extern int same_signature_p (tree, tree);
extern void warn_hidden (tree); extern void warn_hidden (tree);
extern void maybe_add_class_template_decl_list (tree, tree, int); extern void maybe_add_class_template_decl_list (tree, tree, int);
extern tree get_enclosing_class (tree); extern tree get_enclosing_class (tree);
int is_base_of_enclosing_class (tree, tree);
extern void unreverse_member_declarations (tree); extern void unreverse_member_declarations (tree);
extern void invalidate_class_lookup_cache (void); extern void invalidate_class_lookup_cache (void);
extern void maybe_note_name_used_in_class (tree, tree); extern void maybe_note_name_used_in_class (tree, tree);
...@@ -3731,7 +3730,7 @@ extern tree get_scope_of_declarator (tree); ...@@ -3731,7 +3730,7 @@ extern tree get_scope_of_declarator (tree);
extern void grok_special_member_properties (tree); extern void grok_special_member_properties (tree);
extern int grok_ctor_properties (tree, tree); extern int grok_ctor_properties (tree, tree);
extern void grok_op_properties (tree, int); 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 tree xref_tag_from_type (tree, tree, int);
extern void xref_basetypes (tree, tree); extern void xref_basetypes (tree, tree);
extern tree start_enum (tree); extern tree start_enum (tree);
......
...@@ -4278,7 +4278,7 @@ handle_class_head (enum tag_types tag_kind, tree scope, tree id, ...@@ -4278,7 +4278,7 @@ handle_class_head (enum tag_types tag_kind, tree scope, tree id,
if (!decl) if (!decl)
{ {
decl = xref_tag (tag_kind, id, attributes, false); decl = xref_tag (tag_kind, id, attributes, false, false);
if (decl == error_mark_node) if (decl == error_mark_node)
return error_mark_node; return error_mark_node;
decl = TYPE_MAIN_DECL (decl); decl = TYPE_MAIN_DECL (decl);
......
...@@ -8553,7 +8553,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -8553,7 +8553,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
(is_friend (is_friend
|| !is_declaration || !is_declaration
|| cp_lexer_next_token_is_not (parser->lexer, || cp_lexer_next_token_is_not (parser->lexer,
CPP_SEMICOLON))); CPP_SEMICOLON)),
parser->num_template_parameter_lists);
} }
} }
if (tag_type != enum_type) if (tag_type != enum_type)
...@@ -11380,7 +11381,8 @@ cp_parser_class_head (cp_parser* parser, ...@@ -11380,7 +11381,8 @@ cp_parser_class_head (cp_parser* parser,
/* If the class was unnamed, create a dummy name. */ /* If the class was unnamed, create a dummy name. */
if (!id) if (!id)
id = make_anon_name (); 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 else
{ {
......
...@@ -3431,33 +3431,15 @@ convert_template_argument (tree parm, ...@@ -3431,33 +3431,15 @@ convert_template_argument (tree parm,
requires_type = (TREE_CODE (parm) == TYPE_DECL requires_type = (TREE_CODE (parm) == TYPE_DECL
|| requires_tmpl_type); || requires_tmpl_type);
if (TREE_CODE (arg) != RECORD_TYPE) is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
|| 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;
if (is_tmpl_type if (is_tmpl_type
&& (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)) || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
arg = TYPE_STUB_DECL (arg); 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; is_type = TYPE_P (arg) || is_tmpl_type;
......
...@@ -120,7 +120,7 @@ init_rtti_processing (void) ...@@ -120,7 +120,7 @@ init_rtti_processing (void)
push_namespace (std_identifier); push_namespace (std_identifier);
type_info_type_node type_info_type_node
= xref_tag (class_type, get_identifier ("type_info"), = xref_tag (class_type, get_identifier ("type_info"),
/*attributes=*/NULL_TREE, 1); /*attributes=*/NULL_TREE, true, false);
pop_namespace (); pop_namespace ();
const_type_info_type = build_qualified_type (type_info_type_node, const_type_info_type = build_qualified_type (type_info_type_node,
TYPE_QUAL_CONST); TYPE_QUAL_CONST);
...@@ -639,7 +639,7 @@ build_dynamic_cast_1 (tree type, tree expr) ...@@ -639,7 +639,7 @@ build_dynamic_cast_1 (tree type, tree expr)
tinfo_ptr = xref_tag (class_type, tinfo_ptr = xref_tag (class_type,
get_identifier ("__class_type_info"), get_identifier ("__class_type_info"),
/*attributes=*/NULL_TREE, /*attributes=*/NULL_TREE,
1); true, false);
tinfo_ptr = build_pointer_type tinfo_ptr = build_pointer_type
(build_qualified_type (build_qualified_type
...@@ -774,7 +774,7 @@ tinfo_base_init (tree desc, tree target) ...@@ -774,7 +774,7 @@ tinfo_base_init (tree desc, tree target)
push_nested_namespace (abi_node); push_nested_namespace (abi_node);
real_type = xref_tag (class_type, TINFO_REAL_NAME (desc), real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
/*attributes=*/NULL_TREE, 1); /*attributes=*/NULL_TREE, true, false);
pop_nested_namespace (abi_node); pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (real_type)) if (!COMPLETE_TYPE_P (real_type))
...@@ -1371,7 +1371,7 @@ emit_support_tinfos (void) ...@@ -1371,7 +1371,7 @@ emit_support_tinfos (void)
bltn_type = xref_tag (class_type, bltn_type = xref_tag (class_type,
get_identifier ("__fundamental_type_info"), get_identifier ("__fundamental_type_info"),
/*attributes=*/NULL_TREE, /*attributes=*/NULL_TREE,
1); true, false);
pop_nested_namespace (abi_node); pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (bltn_type)) if (!COMPLETE_TYPE_P (bltn_type))
return; return;
......
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> 2003-08-01 Nathan Sidwell <nathan@codesourcery.com>
PR c++/11295 PR c++/11295
......
// 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;
};
...@@ -14,13 +14,13 @@ class OUTER { ...@@ -14,13 +14,13 @@ class OUTER {
template <class T> template <class T>
class List { }; 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> 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 // 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' // get a type/value mismatch. Instead we try and push 'class List'
// into the global namespace and get a redeclaration error. // 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" "" }
// { 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;
...@@ -65,7 +65,7 @@ void Array<Type>::init(const Type *array, int sz) ...@@ -65,7 +65,7 @@ void Array<Type>::init(const Type *array, int sz)
// --------------- Array_RC.h && Array_RC.cc ---------------- // --------------- Array_RC.h && Array_RC.cc ----------------
template <class Type> template <class Type>
class Array_RC : public Array<Type> {// { dg-error "" } previous declaration.* class Array_RC : public Array<Type> {
public: public:
Array_RC(const Type *ar, int sz); Array_RC(const Type *ar, int sz);
Type& operator[](int ix); Type& operator[](int ix);
......
// { dg-do assemble } // { dg-do compile }
// GROUPS niklas pt friend // GROUPS niklas pt friend
template <class T> class C1 template <class T> class C1
{ // { dg-error "" } {
public: public:
void diddle_C2 (); void diddle_C2 ();
}; };
......
// { dg-do run } // { dg-do compile }
template<template<class> class D,class E> class C template<template<class> class D,class E> class C
{ {
public: public:
...@@ -13,8 +13,8 @@ template<class T> class D ...@@ -13,8 +13,8 @@ template<class T> class D
template<class T> int D<T>::f() template<class T> int D<T>::f()
{ {
C<D,D> c; C<D,D> c; // { dg-error "" }
return c.g(); return c.g(); // { dg-error "" }
} }
int main() int main()
......
...@@ -20,11 +20,11 @@ struct Lit { ...@@ -20,11 +20,11 @@ struct Lit {
template < class T > template < class T >
struct Id { struct Id {
Add < T, Id, Lit > operator+(const T& t) const { Add < T, ::Id, Lit > operator+(const T& t) const {
return Add < T, Id, Lit >(*this, Lit<T>(t)); return Add < T, ::Id, Lit >(*this, Lit<T>(t));
} }
Mul < T, Id, Lit > operator*(const T& t) const { Mul < T, ::Id, Lit > operator*(const T& t) const {
return Mul < T, Id, Lit >(*this, Lit<T>(t)); return Mul < T, ::Id, Lit >(*this, Lit<T>(t));
} }
}; };
...@@ -9,8 +9,8 @@ public: ...@@ -9,8 +9,8 @@ public:
template < class T > template < class T >
struct Id { struct Id {
template < template < class > class E > template < template < class > class E >
Add < T, Id, E > operator+(const E<T>& e) const { Add < T, ::Id, E > operator+(const E<T>& e) const {
return Add < T, Id, E >(*this, e); return Add < T, ::Id, E >(*this, e);
} }
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment