diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-11-29 20:10:18 +0000 |
---|---|---|
committer | Mark Mitchell <mark@codesourcery.com> | 2004-11-29 20:10:18 +0000 |
commit | f27524a30166e91b32daaef67f6f8a0a26add891 (patch) | |
tree | 3136f9512ba6b63b67d1999c006891472812416e /gcc/cp/decl.c | |
parent | c7ef4bd8bc136cd40e80dbba0ef3a61fb511353c (diff) |
PR c++/18368
* parser.c (cp_parser_check_for_definition_in_return_type): Take
the defined type as a parameter, and inform the user about the
possibility of a missing semicolon.
(cp_parser_explicit_instantiation): Adjust call to
cp_parser_check_for_definition_in_return_type.
(cp_parser_init_declarator): Likewise.
(cp_parser_member_declaration): Likewise.
PR c++/18674
* cp-tree.def (TYPENAME_TYPE): Remove discussion of implicit
typename from comments.
* cp-tree.h (TYPENAME_IS_ENUM_P): New macro.
(TYPENAME_IS_CLASS_P): Likewise.
(make_typename_type): Change prototype.
* decl.c (struct_typename_info): New type.
(typename_compare): Expect the second argument to be a
typename_info, not a tree.
(build_typename_type): Add tag_type parameter. Do not create a
new type until necessary.
(make_typename_type): Add tag_type parameter.
* error.c (TYPENAME_TYPE): Print tags other than "typename" if
appropriate.
* friend.c (make_friend_class): Adjust call to make_typename_type.
* parser.c (cp_parser_make_typename_type): Likewise.
(cp_parser_primary_expression): Adjust call to
cp_parser_lookup_name.
(cp_parser_unqualified_id): Adjust calls to cp_parser_class_name.
(cp_parser_class_or_namespace_name): Likewise.
(cp_parser_postfix_expression): Adjust calls to
make_typename_type.
(cp_parser_mem_initializer_id): Adjust calls to
cp_parser_class_name.
(cp_parser_type_parameter): Adjust calls to cp_parser_lookup_name.
(cp_parser_template_name): Likewise.
(cp_parser_template_argument): Likewise.
(cp_parser_type_name): Adjust call to cp_parser_class_name.
(cp_parser_elaborated_type_specifier): Adjust calls to
make_typename_type and cp_parser_lookup_name.
(cp_parser_namespace_name): Likewise.
(cp_parser_class_name): Replace type_p parameter with tag_type.
Adjust calls to make_typename_type and cp_parser_lookup_name.
(cp_parser_class_head): Adjust calls to cp_parser_class_name.
(cp_parser_base_specifier): Likewise.
(cp_parser_lookup_name): Replace is_type parameter with tag_type.
Adjust calls to make_typename_type and lookup_qualified_name.
(cp_parser_lookup_name_simple): Adjust call to
cp_parser_lookup_name.
(cp_parser_constructor_declarator_p): Adjust call to
cp_parser_class_name.
* pt.c (convert_template_argument): Adjust all to
make_typename_type.
(tsubst_decl): Do not pre-substitute the type of the declaration.
(tsubst): Hand off declarations more quickly. Adjust call to
make_typename_type.
PR c++/18512
* parser.c (cp_parser_postfix_dot_deref_expression): Robustify.
PR c++/18674
* g++.old-deja/g++.brendan/crash16.C: Adjust error messages.
* g++.old-deja/g++.law/ctors5.C: Likewise.
* g++.old-deja/g++.other/crash25.C: Likewise.
PR c++/18674
* g++.dg/template/error16.C: New test.
PR c++/18512
* g++.dg/template/crash29.C: New test.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@91483 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 107 |
1 files changed, 62 insertions, 45 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 7779080d0f8..92f294f0884 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -121,7 +121,6 @@ static void initialize_local_var (tree, tree); static void expand_static_init (tree, tree); static tree next_initializable_field (tree); static tree reshape_init (tree, tree *); -static tree build_typename_type (tree, tree, tree); /* Erroneous argument lists can use this *IFF* they do not modify it. */ tree error_mark_list; @@ -2538,83 +2537,101 @@ typename_hash (const void* k) return hash; } +typedef struct typename_info { + tree scope; + tree name; + tree template_id; + bool enum_p; + bool class_p; +} typename_info; + /* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */ static int typename_compare (const void * k1, const void * k2) { tree t1; - tree t2; - tree d1; - tree d2; + const typename_info *t2; t1 = (tree) k1; - t2 = (tree) k2; - d1 = TYPE_NAME (t1); - d2 = TYPE_NAME (t2); + t2 = (const typename_info *) k2; - return (DECL_NAME (d1) == DECL_NAME (d2) - && TYPE_CONTEXT (t1) == TYPE_CONTEXT (t2) - && ((TREE_TYPE (t1) != NULL_TREE) - == (TREE_TYPE (t2) != NULL_TREE)) - && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) - && TYPENAME_TYPE_FULLNAME (t1) == TYPENAME_TYPE_FULLNAME (t2)); + return (DECL_NAME (TYPE_NAME (t1)) == t2->name + && TYPE_CONTEXT (t1) == t2->scope + && TYPENAME_TYPE_FULLNAME (t1) == t2->template_id + && TYPENAME_IS_ENUM_P (t1) == t2->enum_p + && TYPENAME_IS_CLASS_P (t1) == t2->class_p); } /* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is - the type of `T', NAME is the IDENTIFIER_NODE for `t'. If BASE_TYPE - is non-NULL, this type is being created by the implicit typename - extension, and BASE_TYPE is a type named `t' in some base class of - `T' which depends on template parameters. - + the type of `T', NAME is the IDENTIFIER_NODE for `t'. + Returns the new TYPENAME_TYPE. */ static GTY ((param_is (union tree_node))) htab_t typename_htab; static tree -build_typename_type (tree context, tree name, tree fullname) +build_typename_type (tree context, tree name, tree fullname, + enum tag_types tag_type) { tree t; tree d; + typename_info ti; void **e; + hashval_t hash; if (typename_htab == NULL) - { - typename_htab = htab_create_ggc (61, &typename_hash, - &typename_compare, NULL); - } - - /* Build the TYPENAME_TYPE. */ - t = make_aggr_type (TYPENAME_TYPE); - TYPE_CONTEXT (t) = FROB_CONTEXT (context); - TYPENAME_TYPE_FULLNAME (t) = fullname; - - /* Build the corresponding TYPE_DECL. */ - d = build_decl (TYPE_DECL, name, t); - TYPE_NAME (TREE_TYPE (d)) = d; - TYPE_STUB_DECL (TREE_TYPE (d)) = d; - DECL_CONTEXT (d) = FROB_CONTEXT (context); - DECL_ARTIFICIAL (d) = 1; + typename_htab = htab_create_ggc (61, &typename_hash, + &typename_compare, NULL); + + ti.scope = FROB_CONTEXT (context); + ti.name = name; + ti.template_id = fullname; + ti.enum_p = tag_type == enum_type; + ti.class_p = (tag_type == class_type + || tag_type == record_type + || tag_type == union_type); + hash = (htab_hash_pointer (ti.scope) + ^ htab_hash_pointer (ti.name)); /* See if we already have this type. */ - e = htab_find_slot (typename_htab, t, INSERT); + e = htab_find_slot_with_hash (typename_htab, &ti, hash, INSERT); if (*e) t = (tree) *e; else - *e = t; + { + /* Build the TYPENAME_TYPE. */ + t = make_aggr_type (TYPENAME_TYPE); + TYPE_CONTEXT (t) = ti.scope; + TYPENAME_TYPE_FULLNAME (t) = ti.template_id; + TYPENAME_IS_ENUM_P (t) = ti.enum_p; + TYPENAME_IS_CLASS_P (t) = ti.class_p; + + /* Build the corresponding TYPE_DECL. */ + d = build_decl (TYPE_DECL, name, t); + TYPE_NAME (TREE_TYPE (d)) = d; + TYPE_STUB_DECL (TREE_TYPE (d)) = d; + DECL_CONTEXT (d) = FROB_CONTEXT (context); + DECL_ARTIFICIAL (d) = 1; + /* Store it in the hash table. */ + *e = t; + } + return t; } -/* Resolve `typename CONTEXT::NAME'. Returns an appropriate type, - unless an error occurs, in which case error_mark_node is returned. - If we locate a non-artificial TYPE_DECL and TF_KEEP_TYPE_DECL is - set, we return that, rather than the _TYPE it corresponds to, in - other cases we look through the type decl. If TF_ERROR is set, - complain about errors, otherwise be quiet. */ +/* Resolve `typename CONTEXT::NAME'. TAG_TYPE indicates the tag + provided to name the type. Returns an appropriate type, unless an + error occurs, in which case error_mark_node is returned. If we + locate a non-artificial TYPE_DECL and TF_KEEP_TYPE_DECL is set, we + return that, rather than the _TYPE it corresponds to, in other + cases we look through the type decl. If TF_ERROR is set, complain + about errors, otherwise be quiet. */ tree -make_typename_type (tree context, tree name, tsubst_flags_t complain) +make_typename_type (tree context, tree name, enum tag_types tag_type, + tsubst_flags_t complain) { tree fullname; @@ -2728,7 +2745,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain) return error_mark_node; } - return build_typename_type (context, name, fullname); + return build_typename_type (context, name, fullname, tag_type); } /* Resolve `CONTEXT::template NAME'. Returns a TEMPLATE_DECL if the name |