aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c336
1 files changed, 253 insertions, 83 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index b4fced4a127..dd2bb436698 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -36,10 +36,25 @@ Boston, MA 02111-1307, USA. */
#include "decl.h"
#include "lex.h"
#include "output.h"
+#include "except.h"
+#include "expr.h"
-extern tree get_file_function_name ();
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static tree get_sentry PROTO((tree));
+static void mark_vtable_entries PROTO((tree));
+static void import_export_template PROTO((tree));
static void grok_function_init PROTO((tree, tree));
-void import_export_decl ();
+static int finish_vtable_vardecl PROTO((tree, tree));
+static int prune_vtable_vardecl PROTO((tree, tree));
+static void finish_sigtable_vardecl PROTO((tree, tree));
+
extern int current_class_depth;
/* A list of virtual function tables we must make sure to write out. */
@@ -158,11 +173,10 @@ int warn_ctor_dtor_privacy = 1;
/* True if we want to implement vtables using "thunks".
The default is off. */
-#if defined(NEW_OVER) && defined (__i386__)
-int flag_vtable_thunks = 1;
-#else
-int flag_vtable_thunks;
+#ifndef DEFAULT_VTABLE_THUNKS
+#define DEFAULT_VTABLE_THUNKS 0
#endif
+int flag_vtable_thunks = DEFAULT_VTABLE_THUNKS;
/* True if we want to deal with repository information. */
@@ -246,10 +260,18 @@ int warn_pmf2ptr = 1;
/* Nonzero means warn about violation of some Effective C++ style rules. */
-int warn_ecpp = 0;
+int warn_ecpp;
-/* Nonzero means `$' can be in an identifier.
- See cccp.c for reasons why this breaks some obscure ANSI C programs. */
+/* Nonzero means warn where overload resolution chooses a promotion from
+ unsigned to signed over a conversion to an unsigned of the same size. */
+
+int warn_sign_promo;
+
+/* Nonzero means warn when an old-style cast is used. */
+
+int warn_old_style_cast;
+
+/* Nonzero means `$' can be in an identifier. */
#ifndef DOLLARS_IN_IDENTIFIERS
#define DOLLARS_IN_IDENTIFIERS 1
@@ -301,7 +323,9 @@ int flag_memoize_lookups; int flag_save_memoized_contexts;
int write_virtuals;
-/* Nonzero means we should attempt to elide constructors when possible. */
+/* Nonzero means we should attempt to elide constructors when possible.
+ FIXME: This flag is obsolete, and should be torn out along with the
+ old overloading code. */
int flag_elide_constructors;
@@ -384,6 +408,14 @@ int flag_weak = 1;
int max_tinst_depth = 17;
+/* The name-mangling scheme to use. Must be 1 or greater to support
+ template functions with identical types, but different template
+ arguments. */
+int name_mangling_version = 1;
+
+/* Nonzero means that guiding declarations are allowed. */
+int flag_guiding_decls;
+
/* Table of language-dependent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
@@ -409,6 +441,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"all-virtual", &flag_all_virtual, 1},
{"memoize-lookups", &flag_memoize_lookups, 1},
{"elide-constructors", &flag_elide_constructors, 1},
+ {"handle-exceptions", &flag_exceptions, 1},
{"handle-signatures", &flag_handle_signatures, 1},
{"default-inline", &flag_default_inline, 1},
{"dollars-in-identifiers", &dollars_in_ident, 1},
@@ -442,7 +475,7 @@ lang_decode_option (p)
char *p;
{
if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
- dollars_in_ident = 1, flag_writable_strings = 1,
+ flag_writable_strings = 1,
flag_this_is_variable = 1, flag_new_for_scope = 0;
/* The +e options are for cfront compatibility. They come in as
`-+eN', to kludge around gcc.c's argument handling. */
@@ -470,13 +503,17 @@ lang_decode_option (p)
p += 2;
/* Try special -f options. */
+ if (!strcmp (p, "handle-exceptions")
+ || !strcmp (p, "no-handle-exceptions"))
+ warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)");
+
if (!strcmp (p, "save-memoized"))
{
flag_memoize_lookups = 1;
flag_save_memoized_contexts = 1;
found = 1;
}
- if (!strcmp (p, "no-save-memoized"))
+ else if (!strcmp (p, "no-save-memoized"))
{
flag_memoize_lookups = 0;
flag_save_memoized_contexts = 0;
@@ -499,6 +536,17 @@ lang_decode_option (p)
flag_implicit_templates = 0;
found = 1;
}
+ else if (!strcmp (p, "guiding-decls"))
+ {
+ flag_guiding_decls = 1;
+ name_mangling_version = 0;
+ found = 1;
+ }
+ else if (!strcmp (p, "no-guiding-decls"))
+ {
+ flag_guiding_decls = 0;
+ found = 1;
+ }
else if (!strncmp (p, "template-depth-", 15))
{
char *endp = p + 15;
@@ -515,6 +563,22 @@ lang_decode_option (p)
max_tinst_depth = atoi (p + 15);
template_depth_lose: ;
}
+ else if (!strncmp (p, "name-mangling-version-", 22))
+ {
+ char *endp = p + 22;
+ while (*endp)
+ {
+ if (*endp >= '0' && *endp <= '9')
+ endp++;
+ else
+ {
+ error ("Invalid option `%s'", p - 2);
+ goto mangling_version_lose;
+ }
+ }
+ name_mangling_version = atoi (p + 22);
+ mangling_version_lose: ;
+ }
else for (j = 0;
!found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]);
j++)
@@ -585,6 +649,10 @@ lang_decode_option (p)
warn_pmf2ptr = setting;
else if (!strcmp (p, "effc++"))
warn_ecpp = setting;
+ else if (!strcmp (p, "sign-promo"))
+ warn_sign_promo = setting;
+ else if (!strcmp (p, "old-style-cast"))
+ warn_old_style_cast = setting;
else if (!strcmp (p, "comment"))
; /* cpp handles this one. */
else if (!strcmp (p, "comments"))
@@ -613,6 +681,7 @@ lang_decode_option (p)
warn_uninitialized = (setting ? 2 : 0);
warn_template_debugging = setting;
warn_reorder = setting;
+ warn_sign_promo = setting;
}
else if (!strcmp (p, "overloaded-virtual"))
@@ -620,7 +689,7 @@ lang_decode_option (p)
else return 0;
}
else if (!strcmp (p, "-ansi"))
- dollars_in_ident = 0, flag_no_nonansi_builtin = 1, flag_ansi = 1,
+ flag_no_nonansi_builtin = 1, flag_ansi = 1,
flag_no_gnu_keywords = 1, flag_operator_names = 1;
#ifdef SPEW_DEBUG
/* Undocumented, only ever used when you're invoking cc1plus by hand, since
@@ -1173,7 +1242,10 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
return t;
}
- t = stabilize_reference (convert_from_reference (exp));
+ t = exp;
+ if (TREE_CODE (t) == OFFSET_REF)
+ t = resolve_offset_ref (t);
+ t = stabilize_reference (convert_from_reference (t));
type = TREE_TYPE (t);
code = TREE_CODE (type);
@@ -1201,15 +1273,14 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
if (code == POINTER_TYPE)
{
#if 0
- /* As of Valley Forge, you can delete a pointer to constant. */
- /* You can't delete a pointer to constant. */
+ /* As of Valley Forge, you can delete a pointer to const. */
if (TREE_READONLY (TREE_TYPE (type)))
{
error ("`const *' cannot be deleted");
return error_mark_node;
}
#endif
- /* You also can't delete functions. */
+ /* You can't delete functions. */
if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
{
error ("cannot delete a function");
@@ -1241,8 +1312,8 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
{
/* Only do access checking here; we'll be calling op delete
from the destructor. */
- tree tmp = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, t,
- size_zero_node, NULL_TREE);
+ tree tmp = build_op_delete_call (DELETE_EXPR, t,
+ size_zero_node, LOOKUP_NORMAL);
if (tmp == error_mark_node)
return error_mark_node;
}
@@ -1252,6 +1323,59 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
}
}
+/* Report an error if the indicated template declaration is not the
+ sort of thing that should be a member template. */
+
+void
+check_member_template (tmpl)
+ tree tmpl;
+{
+ tree decl;
+
+ my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
+ decl = DECL_TEMPLATE_RESULT (tmpl);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (current_function_decl)
+ /* 14.5.2.2 [temp.mem]
+
+ A local class shall not have member templates. */
+ cp_error ("declaration of of member template `%#D' in local class",
+ decl);
+
+ if (DECL_VIRTUAL_P (decl))
+ {
+ /* 14.5.2.3 [temp.mem]
+
+ A member function template shall not be virtual. */
+ cp_error
+ ("invalid use of `virtual' in template declaration of `%#D'",
+ decl);
+ DECL_VIRTUAL_P (decl) = 0;
+ }
+
+ /* The debug-information generating code doesn't know what to do
+ with member templates. */
+ DECL_IGNORED_P (tmpl) = 1;
+ }
+ else if (TREE_CODE (decl) == TYPE_DECL &&
+ AGGREGATE_TYPE_P (TREE_TYPE (decl)))
+ {
+ if (current_function_decl)
+ /* 14.5.2.2 [temp.mem]
+
+ A local class shall not have member templates. */
+ cp_error ("declaration of of member template `%#D' in local class",
+ decl);
+
+ /* We don't handle member template classes yet. */
+ sorry ("member templates classes");
+ }
+ else
+ cp_error ("template declaration of `%#D'", decl);
+}
+
/* Sanity check: report error if this function FUNCTION is not
really a member of the class (CTYPE) it is supposed to belong to.
CNAME is the same here as it is for grokclassfn above. */
@@ -1265,6 +1389,7 @@ check_classfn (ctype, function)
tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));
tree *methods = 0;
tree *end = 0;
+ tree templates = NULL_TREE;
if (method_vec != 0)
{
@@ -1281,6 +1406,7 @@ check_classfn (ctype, function)
while (++methods != end)
{
+ fndecl = *methods;
if (fn_name == DECL_NAME (*methods))
{
got_it:
@@ -1310,16 +1436,46 @@ check_classfn (ctype, function)
if (comptypes (TREE_TYPE (TREE_TYPE (function)),
TREE_TYPE (TREE_TYPE (fndecl)), 1)
- && compparms (p1, p2, 3))
+ && compparms (p1, p2, 3)
+ && (DECL_TEMPLATE_SPECIALIZATION (function)
+ == DECL_TEMPLATE_SPECIALIZATION (fndecl))
+ && (!DECL_TEMPLATE_SPECIALIZATION (function)
+ || (DECL_TI_TEMPLATE (function)
+ == DECL_TI_TEMPLATE (fndecl))))
return fndecl;
+
+ if (is_member_template (fndecl))
+ /* This function might be an instantiation
+ or specialization of fndecl. */
+ templates =
+ scratch_tree_cons (NULL_TREE, fndecl, templates);
}
#endif
fndecl = DECL_CHAIN (fndecl);
}
break; /* loser */
}
- }
- }
+ else if (TREE_CODE (fndecl) == TEMPLATE_DECL
+ && IDENTIFIER_TYPENAME_P (DECL_NAME (fndecl))
+ && IDENTIFIER_TYPENAME_P (fn_name))
+ /* The method in the class is a member template
+ conversion operator. We are declaring another
+ conversion operator. It is possible that even though
+ the names don't match, there is some specialization
+ occurring. */
+ templates =
+ scratch_tree_cons (NULL_TREE, fndecl, templates);
+ }
+ }
+
+ if (templates)
+ /* This function might be an instantiation or a specialization.
+ We should verify that this is possible. If it is, we must
+ somehow add the new declaration to the method vector for the
+ class. Perhaps we should use add_method? For now, we simply
+ return NULL_TREE, which lets the caller know that this
+ function is new, but we don't print an error message. */
+ return NULL_TREE;
if (methods != end)
{
@@ -2063,7 +2219,7 @@ finish_anon_union (anon_union_decl)
DECL_INITIAL (decl) = NULL_TREE;
/* If there's a cleanup to do, it belongs in the
TREE_PURPOSE of the following TREE_LIST. */
- elems = tree_cons (NULL_TREE, decl, elems);
+ elems = scratch_tree_cons (NULL_TREE, decl, elems);
TREE_TYPE (elems) = type;
}
if (static_p)
@@ -2249,6 +2405,7 @@ coerce_delete_type (type)
|| TREE_VALUE (arg_types) != ptr_type_node)
e2 = 1, error ("`operator delete' takes type `void *' as first parameter");
+#if 0
if (arg_types
&& TREE_CHAIN (arg_types)
&& TREE_CHAIN (arg_types) != void_list_node)
@@ -2280,8 +2437,12 @@ coerce_delete_type (type)
arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types));
}
else e3 |= e1;
+#endif
- if (e3)
+ if (e2)
+ arg_types = tree_cons (NULL_TREE, ptr_type_node,
+ arg_types ? TREE_CHAIN (arg_types): NULL_TREE);
+ if (e2 || e1)
type = build_function_type (void_type_node, arg_types);
return type;
@@ -2312,7 +2473,11 @@ mark_vtable_entries (decl)
tree fn = TREE_OPERAND (fnaddr, 0);
TREE_ADDRESSABLE (fn) = 1;
if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn))
- TREE_OPERAND (fnaddr, 0) = fn = abort_fndecl;
+ {
+ TREE_OPERAND (fnaddr, 0) = fn = copy_node (fn);
+ DECL_RTL (fn) = DECL_RTL (abort_fndecl);
+ mark_used (abort_fndecl);
+ }
if (TREE_CODE (fn) == THUNK_DECL && DECL_EXTERNAL (fn))
{
DECL_EXTERNAL (fn) = 0;
@@ -2370,6 +2535,7 @@ import_export_vtable (decl, type, final)
int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type);
+#ifndef MULTIPLE_SYMBOL_SPACES
if (! found && ! final)
{
tree method;
@@ -2383,6 +2549,7 @@ import_export_vtable (decl, type, final)
break;
}
}
+#endif
if (final || ! found)
{
@@ -2431,8 +2598,9 @@ finish_prevtable_vardecl (prev, vars)
&& !DECL_ABSTRACT_VIRTUAL_P (method))
{
SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
- CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
- CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
+ CLASSTYPE_VTABLE_NEEDS_WRITING (ctype)
+ = ! DECL_REALLY_EXTERN (method);
+ CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_REALLY_EXTERN (method);
break;
}
}
@@ -2508,8 +2676,8 @@ prune_vtable_vardecl (prev, vars)
int
walk_vtables (typedecl_fn, vardecl_fn)
- register void (*typedecl_fn)();
- register int (*vardecl_fn)();
+ register void (*typedecl_fn) PROTO ((tree, tree));
+ register int (*vardecl_fn) PROTO ((tree, tree));
{
tree prev, vars;
int flag = 0;
@@ -2556,8 +2724,8 @@ finish_sigtable_vardecl (prev, vars)
void
walk_sigtables (typedecl_fn, vardecl_fn)
- register void (*typedecl_fn)();
- register void (*vardecl_fn)();
+ register void (*typedecl_fn) PROTO((tree, tree));
+ register void (*vardecl_fn) PROTO((tree, tree));
{
tree prev, vars;
@@ -2600,26 +2768,8 @@ import_export_decl (decl)
{
if (TREE_CODE (decl) == FUNCTION_DECL)
comdat_linkage (decl);
- /* Dynamically initialized vars go into common. */
- else if (DECL_INITIAL (decl) == NULL_TREE
- || DECL_INITIAL (decl) == error_mark_node)
- DECL_COMMON (decl) = 1;
- else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
- {
- DECL_COMMON (decl) = 1;
- DECL_INITIAL (decl) = error_mark_node;
- }
else
- {
- /* Statically initialized vars are weak or comdat, if
- supported. */
- if (flag_weak)
- make_decl_one_only (decl);
- else
- /* we can't do anything useful; leave vars for explicit
- instantiation. */
- DECL_NOT_REALLY_EXTERN (decl) = 0;
- }
+ DECL_COMDAT (decl) = 1;
}
else
DECL_NOT_REALLY_EXTERN (decl) = 0;
@@ -2627,7 +2777,8 @@ import_export_decl (decl)
else if (DECL_FUNCTION_MEMBER_P (decl))
{
tree ctype = DECL_CLASS_CONTEXT (decl);
- if (CLASSTYPE_INTERFACE_KNOWN (ctype) && ! DECL_ARTIFICIAL (decl))
+ if (CLASSTYPE_INTERFACE_KNOWN (ctype)
+ && (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl)))
{
DECL_NOT_REALLY_EXTERN (decl)
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
@@ -2652,8 +2803,6 @@ import_export_decl (decl)
else
comdat_linkage (decl);
}
- else if (DECL_C_STATIC (decl))
- TREE_PUBLIC (decl) = 0;
else
comdat_linkage (decl);
@@ -2685,7 +2834,6 @@ extern tree pending_templates;
extern tree maybe_templates;
extern struct obstack permanent_obstack;
-extern tree get_id_2 ();
static tree
get_sentry (base)
@@ -2726,9 +2874,6 @@ finish_file ()
at_eof = 1;
- if (flag_detailed_statistics)
- dump_tree_statistics ();
-
/* Bad parse errors. Just forget about it. */
if (! global_bindings_p () || current_class_type)
return;
@@ -2759,7 +2904,7 @@ finish_file ()
for (fnname = maybe_templates; fnname; fnname = TREE_CHAIN (fnname))
{
- tree *args, fn, decl = TREE_VALUE (fnname);
+ tree args, fn, decl = TREE_VALUE (fnname);
if (DECL_INITIAL (decl))
continue;
@@ -2767,7 +2912,6 @@ finish_file ()
fn = TREE_PURPOSE (fnname);
args = get_bindings (fn, decl);
fn = instantiate_template (fn, args);
- free (args);
instantiate_decl (fn);
}
@@ -2802,7 +2946,8 @@ finish_file ()
/* Walk to mark the inline functions we need, then output them so
that we can pick up any other tdecls that those routines need. */
- walk_vtables ((void (*)())0, finish_prevtable_vardecl);
+ walk_vtables ((void (*) PROTO ((tree, tree))) 0,
+ finish_prevtable_vardecl);
for (vars = pending_statics; vars; vars = TREE_CHAIN (vars))
{
@@ -2821,7 +2966,7 @@ finish_file ()
rest_of_decl_compilation (TREE_VALUE (vars), 0, 1, 1);
vars = static_aggregates;
- if (static_ctors || vars || exception_table_p ())
+ if (static_ctors || vars || register_exception_table_p ())
needs_messing_up = 1;
if (static_dtors)
needs_cleaning = 1;
@@ -2920,7 +3065,7 @@ finish_file ()
push_momentary ();
expand_start_bindings (0);
- if (exception_table_p ())
+ if (register_exception_table_p ())
register_exception_table ();
while (vars)
@@ -2973,7 +3118,7 @@ finish_file ()
expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0),
TREE_VEC_ELT (init, 1),
TREE_VEC_ELT (init, 2), 0),
- const0_rtx, VOIDmode, 0);
+ const0_rtx, VOIDmode, EXPAND_NORMAL);
}
else
expand_assignment (decl, init, 0, 0);
@@ -3044,7 +3189,8 @@ finish_file ()
start_time = get_run_time ();
if (flag_handle_signatures)
- walk_sigtables ((void (*)())0, finish_sigtable_vardecl);
+ walk_sigtables ((void (*) PROTO ((tree, tree))) 0,
+ finish_sigtable_vardecl);
for (fnname = saved_inlines; fnname; fnname = TREE_CHAIN (fnname))
{
@@ -3070,7 +3216,8 @@ finish_file ()
SET_DECL_ARTIFICIAL (vars);
pushdecl (vars);
- reconsider |= walk_vtables ((void (*)())0, finish_vtable_vardecl);
+ reconsider |= walk_vtables ((void (*) PROTO((tree, tree))) 0,
+ finish_vtable_vardecl);
while (*p)
{
@@ -3106,11 +3253,10 @@ finish_file ()
DECL_EXTERNAL (decl) = 0;
reconsider = 1;
/* We can't inline this function after it's been
- emitted, so just disable inlining. We want a
- variant of output_inline_function that doesn't
- prevent subsequent integration... */
- flag_no_inline = 1;
- temporary_allocation ();
+ emitted. We want a variant of
+ output_inline_function that doesn't prevent
+ subsequent integration... */
+ DECL_INLINE (decl) = 0;
output_inline_function (decl);
permanent_allocation (1);
}
@@ -3126,15 +3272,8 @@ finish_file ()
/* Now delete from the chain of variables all virtual function tables.
We output them all ourselves, because each will be treated specially. */
- walk_vtables ((void (*)())0, prune_vtable_vardecl);
-
- for (vars = getdecls (); vars; vars = TREE_CHAIN (vars))
- {
- if (TREE_CODE (vars) == FUNCTION_DECL
- && ! DECL_INTERFACE_KNOWN (vars)
- && DECL_C_STATIC (vars))
- TREE_PUBLIC (vars) = 0;
- }
+ walk_vtables ((void (*) PROTO((tree, tree))) 0,
+ prune_vtable_vardecl);
if (write_virtuals == 2)
{
@@ -3156,7 +3295,10 @@ finish_file ()
varconst_time += this_time - start_time;
if (flag_detailed_statistics)
- dump_time_statistics ();
+ {
+ dump_tree_statistics ();
+ dump_time_statistics ();
+ }
}
/* This is something of the form 'A()()()()()+1' that has turned out to be an
@@ -3229,6 +3371,9 @@ reparse_absdcl_as_casts (decl, expr)
expr = build_c_cast (type, expr);
}
+ if (warn_old_style_cast)
+ warning ("use of old-style cast");
+
return expr;
}
@@ -3252,6 +3397,11 @@ build_expr_from_tree (t)
else
return do_identifier (TREE_OPERAND (t, 0), 0);
+ case TEMPLATE_ID_EXPR:
+ return (lookup_template_function
+ (build_expr_from_tree (TREE_OPERAND (t, 0)),
+ build_expr_from_tree (TREE_OPERAND (t, 1))));
+
case INDIRECT_REF:
return build_x_indirect_ref
(build_expr_from_tree (TREE_OPERAND (t, 0)), "unary *");
@@ -3409,7 +3559,8 @@ build_expr_from_tree (t)
else
{
tree name = TREE_OPERAND (t, 0);
- if (! really_overloaded_fn (name))
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR
+ || ! really_overloaded_fn (name))
name = build_expr_from_tree (name);
return build_x_function_call
(name, build_expr_from_tree (TREE_OPERAND (t, 1)),
@@ -3438,7 +3589,7 @@ build_expr_from_tree (t)
chain = TREE_CHAIN (t);
if (chain && chain != void_type_node)
chain = build_expr_from_tree (chain);
- return tree_cons (purpose, value, chain);
+ return expr_tree_cons (purpose, value, chain);
}
case COMPONENT_REF:
@@ -3485,7 +3636,7 @@ reparse_decl_as_expr (type, decl)
{
decl = build_expr_from_tree (decl);
if (type)
- return build_functional_cast (type, build_tree_list (NULL_TREE, decl));
+ return build_functional_cast (type, build_expr_list (NULL_TREE, decl));
else
return decl;
}
@@ -3698,3 +3849,22 @@ mark_used (decl)
if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
instantiate_decl (decl);
}
+
+/* Helper function for named_class_head_sans_basetype nonterminal. */
+
+tree
+handle_class_head (aggr, scope, id)
+ tree aggr, scope, id;
+{
+ if (TREE_CODE (id) == TYPE_DECL)
+ return id;
+
+ if (scope)
+ cp_error ("`%T' does not have a nested type named `%D'", scope, id);
+ else
+ cp_error ("no file-scope type named `%D'", id);
+
+ id = xref_tag
+ (aggr, make_anon_name (), NULL_TREE, 1);
+ return TYPE_MAIN_DECL (id);
+}