aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-11-29 20:10:18 +0000
committerMark Mitchell <mark@codesourcery.com>2004-11-29 20:10:18 +0000
commitf27524a30166e91b32daaef67f6f8a0a26add891 (patch)
tree3136f9512ba6b63b67d1999c006891472812416e /gcc/cp/decl.c
parentc7ef4bd8bc136cd40e80dbba0ef3a61fb511353c (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.c107
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