aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>1997-12-03 14:46:56 -0500
committerJason Merrill <jason@gcc.gnu.org>1997-12-03 14:46:56 -0500
commitaa36c0813a2f8c213bb5b041ce67e7032b078c5a (patch)
treecbef61e4c68e290653ba52cca7d8b28493864ced
parent868e82ab1fa87c6801acb82b0fb4e079e4e25356 (diff)
downloadgcc-aa36c0813a2f8c213bb5b041ce67e7032b078c5a.zip
gcc-aa36c0813a2f8c213bb5b041ce67e7032b078c5a.tar.gz
gcc-aa36c0813a2f8c213bb5b041ce67e7032b078c5a.tar.bz2
tree.c (is_overloaded_fn): Handle getting a fn template.
* tree.c (is_overloaded_fn): Handle getting a fn template. (really_overloaded_fn): Likewise. * error.c (dump_decl): Handle TEMPLATE_ID_EXPRs better. * pt.c (check_explicit_specialization): Tweak. (determine_explicit_specialization): Tweak. * tree.c, cp-tree.h (get_target_expr): New fn. 1997-12-02 Mark Mitchell <mmitchell@usa.net> * pt.c (determine_explicit_specialization): Avoid an internal error for bad specializations. * method.c (build_overload_value): Handle SCOPE_REF. From-SVN: r16928
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/error.c5
-rw-r--r--gcc/cp/method.c8
-rw-r--r--gcc/cp/pt.c29
-rw-r--r--gcc/cp/tree.c32
6 files changed, 71 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a91d9e3..7def192 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+Wed Dec 3 11:44:52 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (is_overloaded_fn): Handle getting a fn template.
+ (really_overloaded_fn): Likewise.
+ * error.c (dump_decl): Handle TEMPLATE_ID_EXPRs better.
+ * pt.c (check_explicit_specialization): Tweak.
+ (determine_explicit_specialization): Tweak.
+
+ * tree.c, cp-tree.h (get_target_expr): New fn.
+
+1997-12-02 Mark Mitchell <mmitchell@usa.net>
+
+ * pt.c (determine_explicit_specialization): Avoid an internal
+ error for bad specializations.
+
+ * method.c (build_overload_value): Handle SCOPE_REF.
+
Tue Dec 2 19:18:50 1997 Mike Stump <mrs@wrs.com>
* class.c (prepare_fresh_vtable): Enable even more complex MI
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9b69b7b..e165302 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2425,6 +2425,7 @@ extern tree min_tree_cons PROTO((tree, tree, tree));
extern int lvalue_p PROTO((tree));
extern int lvalue_or_else PROTO((tree, char *));
extern tree build_cplus_new PROTO((tree, tree));
+extern tree get_target_expr PROTO((tree));
extern tree break_out_cleanups PROTO((tree));
extern tree break_out_calls PROTO((tree));
extern tree build_cplus_method_type PROTO((tree, tree, tree));
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ccc5b46..2064741 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -779,7 +779,10 @@ dump_decl (t, v)
case TEMPLATE_ID_EXPR:
{
tree args;
- dump_type (TREE_OPERAND (t, 0), v);
+ tree name = TREE_OPERAND (t, 0);
+ if (is_overloaded_fn (name))
+ name = DECL_NAME (get_first_fn (name));
+ dump_decl (name, v);
OB_PUTC ('<');
for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
{
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index c16f6ea..0ab0e23 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -641,6 +641,14 @@ build_overload_value (type, value, in_template)
build_overload_identifier (DECL_ASSEMBLER_NAME (value));
return;
}
+ else if (TREE_CODE (value) == SCOPE_REF)
+ {
+ OB_PUTC2 ('Q', '1');
+ numeric_output_need_bar = 0;
+ build_overload_name (TREE_OPERAND (value, 0), 0, 0);
+ build_overload_identifier (TREE_OPERAND (value, 1));
+ return;
+ }
else
my_friendly_abort (71);
break; /* not really needed */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1e9c905..58ecc3c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -352,27 +352,27 @@ determine_explicit_specialization (template_id, type, targs_out,
int overloaded;
tree fns;
tree matching_fns = NULL_TREE;
- tree name = NULL_TREE;
tree result;
tree fn;
- my_friendly_assert (TREE_CODE (template_id) == TEMPLATE_ID_EXPR,
- 0);
+ my_friendly_assert (TREE_CODE (template_id) == TEMPLATE_ID_EXPR
+ && TREE_OPERAND (template_id, 0), 0);
fns = TREE_OPERAND (template_id, 0);
- overloaded = fns != NULL_TREE && really_overloaded_fn (fns);
+ if (is_overloaded_fn (fns))
+ fn = get_first_fn (fns);
+ else
+ fn = NULL_TREE;
+
+ overloaded = really_overloaded_fn (fns);
- for (fn = (fns != NULL_TREE) ? get_first_fn (fns) : NULL_TREE;
- fn != NULL_TREE;
+ for (; fn != NULL_TREE;
fn = overloaded ? DECL_CHAIN (fn) : NULL_TREE)
{
int dummy = 0;
tree targs;
- if (name == NULL_TREE)
- name = DECL_NAME (fn);
-
if (TREE_CODE (fn) != TEMPLATE_DECL
|| (need_member_template && !is_member_template (fn)))
continue;
@@ -424,8 +424,9 @@ determine_explicit_specialization (template_id, type, targs_out,
if (matching_fns == NULL_TREE)
{
if (complain)
- cp_error ("Specialization of `%s' does not match any template declaration.",
- IDENTIFIER_POINTER (name));
+ cp_error ("`%D' does not match any template declaration.",
+ template_id);
+
*targs_out = NULL_TREE;
return NULL_TREE;
}
@@ -496,8 +497,8 @@ check_explicit_specialization (declarator, decl, template_count, flags)
&& !processing_explicit_specialization (template_count)
&& !is_friend)
{
- if (!have_def && ! template_header_count)
- /* This is not an explicit specialization. It must be
+ if (! have_def && ! template_header_count && ! ctype)
+ /* This is not an explict specialization. It must be
an explicit instantiation. */
return 2;
else if (template_header_count > template_count
@@ -507,7 +508,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
declarator);
return 0;
}
- else if (pedantic)
+ else if (pedantic || uses_template_parms (decl))
pedwarn ("explicit specialization not preceeded by `template <>'");
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 98b1a6d..2d048ab 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -248,6 +248,7 @@ build_cplus_new (type, init)
return init;
slot = build (VAR_DECL, type);
+ DECL_ARTIFICIAL (slot) = 1;
layout_decl (slot, 0);
rval = build (NEW_EXPR, type,
TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot);
@@ -258,6 +259,25 @@ build_cplus_new (type, init)
return rval;
}
+/* Encapsulate the expression INIT in a TARGET_EXPR. */
+
+tree
+get_target_expr (init)
+ tree init;
+{
+ tree slot;
+ tree rval;
+
+ slot = build (VAR_DECL, TREE_TYPE (init));
+ DECL_ARTIFICIAL (slot) = 1;
+ layout_decl (slot, 0);
+ rval = build (TARGET_EXPR, TREE_TYPE (init), slot, init,
+ NULL_TREE, NULL_TREE);
+ TREE_SIDE_EFFECTS (rval) = 1;
+
+ return rval;
+}
+
/* Recursively search EXP for CALL_EXPRs that need cleanups and replace
these CALL_EXPRs with tree nodes that will perform the cleanups. */
@@ -1273,15 +1293,14 @@ int
is_overloaded_fn (x)
tree x;
{
- if (TREE_CODE (x) == FUNCTION_DECL)
- return 1;
-
- if (TREE_CODE (x) == TEMPLATE_ID_EXPR)
+ if (TREE_CODE (x) == FUNCTION_DECL
+ || TREE_CODE (x) == TEMPLATE_ID_EXPR
+ || DECL_FUNCTION_TEMPLATE_P (x))
return 1;
if (TREE_CODE (x) == TREE_LIST
&& (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
- || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
+ || DECL_FUNCTION_TEMPLATE_P (TREE_VALUE (x))))
return 1;
return 0;
@@ -1291,7 +1310,8 @@ int
really_overloaded_fn (x)
tree x;
{
- if (TREE_CODE (x) == TEMPLATE_ID_EXPR)
+ if (TREE_CODE (x) == TEMPLATE_ID_EXPR
+ || DECL_FUNCTION_TEMPLATE_P (x))
return 1;
if (TREE_CODE (x) == TREE_LIST