cp-tree.def (LOOKUP_EXPR): Document.

* 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.

From-SVN: r21544
This commit is contained in:
Mark Mitchell 1998-08-02 21:37:23 +00:00 committed by Mark Mitchell
parent 151ab2f29e
commit 672476cbdf
9 changed files with 104 additions and 34 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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); }

View File

@ -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 */
}

View File

@ -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;

View File

@ -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;

View File

@ -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++)

View File

@ -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>;

View File

@ -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