summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1998-08-02 21:37:23 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1998-08-02 21:37:23 +0000
commit3addf1000fde0804b465bb83f799c299d386185d (patch)
treed2a17ab43d62c027bfce4d7a370eff0f9fdc5a22
parent858e062bc5b8066a11e6c60610369678b5ab4ecc (diff)
downloadgcc-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/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.def7
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/lex.c29
-rw-r--r--gcc/cp/method.c12
-rw-r--r--gcc/cp/pt.c42
-rw-r--r--gcc/cp/tree.c7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/conv2.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/spec19.C5
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