diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-08-02 21:37:23 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-08-02 21:37:23 +0000 |
commit | 3addf1000fde0804b465bb83f799c299d386185d (patch) | |
tree | d2a17ab43d62c027bfce4d7a370eff0f9fdc5a22 | |
parent | 858e062bc5b8066a11e6c60610369678b5ab4ecc (diff) | |
download | gcc-3addf1000fde0804b465bb83f799c299d386185d.tar.gz |
* cp-tree.def (LOOKUP_EXPR): Document. Remove second argument.
* cp-tree.h (DECL_TI_TEMPLATE): Improve documentation.
* lex.c (do_identifier): Don't use a second argument, or a type,
when building LOOKUP_EXPRs.
(do_identifier): Likewise.
(do_scoped_id): Likewise.
* method.c (hack_identifier): Improve error message.
* pt.c (lookup_template_function): Don't needlessly call
copy_to_permanent or build_min.
(tsubst_copy): Remove #if 0'd code. Tsubst into LOOKUP_EXPRs if
necessary.
(do_decl_instantiation): Improve error message.
* tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy.
(build_min): Copy the type to the permanent obstack, too.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@21544 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 7 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/lex.c | 29 | ||||
-rw-r--r-- | gcc/cp/method.c | 12 | ||||
-rw-r--r-- | gcc/cp/pt.c | 42 | ||||
-rw-r--r-- | gcc/cp/tree.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/conv2.C | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/spec19.C | 5 |
9 files changed, 104 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4b806660af1..b7f83bc7abc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +1998-08-02 Mark Mitchell <mark@markmitchell.com> + + * cp-tree.def (LOOKUP_EXPR): Document. Remove second argument. + * cp-tree.h (DECL_TI_TEMPLATE): Improve documentation. + * lex.c (do_identifier): Don't use a second argument, or a type, + when building LOOKUP_EXPRs. + (do_identifier): Likewise. + (do_scoped_id): Likewise. + * method.c (hack_identifier): Improve error message. + * pt.c (lookup_template_function): Don't needlessly call + copy_to_permanent or build_min. + (tsubst_copy): Remove #if 0'd code. Tsubst into LOOKUP_EXPRs if + necessary. + (do_decl_instantiation): Improve error message. + * tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy. + (build_min): Copy the type to the permanent obstack, too. + 1998-08-01 Jason Merrill <jason@yorick.cygnus.com> * init.c (init_init_processing): Remove BI* handling. diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index dbbdb6603d0..b610737cc23 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -182,9 +182,14 @@ DEFTREECODE (WRAPPER, "wrapper", 'x', 1) /* A node to remember a source position. */ DEFTREECODE (SRCLOC, "srcloc", 'x', 2) +/* Used to represent deferred name lookup for dependent names while + parsing a template declaration. The first argument is an + IDENTIFIER_NODE for the name in question. The TREE_TYPE is + unused. */ +DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 1) + /* A whole bunch of tree codes for the initial, superficial parsing of templates. */ -DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2) DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3) DEFTREECODE (CAST_EXPR, "cast_expr", '1', 1) DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", '1', 1) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4e1d1bd4a3c..72a1655f5fe 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1265,8 +1265,8 @@ struct lang_decl As a special case, for a member friend template of a template class, this value will not be a TEMPLATE_DECL, but rather a - LOOKUP_EXPR indicating the name of the template and any explicit - template arguments provided. For example, in: + LOOKUP_EXPR or IDENTIFIER_NODE indicating the name of the template + and any explicit template arguments provided. For example, in: template <class T> struct S { friend void f<int>(int, double); } diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index d127ddceed2..a9166d1fd44 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -2891,7 +2891,7 @@ do_identifier (token, parsing, args) } if (current_template_parms) - return build_min_nt (LOOKUP_EXPR, token, NULL_TREE); + return build_min_nt (LOOKUP_EXPR, token); else if (IDENTIFIER_OPNAME_P (token)) { if (token != ansi_opname[ERROR_MARK]) @@ -2988,21 +2988,12 @@ do_identifier (token, parsing, args) else id = hack_identifier (id, token); - if (current_template_parms) - { - if (is_overloaded_fn (id)) - { - tree t = build_min (LOOKUP_EXPR, unknown_type_node, - token, get_first_fn (id)); - if (id != IDENTIFIER_NAMESPACE_VALUE (token)) - TREE_OPERAND (t, 1) = error_mark_node; - id = t; - } - else if (! TREE_PERMANENT (id) || TREE_CODE (id) == PARM_DECL - || TREE_CODE (id) == USING_DECL) - id = build_min (LOOKUP_EXPR, TREE_TYPE (id), token, error_mark_node); - /* else just use the decl */ - } + if (current_template_parms + && (is_overloaded_fn (id) + || !TREE_PERMANENT (id) + || TREE_CODE (id) == PARM_DECL + || TREE_CODE (id) == USING_DECL)) + id = build_min_nt (LOOKUP_EXPR, token); return id; } @@ -3031,7 +3022,7 @@ do_scoped_id (token, parsing) { if (processing_template_decl) { - id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE); + id = build_min_nt (LOOKUP_EXPR, token); LOOKUP_EXPR_GLOBAL (id) = 1; return id; } @@ -3068,9 +3059,9 @@ do_scoped_id (token, parsing) { if (is_overloaded_fn (id)) { - id = build_min (LOOKUP_EXPR, unknown_type_node, - token, get_first_fn (id)); + id = build_min_nt (LOOKUP_EXPR, token); LOOKUP_EXPR_GLOBAL (id) = 1; + return id; } /* else just use the decl */ } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index a4c19822897..18e638cda75 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1845,8 +1845,16 @@ hack_identifier (value, name) { if (current_class_ptr == NULL_TREE) { - error ("request for member `%s' in static member function", - IDENTIFIER_POINTER (DECL_NAME (value))); + if (current_function_decl + && DECL_STATIC_FUNCTION_P (current_function_decl)) + cp_error ("invalid use of member `%D' in static member function", + value); + else + /* We can get here when processing a bad default + argument, like: + struct S { int a; void f(int i = a); } */ + cp_error ("invalid use of member `%D'", value); + return error_mark_node; } TREE_USED (current_class_ptr) = 1; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9e13916b418..3906eb38d99 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2999,14 +2999,14 @@ lookup_template_function (fns, arglist) return error_mark_node; } - if (arglist != NULL_TREE && !TREE_PERMANENT (arglist)) - copy_to_permanent (arglist); - type = TREE_TYPE (fns); if (TREE_CODE (fns) == OVERLOAD || !type) type = unknown_type_node; - return build_min (TEMPLATE_ID_EXPR, type, fns, arglist); + if (processing_template_decl) + return build_min (TEMPLATE_ID_EXPR, type, fns, arglist); + else + return build (TEMPLATE_ID_EXPR, type, fns, arglist); } /* Within the scope of a template class S<T>, the name S gets bound @@ -5469,11 +5469,25 @@ tsubst_copy (t, args, in_decl) else return t; -#if 0 - case IDENTIFIER_NODE: - return do_identifier (t, 0); -#endif - + case LOOKUP_EXPR: + { + /* We must tsbust into a LOOKUP_EXPR in case the names to + which it refers is a conversion operator; in that case the + name will change. We avoid making unnecessary copies, + however. */ + + tree id = tsubst_copy (TREE_OPERAND (t, 0), args, in_decl); + + if (id != TREE_OPERAND (t, 0)) + { + tree r = build_nt (LOOKUP_EXPR, id); + LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t); + t = r; + } + + return t; + } + case CAST_EXPR: case REINTERPRET_CAST_EXPR: case CONST_CAST_EXPR: @@ -7236,6 +7250,16 @@ do_decl_instantiation (declspecs, declarator, storage) cp_error ("explicit instantiation of `%#D'", decl); return; } + else if (DECL_TEMPLATE_SPECIALIZATION (decl)) + /* [temp.spec] + + No program shall both explicit instantiation and explicit + specialize a template. */ + { + cp_error ("explicit instantiation of `%#D' after", decl); + cp_error_at ("explicit specialization here", decl); + return; + } else if (DECL_TEMPLATE_INSTANTIATION (decl)) result = decl; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index dce01cb6724..8b782bbb85c 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1784,6 +1784,11 @@ mapcar (t, func) TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func); return t; + case LOOKUP_EXPR: + t = copy_node (t); + TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); + return t; + case RECORD_TYPE: if (TYPE_PTRMEMFUNC_P (t)) return build_ptrmemfunc_type @@ -2022,7 +2027,7 @@ build_min VPROTO((enum tree_code code, tree tt, ...)) t = make_node (code); length = tree_code_length[(int) code]; - TREE_TYPE (t) = tt; + TREE_TYPE (t) = copy_to_permanent (tt); TREE_COMPLEXITY (t) = lineno; for (i = 0; i < length; i++) diff --git a/gcc/testsuite/g++.old-deja/g++.pt/conv2.C b/gcc/testsuite/g++.old-deja/g++.pt/conv2.C new file mode 100644 index 00000000000..f3e0b359e19 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/conv2.C @@ -0,0 +1,15 @@ +// Build don't link: + +template<class T> +class A { +public: + operator const T*() const; + const T* cast() const; +}; + +template<class T> +const T* A<T>::cast() const { + return operator const T*(); +} + +template class A<char>; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec19.C b/gcc/testsuite/g++.old-deja/g++.pt/spec19.C new file mode 100644 index 00000000000..f9b601125b4 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/spec19.C @@ -0,0 +1,5 @@ +// Build don't link: + +template<class T> T f(T o) { return o; } +template<> int f(int o) { return o; } // ERROR - after specialization +template int f(int); // ERROR - explicit instantiation |