diff options
-rw-r--r-- | gcc/cp/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/parser.c | 33 | ||||
-rw-r--r-- | gcc/cp/pt.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/defarg1.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/local2.C | 61 |
6 files changed, 113 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7b3df0050c9..0da8e47208a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2003-01-05 Mark Mitchell <mark@codesourcery.com> + + * parser.c (cp_parser_template_parameter): Adjust call to + cp_parser_parameter_declaration. + (cp_parser_parameter_declaration_list): Likewise. + (cp_parser_parameter_declaration): Replace + greater_than_is_operator_p with template_parm_p parameter. Do not + cache tokens for template default arguments. + + * pt.c (retrieve_local_specialization): Use htab_find, not + htab_find_with_hash. + (register_local_specialization): Use htab_find_slot, not + htab_find_slot_with_hash. + (instantiate_decl): Pass a hash function to htab_create. + 2003-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * parser.c (cp_parser_binary_expression, diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8715deb5c58..02bcd4d0a09 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7911,8 +7911,7 @@ cp_parser_template_parameter (parser) of the template parameter-list rather than a greater-than operator. */ return - cp_parser_parameter_declaration (parser, - /*greater_than_is_operator_p=*/false); + cp_parser_parameter_declaration (parser, /*template_parm_p=*/true); } /* Parse a type-parameter. @@ -10792,8 +10791,8 @@ cp_parser_parameter_declaration_list (parser) tree parameter; /* Parse the parameter. */ parameter - = cp_parser_parameter_declaration (parser, - /*greater_than_is_operator_p=*/true); + = cp_parser_parameter_declaration (parser, /*template_parm_p=*/false); + /* If a parse error ocurred parsing the parameter declaration, then the entire parameter-declaration-list is erroneous. */ if (parameter == error_mark_node) @@ -10842,9 +10841,10 @@ cp_parser_parameter_declaration_list (parser) decl-specifier-seq abstract-declarator [opt] decl-specifier-seq abstract-declarator [opt] = assignment-expression - If GREATER_THAN_IS_OPERATOR_P is FALSE, then a non-nested `>' token - encountered during the parsing of the assignment-expression is not - interpreted as a greater-than operator. + If TEMPLATE_PARM_P is TRUE, then this parameter-declaration + declares a template parameter. (In that case, a non-nested `>' + token encountered during the parsing of the assignment-expression + is not interpreted as a greater-than operator.) Returns a TREE_LIST representing the parameter-declaration. The TREE_VALUE is a representation of the decl-specifier-seq and @@ -10853,11 +10853,11 @@ cp_parser_parameter_declaration_list (parser) TREE_VALUE represents the declarator. */ static tree -cp_parser_parameter_declaration (parser, greater_than_is_operator_p) - cp_parser *parser; - bool greater_than_is_operator_p; +cp_parser_parameter_declaration (cp_parser *parser, + bool template_parm_p) { bool declares_class_or_enum; + bool greater_than_is_operator_p; tree decl_specifiers; tree attributes; tree declarator; @@ -10866,6 +10866,16 @@ cp_parser_parameter_declaration (parser, greater_than_is_operator_p) cp_token *token; const char *saved_message; + /* In a template parameter, `>' is not an operator. + + [temp.param] + + When parsing a default template-argument for a non-type + template-parameter, the first non-nested `>' is taken as the end + of the template parameter-list rather than a greater-than + operator. */ + greater_than_is_operator_p = !template_parm_p; + /* Type definitions may not appear in parameter types. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message @@ -10930,7 +10940,8 @@ cp_parser_parameter_declaration (parser, greater_than_is_operator_p) /* If we are defining a class, then the tokens that make up the default argument must be saved and processed later. */ - if (at_class_scope_p () && TYPE_BEING_DEFINED (current_class_type)) + if (!template_parm_p && at_class_scope_p () + && TYPE_BEING_DEFINED (current_class_type)) { unsigned depth = 0; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index aedc90d2ec6..05e98266db2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -745,9 +745,7 @@ static tree retrieve_local_specialization (tmpl) tree tmpl; { - tree spec = - (tree) htab_find_with_hash (local_specializations, tmpl, - htab_hash_pointer (tmpl)); + tree spec = (tree) htab_find (local_specializations, tmpl); return spec ? TREE_PURPOSE (spec) : NULL_TREE; } @@ -934,8 +932,7 @@ register_local_specialization (spec, tmpl) { void **slot; - slot = htab_find_slot_with_hash (local_specializations, tmpl, - htab_hash_pointer (tmpl), INSERT); + slot = htab_find_slot (local_specializations, tmpl, INSERT); *slot = build_tree_list (spec, tmpl); } @@ -10311,7 +10308,7 @@ instantiate_decl (d, defer_ok) /* Set up the list of local specializations. */ local_specializations = htab_create (37, - NULL, + htab_hash_pointer, eq_local_specializations, NULL); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 57b4e7310ea..b81e6aa1854 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-01-05 Mark Mitchell <mark@codesourcery.com> + + * g++.dg/template/defarg-1.C: New test. + * g++.dg/template/local2.C: Likewise. + 2003-01-05 Richard Sandiford <rsandifo@redhat.com> * gcc.c-torture/execute/20030105-1.c: New test. diff --git a/gcc/testsuite/g++.dg/template/defarg1.C b/gcc/testsuite/g++.dg/template/defarg1.C new file mode 100644 index 00000000000..1b0e4a24a15 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg1.C @@ -0,0 +1,7 @@ +struct Outer { + template <int I, int J=I> struct Inner {}; +}; + +void f() { + Outer::Inner<2> i; +} diff --git a/gcc/testsuite/g++.dg/template/local2.C b/gcc/testsuite/g++.dg/template/local2.C new file mode 100644 index 00000000000..51c946a5a49 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/local2.C @@ -0,0 +1,61 @@ +template<typename T> +struct X { + double & f (const unsigned int i, + const unsigned int j); + void g (X &M); +}; + +template <typename T> +void X<T>::g (X &x) { + double t14 = x.f(0,0)*x.f(1,1); + double t15 = x.f(2,2)*x.f(3,3); + double t17 = x.f(2,3)*x.f(3,2); + double t19 = x.f(0,0)*x.f(2,1); + double t20 = x.f(1,2)*x.f(3,3); + double t22 = x.f(1,3)*x.f(3,2); + double t24 = x.f(0,0)*x.f(3,1); + double t25 = x.f(1,2)*x.f(2,3); + double t27 = x.f(1,3)*x.f(2,2); + double t29 = x.f(1,0)*x.f(0,1); + double t32 = x.f(1,0)*x.f(2,1); + double t33 = x.f(0,2)*x.f(3,3); + double t35 = x.f(0,3)*x.f(3,2); + double t37 = x.f(1,0)*x.f(3,1); + double t38 = x.f(0,2)*x.f(2,3); + double t40 = x.f(0,3)*x.f(2,2); + double t42 = t14*t15-t14*t17-t19*t20+t19*t22+ + t24*t25-t24*t27-t29*t15+t29*t17+ + t32*t33-t32*t35-t37*t38+t37*t40; + double t43 = x.f(2,0)*x.f(0,1); + double t46 = x.f(2,0)*x.f(1,1); + double t49 = x.f(2,0)*x.f(3,1); + double t50 = x.f(0,2)*x.f(1,3); + double t52 = x.f(0,3)*x.f(1,2); + double t54 = x.f(3,0)*x.f(0,1); + double t57 = x.f(3,0)*x.f(1,1); + double t60 = x.f(3,0)*x.f(2,1); + double t63 = t43*t20-t43*t22-t46*t33+t46*t35+ + t49*t50-t49*t52-t54*t25+t54*t27+ + t57*t38-t57*t40-t60*t50+t60*t52; + double t65 = 1/(t42+t63); + double t71 = x.f(0,2)*x.f(2,1); + double t73 = x.f(0,3)*x.f(2,1); + double t75 = x.f(0,2)*x.f(3,1); + double t77 = x.f(0,3)*x.f(3,1); + double t81 = x.f(0,1)*x.f(1,2); + double t83 = x.f(0,1)*x.f(1,3); + double t85 = x.f(0,2)*x.f(1,1); + double t87 = x.f(0,3)*x.f(1,1); + double t101 = x.f(1,0)*x.f(2,2); + double t103 = x.f(1,0)*x.f(2,3); + double t105 = x.f(2,0)*x.f(1,2); + double t107 = x.f(2,0)*x.f(1,3); + double t109 = x.f(3,0)*x.f(1,2); + double t111 = x.f(3,0)*x.f(1,3); + double t115 = x.f(0,0)*x.f(2,2); + double t117 = x.f(0,0)*x.f(2,3); + double t119 = x.f(2,0)*x.f(0,2); + double t121 = x.f(2,0)*x.f(0,3); +} + +template void X<double>::g (X<double>&); |