diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-11-29 20:10:18 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-11-29 20:10:18 +0000 |
commit | fc6a28d7633ddd7c734b759f4d60233b70bf1770 (patch) | |
tree | 3136f9512ba6b63b67d1999c006891472812416e /gcc/cp/pt.c | |
parent | b7034e060b24bd94c51cb563db1cd18c30eb1fd6 (diff) | |
download | gcc-fc6a28d7633ddd7c734b759f4d60233b70bf1770.zip gcc-fc6a28d7633ddd7c734b759f4d60233b70bf1770.tar.gz gcc-fc6a28d7633ddd7c734b759f4d60233b70bf1770.tar.bz2 |
re PR c++/18368 (C++ error message regression)
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.
From-SVN: r91483
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 76 |
1 files changed, 50 insertions, 26 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fca3f3d..34e86c8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -140,7 +140,6 @@ static tree most_specialized (tree, tree, tree); static tree most_specialized_class (tree, tree); static int template_class_depth_real (tree, int); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); -static tree tsubst_decl (tree, tree, tree, tsubst_flags_t); static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); static void check_specialization_scope (void); @@ -3833,6 +3832,7 @@ convert_template_argument (tree parm, arg = make_typename_type (TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1), + typename_type, complain & tf_error); is_type = 1; } @@ -6140,13 +6140,12 @@ tsubst_default_arguments (tree fn) TREE_PURPOSE (arg)); } -/* Substitute the ARGS into the T, which is a _DECL. TYPE is the - (already computed) substitution of ARGS into TREE_TYPE (T), if - appropriate. Return the result of the substitution. Issue error - and warning messages under control of COMPLAIN. */ +/* Substitute the ARGS into the T, which is a _DECL. Return the + result of the substitution. Issue error and warning messages under + control of COMPLAIN. */ static tree -tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) +tsubst_decl (tree t, tree args, tsubst_flags_t complain) { location_t saved_loc; tree r = NULL_TREE; @@ -6267,6 +6266,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) tree argvec = NULL_TREE; tree *friends; tree gen_tmpl; + tree type; int member; int args_depth; int parms_depth; @@ -6376,7 +6376,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) member = 0; ctx = DECL_CONTEXT (t); } - type = tsubst (type, args, complain, in_decl); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); if (type == error_mark_node) return error_mark_node; @@ -6485,10 +6485,13 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) case PARM_DECL: { + tree type; + r = copy_node (t); if (DECL_TEMPLATE_PARM_P (t)) SET_DECL_TEMPLATE_PARM_P (r); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); @@ -6513,7 +6516,12 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) case FIELD_DECL: { + tree type; + r = copy_decl (t); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node) + return error_mark_node; TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); @@ -6541,19 +6549,6 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) break; case TYPE_DECL: - if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM - || t == TYPE_MAIN_DECL (TREE_TYPE (t))) - { - /* If this is the canonical decl, we don't have to mess with - instantiations, and often we can't (for typename, template - type parms and such). Note that TYPE_NAME is not correct for - the above test if we've copied the type for a typedef. */ - r = TYPE_NAME (type); - break; - } - - /* Fall through. */ - case VAR_DECL: { tree argvec = NULL_TREE; @@ -6561,8 +6556,25 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) tree spec; tree tmpl = NULL_TREE; tree ctx; + tree type = NULL_TREE; int local_p; + if (TREE_CODE (t) == TYPE_DECL) + { + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM + || t == TYPE_MAIN_DECL (TREE_TYPE (t))) + { + /* If this is the canonical decl, we don't have to + mess with instantiations, and often we can't (for + typename, template type parms and such). Note that + TYPE_NAME is not correct for the above test if + we've copied the type for a typedef. */ + r = TYPE_NAME (type); + break; + } + } + /* Assume this is a non-local variable. */ local_p = 0; @@ -6600,6 +6612,9 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) r = copy_decl (t); if (TREE_CODE (r) == VAR_DECL) { + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node) + return error_mark_node; type = complete_type (type); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t); @@ -6885,6 +6900,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) || TREE_CODE (t) == NAMESPACE_DECL) return t; + if (DECL_P (t)) + return tsubst_decl (t, args, complain); + if (TREE_CODE (t) == IDENTIFIER_NODE) type = IDENTIFIER_TYPE_VALUE (t); else @@ -6892,9 +6910,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) gcc_assert (type != unknown_type_node); - if (type && TREE_CODE (t) != FUNCTION_DECL + if (type && TREE_CODE (t) != TYPENAME_TYPE - && TREE_CODE (t) != TEMPLATE_DECL && TREE_CODE (t) != IDENTIFIER_NODE && TREE_CODE (t) != FUNCTION_TYPE && TREE_CODE (t) != METHOD_TYPE) @@ -6902,9 +6919,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (type == error_mark_node) return error_mark_node; - if (DECL_P (t)) - return tsubst_decl (t, args, type, complain); - switch (TREE_CODE (t)) { case RECORD_TYPE: @@ -7364,7 +7378,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } } - f = make_typename_type (ctx, f, + f = make_typename_type (ctx, f, typename_type, (complain & tf_error) | tf_keep_type_decl); if (f == error_mark_node) return f; @@ -7374,6 +7388,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) f = TREE_TYPE (f); } + if (TREE_CODE (f) != TYPENAME_TYPE) + { + if (TYPENAME_IS_ENUM_P (t) && TREE_CODE (f) != ENUMERAL_TYPE) + error ("%qT resolves to %qT, which is not an enumeration type", + t, f); + else if (TYPENAME_IS_CLASS_P (t) && !CLASS_TYPE_P (f)) + error ("%qT resolves to %qT, which is is not a class type", + t, f); + } + return cp_build_qualified_type_real (f, cp_type_quals (f) | cp_type_quals (t), complain); } |