blob: 496158d942b43c5787f630be1d6abab458e07cb2 [file] [log] [blame]
/* Process declarations and variables for C compiler.
Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Process declarations and symbol lookup for C front end.
Also constructs types; the standard scalar types at initialization,
and structure, union, array and enum types when they are declared. */
/* ??? not all decl nodes are given the most useful possible
line numbers. For example, the CONST_DECLs for enum values. */
#include "config.h"
#include "system.h"
#include "tree.h"
#include "rtl.h"
#include "flags.h"
#include "cp-tree.h"
#include "decl.h"
#include "lex.h"
#include <signal.h>
#include "obstack.h"
#include "defaults.h"
#include "output.h"
#include "except.h"
#include "toplev.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
extern tree builtin_return_address_fndecl;
extern struct obstack permanent_obstack;
extern struct obstack* saveable_obstack;
extern int current_class_depth;
extern tree static_ctors, static_dtors;
extern int static_labelno;
extern tree current_namespace;
extern tree global_namespace;
extern void (*print_error_function) PROTO((char *));
/* Stack of places to restore the search obstack back to. */
/* Obstack used for remembering local class declarations (like
enums and static (const) members. */
#include "stack.h"
struct obstack decl_obstack;
static struct stack_level *decl_stack;
#ifndef CHAR_TYPE_SIZE
#define CHAR_TYPE_SIZE BITS_PER_UNIT
#endif
#ifndef SHORT_TYPE_SIZE
#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2))
#endif
#ifndef INT_TYPE_SIZE
#define INT_TYPE_SIZE BITS_PER_WORD
#endif
#ifndef LONG_TYPE_SIZE
#define LONG_TYPE_SIZE BITS_PER_WORD
#endif
#ifndef LONG_LONG_TYPE_SIZE
#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
#endif
#ifndef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#endif
#ifndef FLOAT_TYPE_SIZE
#define FLOAT_TYPE_SIZE BITS_PER_WORD
#endif
#ifndef DOUBLE_TYPE_SIZE
#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
#endif
#ifndef LONG_DOUBLE_TYPE_SIZE
#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
#endif
#ifndef BOOL_TYPE_SIZE
#ifdef SLOW_BYTE_ACCESS
#define BOOL_TYPE_SIZE ((SLOW_BYTE_ACCESS) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE))
#else
#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE
#endif
#endif
/* We let tm.h override the types used here, to handle trivial differences
such as the choice of unsigned int or long unsigned int for size_t.
When machines start needing nontrivial differences in the size type,
it would be best to do something here to figure out automatically
from other information what type to use. */
#ifndef SIZE_TYPE
#define SIZE_TYPE "long unsigned int"
#endif
#ifndef PTRDIFF_TYPE
#define PTRDIFF_TYPE "long int"
#endif
#ifndef WCHAR_TYPE
#define WCHAR_TYPE "int"
#endif
static tree grokparms PROTO((tree, int));
static tree lookup_nested_type PROTO((tree, tree));
static char *redeclaration_error_message PROTO((tree, tree));
static tree push_overloaded_decl PROTO((tree, int));
static struct stack_level *push_decl_level PROTO((struct stack_level *,
struct obstack *));
static void push_binding_level PROTO((struct binding_level *, int,
int));
static void pop_binding_level PROTO((void));
static void suspend_binding_level PROTO((void));
static void resume_binding_level PROTO((struct binding_level *));
static struct binding_level *make_binding_level PROTO((void));
static int namespace_bindings_p PROTO((void));
static void declare_namespace_level PROTO((void));
static void signal_catch PROTO((int));
static void storedecls PROTO((tree));
static void storetags PROTO((tree));
static void require_complete_types_for_parms PROTO((tree));
static void push_overloaded_decl_1 PROTO((tree));
static int ambi_op_p PROTO((tree));
static int unary_op_p PROTO((tree));
static tree store_bindings PROTO((tree, tree));
static tree lookup_tag_reverse PROTO((tree, tree));
static tree obscure_complex_init PROTO((tree, tree));
static tree maybe_build_cleanup_1 PROTO((tree, tree));
static tree lookup_name_real PROTO((tree, int, int, int));
static void warn_extern_redeclared_static PROTO((tree, tree));
static void grok_reference_init PROTO((tree, tree, tree));
static tree grokfndecl PROTO((tree, tree, tree, tree, int,
enum overload_flags, tree,
tree, tree, int, int, int, int, int, int, tree));
static tree grokvardecl PROTO((tree, tree, RID_BIT_TYPE *, int, int, tree));
static tree lookup_tag PROTO((enum tree_code, tree,
struct binding_level *, int));
static void set_identifier_type_value_with_scope
PROTO((tree, tree, struct binding_level *));
static void set_identifier_local_value_with_scope
PROTO((tree, tree, struct binding_level *));
static void record_builtin_type PROTO((enum rid, char *, tree));
static void record_unknown_type PROTO((tree, char *));
static int member_function_or_else PROTO((tree, tree, char *));
static void bad_specifiers PROTO((tree, char *, int, int, int, int,
int));
static void lang_print_error_function PROTO((char *));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PROTO((void));
#endif
/* A node which has tree code ERROR_MARK, and whose type is itself.
All erroneous expressions are replaced with this node. All functions
that accept nodes as arguments should avoid generating error messages
if this node is one of the arguments, since it is undesirable to get
multiple error messages from one error in the input. */
tree error_mark_node;
/* Erroneous argument lists can use this *IFF* they do not modify it. */
tree error_mark_list;
/* INTEGER_TYPE and REAL_TYPE nodes for the standard data types */
tree short_integer_type_node;
tree integer_type_node;
tree long_integer_type_node;
tree long_long_integer_type_node;
tree short_unsigned_type_node;
tree unsigned_type_node;
tree long_unsigned_type_node;
tree long_long_unsigned_type_node;
tree ptrdiff_type_node;
tree unsigned_char_type_node;
tree signed_char_type_node;
tree char_type_node;
tree wchar_type_node;
tree signed_wchar_type_node;
tree unsigned_wchar_type_node;
tree wchar_decl_node;
tree float_type_node;
tree double_type_node;
tree long_double_type_node;
tree complex_integer_type_node;
tree complex_float_type_node;
tree complex_double_type_node;
tree complex_long_double_type_node;
tree intQI_type_node;
tree intHI_type_node;
tree intSI_type_node;
tree intDI_type_node;
tree intTI_type_node;
tree unsigned_intQI_type_node;
tree unsigned_intHI_type_node;
tree unsigned_intSI_type_node;
tree unsigned_intDI_type_node;
tree unsigned_intTI_type_node;
tree java_byte_type_node;
tree java_short_type_node;
tree java_int_type_node;
tree java_long_type_node;
tree java_float_type_node;
tree java_double_type_node;
tree java_char_type_node;
tree java_boolean_type_node;
/* A VOID_TYPE node, and the same, packaged in a TREE_LIST. */
tree void_type_node, void_list_node;
tree void_zero_node;
/* Nodes for types `void *' and `const void *'. */
tree ptr_type_node;
tree const_ptr_type_node;
/* Nodes for types `char *' and `const char *'. */
tree string_type_node, const_string_type_node;
/* Type `char[256]' or something like it.
Used when an array of char is needed and the size is irrelevant. */
tree char_array_type_node;
/* Type `int[256]' or something like it.
Used when an array of int needed and the size is irrelevant. */
tree int_array_type_node;
/* Type `wchar_t[256]' or something like it.
Used when a wide string literal is created. */
tree wchar_array_type_node;
/* The bool data type, and constants */
tree boolean_type_node, boolean_true_node, boolean_false_node;
/* Type `int ()' -- used for implicit declaration of functions. */
tree default_function_type;
/* Function types `double (double)' and `double (double, double)', etc. */
static tree double_ftype_double, double_ftype_double_double;
static tree int_ftype_int, long_ftype_long;
static tree float_ftype_float;
static tree ldouble_ftype_ldouble;
/* Function type `int (const void *, const void *, size_t)' */
static tree int_ftype_cptr_cptr_sizet;
/* C++ extensions */
tree vtable_entry_type;
tree delta_type_node;
#if 0
/* Old rtti stuff. */
tree __baselist_desc_type_node;
tree __i_desc_type_node, __m_desc_type_node;
tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type;
#endif
tree __t_desc_type_node;
#if 0
tree __tp_desc_type_node;
#endif
tree __access_mode_type_node;
tree __bltn_desc_type_node, __user_desc_type_node, __class_desc_type_node;
tree __ptr_desc_type_node, __attr_desc_type_node, __func_desc_type_node;
tree __ptmf_desc_type_node, __ptmd_desc_type_node;
#if 0
/* Not needed yet? May be needed one day? */
tree __bltn_desc_array_type, __user_desc_array_type, __class_desc_array_type;
tree __ptr_desc_array_type, __attr_dec_array_type, __func_desc_array_type;
tree __ptmf_desc_array_type, __ptmd_desc_array_type;
#endif
/* Indicates that there is a type value in some namespace, although
that is not necessarily in scope at the moment. */
static tree global_type_node;
tree class_star_type_node;
tree class_type_node, record_type_node, union_type_node, enum_type_node;
tree unknown_type_node;
tree opaque_type_node, signature_type_node;
tree sigtable_entry_type;
/* Array type `vtable_entry_type[]' */
tree vtbl_type_node;
/* namespace std */
tree std_node;
int in_std = 0;
/* Expect only namespace names now. */
static int only_namespace_names;
/* In a destructor, the point at which all derived class destroying
has been done, just before any base class destroying will be done. */
tree dtor_label;
/* In a destructor, the last insn emitted after the start of the
function and the parms. */
static rtx last_dtor_insn;
/* In a constructor, the last insn emitted after the start of the
function and the parms, the exception specification and any
function-try-block. The constructor initializers are emitted after
this insn. */
static rtx last_parm_cleanup_insn;
/* In a constructor, the point at which we are ready to return
the pointer to the initialized object. */
tree ctor_label;
/* A FUNCTION_DECL which can call `abort'. Not necessarily the
one that the user will declare, but sufficient to be called
by routines that want to abort the program. */
tree abort_fndecl;
extern rtx cleanup_label, return_label;
/* If original DECL_RESULT of current function was a register,
but due to being an addressable named return value, would up
on the stack, this variable holds the named return value's
original location. */
static rtx original_result_rtx;
/* Sequence of insns which represents base initialization. */
tree base_init_expr;
/* C++: Keep these around to reduce calls to `get_identifier'.
Identifiers for `this' in member functions and the auto-delete
parameter for destructors. */
tree this_identifier, in_charge_identifier;
tree ctor_identifier, dtor_identifier;
/* Used in pointer to member functions, in vtables, and in sigtables. */
tree pfn_identifier, index_identifier, delta_identifier, delta2_identifier;
tree pfn_or_delta2_identifier, tag_identifier;
tree vt_off_identifier;
struct named_label_list
{
struct binding_level *binding_level;
tree names_in_scope;
tree label_decl;
char *filename_o_goto;
int lineno_o_goto;
struct named_label_list *next;
};
/* A list (chain of TREE_LIST nodes) of named label uses.
The TREE_PURPOSE field is the list of variables defined
in the label's scope defined at the point of use.
The TREE_VALUE field is the LABEL_DECL used.
The TREE_TYPE field holds `current_binding_level' at the
point of the label's use.
BWAHAHAAHAHahhahahahaah. No, no, no, said the little chicken.
Look at the pretty struct named_label_list. See the pretty struct
with the pretty named fields that describe what they do. See the
pretty lack of gratuitous casts. Notice the code got a lot cleaner.
Used only for jumps to as-yet undefined labels, since
jumps to defined labels can have their validity checked
by stmt.c. */
static struct named_label_list *named_label_uses = NULL;
/* A list of objects which have constructors or destructors
which reside in the global scope. The decl is stored in
the TREE_VALUE slot and the initializer is stored
in the TREE_PURPOSE slot. */
tree static_aggregates;
/* -- end of C++ */
/* Two expressions that are constants with value zero.
The first is of type `int', the second of type `void *'. */
tree integer_zero_node;
tree null_pointer_node;
/* The value for __null (NULL), either of type `void *' or, with -ansi,
an integer type of the same size. */
tree null_node;
/* A node for the integer constants 1, 2, and 3. */
tree integer_one_node, integer_two_node, integer_three_node;
/* While defining an enum type, this is 1 plus the last enumerator
constant value. */
static tree enum_next_value;
/* Nonzero means that there was overflow computing enum_next_value. */
static int enum_overflow;
/* Parsing a function declarator leaves a list of parameter names
or a chain or parameter decls here. */
tree last_function_parms;
/* Parsing a function declarator leaves here a chain of structure
and enum types declared in the parmlist. */
static tree last_function_parm_tags;
/* After parsing the declarator that starts a function definition,
`start_function' puts here the list of parameter names or chain of decls.
`store_parm_decls' finds it here. */
static tree current_function_parms;
/* Similar, for last_function_parm_tags. */
static tree current_function_parm_tags;
/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
that have names. Here so we can clear out their names' definitions
at the end of the function. */
static tree named_labels;
/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
static tree shadowed_labels;
/* The FUNCTION_DECL for the function currently being compiled,
or 0 if between functions. */
tree current_function_decl;
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
int current_function_returns_value;
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement with no argument is seen. */
int current_function_returns_null;
/* Set to 0 at beginning of a function definition, and whenever
a label (case or named) is defined. Set to value of expression
returned from function when that value can be transformed into
a named return value. */
tree current_function_return_value;
/* Set to nonzero by `grokdeclarator' for a function
whose return type is defaulted, if warnings for this are desired. */
static int warn_about_return_type;
/* Nonzero means give `double' the same size as `float'. */
extern int flag_short_double;
/* Nonzero means don't recognize any builtin functions. */
extern int flag_no_builtin;
/* Nonzero means don't recognize the non-ANSI builtin functions.
-ansi sets this. */
extern int flag_no_nonansi_builtin;
/* Nonzero means enable obscure ANSI features and disable GNU extensions
that might cause ANSI-compliant code to be miscompiled. */
extern int flag_ansi;
/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
objects. */
extern int flag_huge_objects;
/* Nonzero if we want to conserve space in the .o files. We do this
by putting uninitialized data and runtime initialized data into
.common instead of .data at the expense of not flagging multiple
definitions. */
extern int flag_conserve_space;
/* Pointers to the base and current top of the language name stack. */
extern tree *current_lang_base, *current_lang_stack;
/* C and C++ flags are in decl2.c. */
/* Set to 0 at beginning of a constructor, set to 1
if that function does an allocation before referencing its
instance variable. */
static int current_function_assigns_this;
int current_function_just_assigned_this;
/* Set to 0 at beginning of a function. Set non-zero when
store_parm_decls is called. Don't call store_parm_decls
if this flag is non-zero! */
int current_function_parms_stored;
/* Flag used when debugging spew.c */
extern int spew_debug;
/* This is a copy of the class_shadowed list of the previous class binding
contour when at global scope. It's used to reset IDENTIFIER_CLASS_VALUEs
when entering another class scope (i.e. a cache miss). */
extern tree previous_class_values;
/* A expression of value 0 with the same precision as a sizetype
node, but signed. */
tree signed_size_zero_node;
/* Allocate a level of searching. */
static
struct stack_level *
push_decl_level (stack, obstack)
struct stack_level *stack;
struct obstack *obstack;
{
struct stack_level tem;
tem.prev = stack;
return push_stack_level (obstack, (char *)&tem, sizeof (tem));
}
/* For each binding contour we allocate a binding_level structure
which records the names defined in that contour.
Contours include:
0) the global one
1) one for each function definition,
where internal declarations of the parameters appear.
2) one for each compound statement,
to record its declarations.
The current meaning of a name can be found by searching the levels
from the current one out to the global one.
Off to the side, may be the class_binding_level. This exists only
to catch class-local declarations. It is otherwise nonexistent.
Also there may be binding levels that catch cleanups that must be
run when exceptions occur. */
/* Note that the information in the `names' component of the global contour
is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
struct binding_level
{
/* A chain of _DECL nodes for all variables, constants, functions,
and typedef types. These are in the reverse of the order
supplied. */
tree names;
/* A list of structure, union and enum definitions, for looking up
tag names.
It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name,
or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE,
or ENUMERAL_TYPE node.
C++: the TREE_VALUE nodes can be simple types for
component_bindings. */
tree tags;
/* A list of USING_DECL nodes. */
tree usings;
/* A list of used namespaces. PURPOSE is the namespace,
VALUE the common ancestor with this binding_level's namespace. */
tree using_directives;
/* For each level, a list of shadowed outer-level local definitions
to be restored when this level is popped.
Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
whose TREE_VALUE is its old definition (a kind of ..._DECL node). */
tree shadowed;
/* Same, for IDENTIFIER_CLASS_VALUE. */
tree class_shadowed;
/* Same, for IDENTIFIER_TYPE_VALUE. */
tree type_shadowed;
/* For each level (except not the global one),
a chain of BLOCK nodes for all the levels
that were entered and exited one level down. */
tree blocks;
/* The BLOCK node for this level, if one has been preallocated.
If 0, the BLOCK is allocated (if needed) when the level is popped. */
tree this_block;
/* The binding level which this one is contained in (inherits from). */
struct binding_level *level_chain;
/* List of decls in `names' that have incomplete
structure or union types. */
tree incomplete;
/* List of VAR_DECLS saved from a previous for statement.
These would be dead in ANSI-conforming code, but might
be referenced in ARM-era code. */
tree dead_vars_from_for;
/* 1 for the level that holds the parameters of a function.
2 for the level that holds a class declaration.
3 for levels that hold parameter declarations. */
unsigned parm_flag : 4;
/* 1 means make a BLOCK for this level regardless of all else.
2 for temporary binding contours created by the compiler. */
unsigned keep : 3;
/* Nonzero if this level "doesn't exist" for tags. */
unsigned tag_transparent : 1;
/* Nonzero if this level can safely have additional
cleanup-needing variables added to it. */
unsigned more_cleanups_ok : 1;
unsigned have_cleanups : 1;
/* Nonzero if this level is for storing the decls for template
parameters and generic decls; these decls will be discarded and
replaced with a TEMPLATE_DECL. */
unsigned pseudo_global : 1;
/* This is set for a namespace binding level. */
unsigned namespace_p : 1;
/* True if this level is that of a for-statement where we need to
worry about ambiguous (ARM or ANSI) scope rules. */
unsigned is_for_scope : 1;
/* Two bits left for this word. */
#if defined(DEBUG_CP_BINDING_LEVELS)
/* Binding depth at which this level began. */
unsigned binding_depth;
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
};
#define NULL_BINDING_LEVEL ((struct binding_level *) NULL)
/* The (non-class) binding level currently in effect. */
static struct binding_level *current_binding_level;
/* The binding level of the current class, if any. */
static struct binding_level *class_binding_level;
/* The current (class or non-class) binding level currently in effect. */
#define inner_binding_level \
(class_binding_level ? class_binding_level : current_binding_level)
/* A chain of binding_level structures awaiting reuse. */
static struct binding_level *free_binding_level;
/* The outermost binding level, for names of file scope.
This is created when the compiler is started and exists
through the entire run. */
static struct binding_level *global_binding_level;
/* Binding level structures are initialized by copying this one. */
static struct binding_level clear_binding_level;
/* Nonzero means unconditionally make a BLOCK for the next level pushed. */
static int keep_next_level_flag;
#if defined(DEBUG_CP_BINDING_LEVELS)
static int binding_depth = 0;
static int is_class_level = 0;
static void
indent ()
{
register unsigned i;
for (i = 0; i < binding_depth*2; i++)
putc (' ', stderr);
}
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
static tree pushdecl_with_scope PROTO((tree, struct binding_level *));
static void
push_binding_level (newlevel, tag_transparent, keep)
struct binding_level *newlevel;
int tag_transparent, keep;
{
/* Add this level to the front of the chain (stack) of levels that
are active. */
*newlevel = clear_binding_level;
if (class_binding_level)
{
newlevel->level_chain = class_binding_level;
class_binding_level = (struct binding_level *)0;
}
else
{
newlevel->level_chain = current_binding_level;
}
current_binding_level = newlevel;
newlevel->tag_transparent = tag_transparent;
newlevel->more_cleanups_ok = 1;
newlevel->keep = keep;
#if defined(DEBUG_CP_BINDING_LEVELS)
newlevel->binding_depth = binding_depth;
indent ();
fprintf (stderr, "push %s level 0x%08x line %d\n",
(is_class_level) ? "class" : "block", newlevel, lineno);
is_class_level = 0;
binding_depth++;
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
}
static void
pop_binding_level ()
{
if (class_binding_level)
current_binding_level = class_binding_level;
if (global_binding_level)
{
/* Cannot pop a level, if there are none left to pop. */
if (current_binding_level == global_binding_level)
my_friendly_abort (123);
}
/* Pop the current level, and free the structure for reuse. */
#if defined(DEBUG_CP_BINDING_LEVELS)
binding_depth--;
indent ();
fprintf (stderr, "pop %s level 0x%08x line %d\n",
(is_class_level) ? "class" : "block",
current_binding_level, lineno);
if (is_class_level != (current_binding_level == class_binding_level))
{
indent ();
fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n");
}
is_class_level = 0;
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
{
register struct binding_level *level = current_binding_level;
current_binding_level = current_binding_level->level_chain;
level->level_chain = free_binding_level;
#if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */
if (level->binding_depth != binding_depth)
abort ();
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
free_binding_level = level;
class_binding_level = current_binding_level;
if (class_binding_level->parm_flag != 2)
class_binding_level = 0;
while (current_binding_level->parm_flag == 2)
current_binding_level = current_binding_level->level_chain;
}
}
static void
suspend_binding_level ()
{
if (class_binding_level)
current_binding_level = class_binding_level;
if (global_binding_level)
{
/* Cannot suspend a level, if there are none left to suspend. */
if (current_binding_level == global_binding_level)
my_friendly_abort (123);
}
/* Suspend the current level. */
#if defined(DEBUG_CP_BINDING_LEVELS)
binding_depth--;
indent ();
fprintf (stderr, "suspend %s level 0x%08x line %d\n",
(is_class_level) ? "class" : "block",
current_binding_level, lineno);
if (is_class_level != (current_binding_level == class_binding_level))
{
indent ();
fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n");
}
is_class_level = 0;
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
{
current_binding_level = current_binding_level->level_chain;
class_binding_level = current_binding_level;
if (class_binding_level->parm_flag != 2)
class_binding_level = 0;
while (current_binding_level->parm_flag == 2)
current_binding_level = current_binding_level->level_chain;
}
}
static void
resume_binding_level (b)
struct binding_level *b;
{
/* Resuming binding levels is meant only for namespaces,
and those cannot nest into classes. */
my_friendly_assert(!class_binding_level, 386);
/* Also, resuming a non-directly nested namespace is a no-no. */
my_friendly_assert(b->level_chain == current_binding_level, 386);
current_binding_level = b;
#if defined(DEBUG_CP_BINDING_LEVELS)
b->binding_depth = binding_depth;
indent ();
fprintf (stderr, "resume %s level 0x%08x line %d\n",
(is_class_level) ? "class" : "block", b, lineno);
is_class_level = 0;
binding_depth++;
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
}
/* Create a new `struct binding_level'. */
static
struct binding_level *
make_binding_level ()
{
/* NOSTRICT */
return (struct binding_level *) xmalloc (sizeof (struct binding_level));
}
/* Nonzero if we are currently in the global binding level. */
int
global_bindings_p ()
{
return current_binding_level == global_binding_level;
}
/* Nonzero if we are currently in a toplevel binding level. This
means either the global binding level or a namespace in a toplevel
binding level.
Since there are no non-toplevel namespace levels, this really
means any namespace or pseudo-global level. */
int
toplevel_bindings_p ()
{
return current_binding_level->namespace_p
|| current_binding_level->pseudo_global;
}
/* Nonzero if this is a namespace scope. */
static int
namespace_bindings_p ()
{
return current_binding_level->namespace_p;
}
void
keep_next_level ()
{
keep_next_level_flag = 1;
}
/* Nonzero if the current level needs to have a BLOCK made. */
int
kept_level_p ()
{
return (current_binding_level->blocks != NULL_TREE
|| current_binding_level->keep
|| current_binding_level->names != NULL_TREE
|| (current_binding_level->tags != NULL_TREE
&& !current_binding_level->tag_transparent));
}
/* Identify this binding level as a level of parameters. */
void
declare_parm_level ()
{
current_binding_level->parm_flag = 1;
}
void
declare_pseudo_global_level ()
{
current_binding_level->pseudo_global = 1;
}
static void
declare_namespace_level ()
{
current_binding_level->namespace_p = 1;
}
int
pseudo_global_level_p ()
{
return current_binding_level->pseudo_global;
}
void
set_class_shadows (shadows)
tree shadows;
{
class_binding_level->class_shadowed = shadows;
}
/* Enter a new binding level.
If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
not for that of tags. */
void
pushlevel (tag_transparent)
int tag_transparent;
{
register struct binding_level *newlevel = NULL_BINDING_LEVEL;
/* If this is the top level of a function,
just make sure that NAMED_LABELS is 0.
They should have been set to 0 at the end of the previous function. */
if (current_binding_level == global_binding_level)
my_friendly_assert (named_labels == NULL_TREE, 134);
/* Reuse or create a struct for this binding level. */
#if defined(DEBUG_CP_BINDING_LEVELS)
if (0)
#else /* !defined(DEBUG_CP_BINDING_LEVELS) */
if (free_binding_level)
#endif /* !defined(DEBUG_CP_BINDING_LEVELS) */
{
newlevel = free_binding_level;
free_binding_level = free_binding_level->level_chain;
}
else
{
newlevel = make_binding_level ();
}
push_binding_level (newlevel, tag_transparent, keep_next_level_flag);
GNU_xref_start_scope ((HOST_WIDE_INT) newlevel);
keep_next_level_flag = 0;
}
void
note_level_for_for ()
{
current_binding_level->is_for_scope = 1;
}
void
pushlevel_temporary (tag_transparent)
int tag_transparent;
{
pushlevel (tag_transparent);
current_binding_level->keep = 2;
clear_last_expr ();
/* Note we don't call push_momentary() here. Otherwise, it would cause
cleanups to be allocated on the momentary obstack, and they will be
overwritten by the next statement. */
expand_start_bindings (0);
}
/* Exit a binding level.
Pop the level off, and restore the state of the identifier-decl mappings
that were in effect when this level was entered.
If KEEP == 1, this level had explicit declarations, so
and create a "block" (a BLOCK node) for the level
to record its declarations and subblocks for symbol table output.
If KEEP == 2, this level's subblocks go to the front,
not the back of the current binding level. This happens,
for instance, when code for constructors and destructors
need to generate code at the end of a function which must
be moved up to the front of the function.
If FUNCTIONBODY is nonzero, this level is the body of a function,
so create a block as if KEEP were set and also clear out all
label names.
If REVERSE is nonzero, reverse the order of decls before putting
them into the BLOCK. */
tree
poplevel (keep, reverse, functionbody)
int keep;
int reverse;
int functionbody;
{
register tree link;
/* The chain of decls was accumulated in reverse order.
Put it into forward order, just for cleanliness. */
tree decls;
int tmp = functionbody;
int real_functionbody = current_binding_level->keep == 2
? ((functionbody = 0), tmp) : functionbody;
tree tags = functionbody >= 0 ? current_binding_level->tags : 0;
tree subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
tree block = NULL_TREE;
tree decl;
int block_previously_created;
GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level,
(HOST_WIDE_INT) current_binding_level->level_chain,
current_binding_level->parm_flag,
current_binding_level->keep);
if (current_binding_level->keep == 1)
keep = 1;
/* Get the decls in the order they were written.
Usually current_binding_level->names is in reverse order.
But parameter decls were previously put in forward order. */
if (reverse)
current_binding_level->names
= decls = nreverse (current_binding_level->names);
else
decls = current_binding_level->names;
/* Output any nested inline functions within this block
if they weren't already output. */
for (decl = decls; decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == FUNCTION_DECL
&& ! TREE_ASM_WRITTEN (decl)
&& DECL_INITIAL (decl) != NULL_TREE
&& TREE_ADDRESSABLE (decl)
&& decl_function_context (decl) == current_function_decl)
{
/* If this decl was copied from a file-scope decl
on account of a block-scope extern decl,
propagate TREE_ADDRESSABLE to the file-scope decl. */
if (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE)
TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
else
{
push_function_context ();
output_inline_function (decl);
pop_function_context ();
}
}
/* If there were any declarations or structure tags in that level,
or if this level is a function body,
create a BLOCK to record them for the life of this function. */
block = NULL_TREE;
block_previously_created = (current_binding_level->this_block != NULL_TREE);
if (block_previously_created)
block = current_binding_level->this_block;
else if (keep == 1 || functionbody)
block = make_node (BLOCK);
if (block != NULL_TREE)
{
if (block_previously_created)
{
if (decls || tags || subblocks)
{
if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block))
{
warning ("internal compiler error: debugging info corrupted");
}
BLOCK_VARS (block) = decls;
BLOCK_TYPE_TAGS (block) = tags;
/* We can have previous subblocks and new subblocks when
doing fixup_gotos with complex cleanups. We chain the new
subblocks onto the end of any pre-existing subblocks. */
BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block),
subblocks);
}
/* If we created the block earlier on, and we are just
diddling it now, then it already should have a proper
BLOCK_END_NOTE value associated with it. */
}
else
{
BLOCK_VARS (block) = decls;
BLOCK_TYPE_TAGS (block) = tags;
BLOCK_SUBBLOCKS (block) = subblocks;
/* Otherwise, for a new block, install a new BLOCK_END_NOTE value. */
remember_end_note (block);
}
}
/* In each subblock, record that this is its superior. */
if (keep >= 0)
for (link = subblocks; link; link = TREE_CHAIN (link))
BLOCK_SUPERCONTEXT (link) = block;
/* Clear out the meanings of the local variables of this level. */
if (current_binding_level->is_for_scope && flag_new_for_scope == 1)
{
struct binding_level *outer = current_binding_level->level_chain;
for (link = decls; link; link = TREE_CHAIN (link))
{
if (TREE_CODE (link) == VAR_DECL)
DECL_DEAD_FOR_LOCAL (link) = 1;
else
IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE;
}
/* Save declarations made in a 'for' statement so we can support pre-ANSI
'for' scoping semantics. */
for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
{
tree id = TREE_PURPOSE (link);
tree decl = IDENTIFIER_LOCAL_VALUE (id);
if (decl && DECL_DEAD_FOR_LOCAL (decl))
{
/* In this case keep the dead for-decl visible,
but remember what (if anything) it shadowed. */
DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link);
TREE_CHAIN (decl) = outer->dead_vars_from_for;
outer->dead_vars_from_for = decl;
}
else
IDENTIFIER_LOCAL_VALUE (id) = TREE_VALUE (link);
}
}
else /* Not special for scope. */
{
for (link = decls; link; link = TREE_CHAIN (link))
{
if (DECL_NAME (link) != NULL_TREE)
{
/* If the ident. was used or addressed via a local extern decl,
don't forget that fact. */
if (DECL_EXTERNAL (link))
{
if (TREE_USED (link))
TREE_USED (DECL_ASSEMBLER_NAME (link)) = 1;
if (TREE_ADDRESSABLE (link))
TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
}
IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE;
}
}
/* Restore all name-meanings of the outer levels
that were shadowed by this level. */
for (link = current_binding_level->shadowed;
link; link = TREE_CHAIN (link))
IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
/* We first restore the regular decls and *then* the dead_vars_from_for
to handle this case:
int i; // i#1
{
for (int i; ; ) { ...} // i#2
int i; // i#3
} // we are here
In this case, we want remove the binding for i#3, restoring
that of i#2. Then we want to remove the binding for i#2,
and restore that of i#1. */
link = current_binding_level->dead_vars_from_for;
for (; link != NULL_TREE; link = TREE_CHAIN (link))
{
tree id = DECL_NAME (link);
if (IDENTIFIER_LOCAL_VALUE (id) == link)
IDENTIFIER_LOCAL_VALUE (id) = DECL_SHADOWED_FOR_VAR (link);
}
for (link = current_binding_level->class_shadowed;
link; link = TREE_CHAIN (link))
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
for (link = current_binding_level->type_shadowed;
link; link = TREE_CHAIN (link))
SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
}
/* If the level being exited is the top level of a function,
check over all the labels. */
if (functionbody)
{
/* If this is the top level block of a function,
the vars are the function's parameters.
Don't leave them in the BLOCK because they are
found in the FUNCTION_DECL instead. */
BLOCK_VARS (block) = 0;
/* Clear out the definitions of all label names,
since their scopes end here. */
for (link = named_labels; link; link = TREE_CHAIN (link))
{
register tree label = TREE_VALUE (link);
if (DECL_INITIAL (label) == NULL_TREE)
{
cp_error_at ("label `%D' used but not defined", label);
/* Avoid crashing later. */
define_label (input_filename, 1, DECL_NAME (label));
}
else if (warn_unused && !TREE_USED (label))
cp_warning_at ("label `%D' defined but not used", label);
SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), NULL_TREE);
/* Put the labels into the "variables" of the
top-level block, so debugger can see them. */
TREE_CHAIN (label) = BLOCK_VARS (block);
BLOCK_VARS (block) = label;
}
named_labels = NULL_TREE;
}
/* Any uses of undefined labels now operate under constraints
of next binding contour. */
{
struct binding_level *level_chain;
level_chain = current_binding_level->level_chain;
if (level_chain)
{
struct named_label_list *labels;
for (labels = named_label_uses; labels; labels = labels->next)
if (labels->binding_level == current_binding_level)
{
labels->binding_level = level_chain;
labels->names_in_scope = level_chain->names;
}
}
}
tmp = current_binding_level->keep;
pop_binding_level ();
if (functionbody)
DECL_INITIAL (current_function_decl) = block;
else if (block)
{
if (!block_previously_created)
current_binding_level->blocks
= chainon (current_binding_level->blocks, block);
}
/* If we did not make a block for the level just exited,
any blocks made for inner levels
(since they cannot be recorded as subblocks in that level)
must be carried forward so they will later become subblocks
of something else. */
else if (subblocks)
{
if (keep == 2)
current_binding_level->blocks
= chainon (subblocks, current_binding_level->blocks);
else
current_binding_level->blocks
= chainon (current_binding_level->blocks, subblocks);
}
/* Take care of compiler's internal binding structures. */
if (tmp == 2)
{
expand_end_bindings (getdecls (), keep, 1);
/* Each and every BLOCK node created here in `poplevel' is important
(e.g. for proper debugging information) so if we created one
earlier, mark it as "used". */
if (block)
TREE_USED (block) = 1;
block = poplevel (keep, reverse, real_functionbody);
}
/* Each and every BLOCK node created here in `poplevel' is important
(e.g. for proper debugging information) so if we created one
earlier, mark it as "used". */
if (block)
TREE_USED (block) = 1;
return block;
}
/* Delete the node BLOCK from the current binding level.
This is used for the block inside a stmt expr ({...})
so that the block can be reinserted where appropriate. */
void
delete_block (block)
tree block;
{
tree t;
if (current_binding_level->blocks == block)
current_binding_level->blocks = TREE_CHAIN (block);
for (t = current_binding_level->blocks; t;)
{
if (TREE_CHAIN (t) == block)
TREE_CHAIN (t) = TREE_CHAIN (block);
else
t = TREE_CHAIN (t);
}
TREE_CHAIN (block) = NULL_TREE;
/* Clear TREE_USED which is always set by poplevel.
The flag is set again if insert_block is called. */
TREE_USED (block) = 0;
}
/* Insert BLOCK at the end of the list of subblocks of the
current binding level. This is used when a BIND_EXPR is expanded,
to handle the BLOCK node inside the BIND_EXPR. */
void
insert_block (block)
tree block;
{
TREE_USED (block) = 1;
current_binding_level->blocks
= chainon (current_binding_level->blocks, block);
}
/* Set the BLOCK node for the innermost scope
(the one we are currently in). */
void
set_block (block)
register tree block;
{
current_binding_level->this_block = block;
}
/* Do a pushlevel for class declarations. */
void
pushlevel_class ()
{
register struct binding_level *newlevel;
/* Reuse or create a struct for this binding level. */
#if defined(DEBUG_CP_BINDING_LEVELS)
if (0)
#else /* !defined(DEBUG_CP_BINDING_LEVELS) */
if (free_binding_level)
#endif /* !defined(DEBUG_CP_BINDING_LEVELS) */
{
newlevel = free_binding_level;
free_binding_level = free_binding_level->level_chain;
}
else
{
newlevel = make_binding_level ();
}
#if defined(DEBUG_CP_BINDING_LEVELS)
is_class_level = 1;
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
push_binding_level (newlevel, 0, 0);
decl_stack = push_decl_level (decl_stack, &decl_obstack);
class_binding_level = current_binding_level;
class_binding_level->parm_flag = 2;
/* We have just pushed into a new binding level. Now, fake out the rest
of the compiler. Set the `current_binding_level' back to point to
the most closely containing non-class binding level. */
do
{
current_binding_level = current_binding_level->level_chain;
}
while (current_binding_level->parm_flag == 2);
}
/* ...and a poplevel for class declarations. FORCE is used to force
clearing out of CLASS_VALUEs after a class definition. */
tree
poplevel_class (force)
int force;
{
register struct binding_level *level = class_binding_level;
tree block = NULL_TREE;
tree shadowed;
my_friendly_assert (level != 0, 354);
decl_stack = pop_stack_level (decl_stack);
for (shadowed = level->shadowed; shadowed; shadowed = TREE_CHAIN (shadowed))
IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed);
/* If we're leaving a toplevel class, don't bother to do the setting
of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot
shouldn't even be used when current_class_type isn't set, and second,
if we don't touch it here, we're able to use the cache effect if the
next time we're entering a class scope, it is the same class. */
if (current_class_depth != 1 || force)
for (shadowed = level->class_shadowed;
shadowed;
shadowed = TREE_CHAIN (shadowed))
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed);
else
/* Remember to save what IDENTIFIER's were bound in this scope so we
can recover from cache misses. */
{
previous_class_type = current_class_type;
previous_class_values = class_binding_level->class_shadowed;
}
for (shadowed = level->type_shadowed;
shadowed;
shadowed = TREE_CHAIN (shadowed))
SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level,
(HOST_WIDE_INT) class_binding_level->level_chain,
class_binding_level->parm_flag,
class_binding_level->keep);
if (class_binding_level->parm_flag != 2)
class_binding_level = (struct binding_level *)0;
/* Now, pop out of the binding level which we created up in the
`pushlevel_class' routine. */
#if defined(DEBUG_CP_BINDING_LEVELS)
is_class_level = 1;
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
pop_binding_level ();
return block;
}
/* For debugging. */
static int no_print_functions = 0;
static int no_print_builtins = 0;
void
print_binding_level (lvl)
struct binding_level *lvl;
{
tree t;
int i = 0, len;
fprintf (stderr, " blocks=");
fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks);
fprintf (stderr, " n_incomplete=%d parm_flag=%d keep=%d",
list_length (lvl->incomplete), lvl->parm_flag, lvl->keep);
if (lvl->tag_transparent)
fprintf (stderr, " tag-transparent");
if (lvl->more_cleanups_ok)
fprintf (stderr, " more-cleanups-ok");
if (lvl->have_cleanups)
fprintf (stderr, " have-cleanups");
fprintf (stderr, "\n");
if (lvl->names)
{
fprintf (stderr, " names:\t");
/* We can probably fit 3 names to a line? */
for (t = lvl->names; t; t = TREE_CHAIN (t))
{
if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
continue;
if (no_print_builtins
&& (TREE_CODE (t) == TYPE_DECL)
&& (!strcmp (DECL_SOURCE_FILE (t),"<built-in>")))
continue;
/* Function decls tend to have longer names. */
if (TREE_CODE (t) == FUNCTION_DECL)
len = 3;
else
len = 2;
i += len;
if (i > 6)
{
fprintf (stderr, "\n\t");
i = len;
}
print_node_brief (stderr, "", t, 0);
if (t == error_mark_node)
break;
}
if (i)
fprintf (stderr, "\n");
}
if (lvl->tags)
{
fprintf (stderr, " tags:\t");
i = 0;
for (t = lvl->tags; t; t = TREE_CHAIN (t))
{
if (TREE_PURPOSE (t) == NULL_TREE)
len = 3;
else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t)))
len = 2;
else
len = 4;
i += len;
if (i > 5)
{
fprintf (stderr, "\n\t");
i = len;
}
if (TREE_PURPOSE (t) == NULL_TREE)
{
print_node_brief (stderr, "<unnamed-typedef", TREE_VALUE (t), 0);
fprintf (stderr, ">");
}
else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t)))
print_node_brief (stderr, "", TREE_VALUE (t), 0);
else
{
print_node_brief (stderr, "<typedef", TREE_PURPOSE (t), 0);
print_node_brief (stderr, "", TREE_VALUE (t), 0);
fprintf (stderr, ">");
}
}
if (i)
fprintf (stderr, "\n");
}
if (lvl->shadowed)
{
fprintf (stderr, " shadowed:");
for (t = lvl->shadowed; t; t = TREE_CHAIN (t))
{
fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
}
fprintf (stderr, "\n");
}
if (lvl->class_shadowed)
{
fprintf (stderr, " class-shadowed:");
for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t))
{
fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
}
fprintf (stderr, "\n");
}
if (lvl->type_shadowed)
{
fprintf (stderr, " type-shadowed:");
for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
{
fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
}
fprintf (stderr, "\n");
}
}
void
print_other_binding_stack (stack)
struct binding_level *stack;
{
struct binding_level *level;
for (level = stack; level != global_binding_level; level = level->level_chain)
{
fprintf (stderr, "binding level ");
fprintf (stderr, HOST_PTR_PRINTF, level);
fprintf (stderr, "\n");
print_binding_level (level);
}
}
void
print_binding_stack ()
{
struct binding_level *b;
fprintf (stderr, "current_binding_level=");
fprintf (stderr, HOST_PTR_PRINTF, current_binding_level);
fprintf (stderr, "\nclass_binding_level=");
fprintf (stderr, HOST_PTR_PRINTF, class_binding_level);
fprintf (stderr, "\nglobal_binding_level=");
fprintf (stderr, HOST_PTR_PRINTF, global_binding_level);
fprintf (stderr, "\n");
if (class_binding_level)
{
for (b = class_binding_level; b; b = b->level_chain)
if (b == current_binding_level)
break;
if (b)
b = class_binding_level;
else
b = current_binding_level;
}
else
b = current_binding_level;
print_other_binding_stack (b);
fprintf (stderr, "global:\n");
print_binding_level (global_binding_level);
}
/* Namespace binding access routines: The namespace_bindings field of
the identifier is polymorphic, with three possible values:
NULL_TREE, a list of CPLUS_BINDINGS, or any other tree_node
indicating the BINDING_VALUE of global_namespace. */
/* Check whether the a binding for the name to scope is known.
Assumes that the bindings of the name are already a list
of bindings. Returns the binding found, or NULL_TREE. */
static tree
find_binding (name, scope)
tree name;
tree scope;
{
tree iter, prev = NULL_TREE;
scope = ORIGINAL_NAMESPACE (scope);
for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
iter = TREE_CHAIN (iter))
{
my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
if (BINDING_SCOPE (iter) == scope)
{
/* Move binding found to the fron of the list, so
subsequent lookups will find it faster. */
if (prev)
{
TREE_CHAIN (prev) = TREE_CHAIN (iter);
TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name);
IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
}
return iter;
}
prev = iter;
}
return NULL_TREE;
}
/* Always returns a binding for name in scope. If the
namespace_bindings is not a list, convert it to one first.
If no binding is found, make a new one. */
tree
binding_for_name (name, scope)
tree name;
tree scope;
{
tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
tree result;
scope = ORIGINAL_NAMESPACE (scope);
if (b && TREE_CODE (b) != CPLUS_BINDING)
{
/* Get rid of optimization for global scope. */
IDENTIFIER_NAMESPACE_BINDINGS (name) = NULL_TREE;
BINDING_VALUE (binding_for_name (name, global_namespace)) = b;
b = IDENTIFIER_NAMESPACE_BINDINGS (name);
}
if (b && (result = find_binding (name, scope)))
return result;
/* Not found, make a new permanent one. */
push_obstacks (&permanent_obstack, &permanent_obstack);
result = make_node (CPLUS_BINDING);
TREE_CHAIN (result) = b;
IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
BINDING_SCOPE (result) = scope;
BINDING_TYPE (result) = NULL_TREE;
BINDING_VALUE (result) = NULL_TREE;
pop_obstacks ();
return result;
}
/* Return the binding value for name in scope, considering that
namespace_binding may or may not be a list of CPLUS_BINDINGS. */
tree
namespace_binding (name, scope)
tree name;
tree scope;
{
tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
if (b == NULL_TREE)
return NULL_TREE;
if (scope == NULL_TREE)
scope = global_namespace;
if (TREE_CODE (b) != CPLUS_BINDING)
return (scope == global_namespace) ? b : NULL_TREE;
name = find_binding (name,scope);
if (name == NULL_TREE)
return name;
return BINDING_VALUE (name);
}
/* Set the binding value for name in scope. If modifying the binding
of global_namespace is attempted, try to optimize it. */
void
set_namespace_binding (name, scope, val)
tree name;
tree scope;
tree val;
{
tree b;
if (scope == NULL_TREE)
scope = global_namespace;
if (scope == global_namespace)
{
b = IDENTIFIER_NAMESPACE_BINDINGS (name);
if (b == NULL_TREE || TREE_CODE (b) != CPLUS_BINDING)
{
IDENTIFIER_NAMESPACE_BINDINGS (name) = val;
return;
}
}
b = binding_for_name (name, scope);
BINDING_VALUE (b) = val;
}
/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
select a name that is unique to this compilation unit. */
void
push_namespace (name)
tree name;
{
tree d;
int need_new = 1;
int implicit_use = 0;
int global = 0;
if (!global_namespace)
{
/* This must be ::. */
my_friendly_assert (name == get_identifier ("::"), 377);
global = 1;
}
else if (!name)
{
/* The name of anonymous namespace is unique for the translation
unit. */
static tree anon_name = NULL_TREE;
if (!anon_name)
anon_name = get_file_function_name ('N');
name = anon_name;
d = IDENTIFIER_NAMESPACE_VALUE (name);
if (d)
/* Reopening anonymous namespace. */
need_new = 0;
implicit_use = 1;
}
else if (current_namespace == global_namespace
&& name == DECL_NAME (std_node))
{
in_std++;
return;
}
else
{
/* Check whether this is an extended namespace definition. */
d = IDENTIFIER_NAMESPACE_VALUE (name);
if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
{
need_new = 0;
if (DECL_NAMESPACE_ALIAS (d))
{
cp_error ("namespace alias `%D' not allowed here, assuming `%D'",
d, DECL_NAMESPACE_ALIAS (d));
d = DECL_NAMESPACE_ALIAS (d);
}
}
}
if (need_new)
{
/* Make a new namespace, binding the name to it. */
d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
/* The global namespace is not pushed, and the global binding
level is set elsewhere. */
if (!global)
{
d = pushdecl (d);
pushlevel (0);
declare_namespace_level ();
NAMESPACE_LEVEL (d) = current_binding_level;
}
}
else
resume_binding_level (NAMESPACE_LEVEL (d));
if (implicit_use)
do_using_directive (d);
/* Enter the name space. */
current_namespace = d;
}
/* Pop from the scope of the current namespace. */
void
pop_namespace ()
{
if (current_namespace == global_namespace)
{
my_friendly_assert (in_std>0, 980421);
in_std--;
return;
}
current_namespace = CP_DECL_CONTEXT (current_namespace);
/* The binding level is not popped, as it might be re-opened later. */
suspend_binding_level ();
}
/* Concatenate the binding levels of all namespaces. */
void
cat_namespace_levels()
{
tree current;
tree last;
struct binding_level *b;
last = NAMESPACE_LEVEL (global_namespace) -> names;
/* The nested namespaces appear in the names list of their ancestors. */
for (current = last; current; current = TREE_CHAIN (current))
{
if (TREE_CODE (current) != NAMESPACE_DECL
|| DECL_NAMESPACE_ALIAS (current))
continue;
if (!DECL_LANG_SPECIFIC (current))
{
/* Hmm. std. */
my_friendly_assert (current == std_node, 393);
continue;
}
b = NAMESPACE_LEVEL (current);
while (TREE_CHAIN (last))
last = TREE_CHAIN (last);
TREE_CHAIN (last) = NAMESPACE_LEVEL (current) -> names;
}
}
/* Subroutines for reverting temporarily to top-level for instantiation
of templates and such. We actually need to clear out the class- and
local-value slots of all identifiers, so that only the global values
are at all visible. Simply setting current_binding_level to the global
scope isn't enough, because more binding levels may be pushed. */
struct saved_scope {
struct binding_level *old_binding_level;
tree old_bindings;
tree old_namespace;
struct saved_scope *prev;
tree class_name, class_type, function_decl;
struct binding_level *class_bindings;
tree *lang_base, *lang_stack, lang_name;
int lang_stacksize;
int minimal_parse_mode;
tree last_function_parms;
tree template_parms;
HOST_WIDE_INT processing_template_decl;
tree previous_class_type, previous_class_values;
int processing_specialization;
int processing_explicit_instantiation;
};
static struct saved_scope *current_saved_scope;
/* A chain of the binding vecs created by store_bindings. We create a
whole bunch of these during compilation, on permanent_obstack, so we
can't just throw them away. */
static tree free_binding_vecs;
static tree
store_bindings (names, old_bindings)
tree names, old_bindings;
{
tree t;
for (t = names; t; t = TREE_CHAIN (t))
{
tree binding, t1, id;
if (TREE_CODE (t) == TREE_LIST)
id = TREE_PURPOSE (t);
else
id = DECL_NAME (t);
if (!id
|| (!IDENTIFIER_LOCAL_VALUE (id)
&& !IDENTIFIER_CLASS_VALUE (id)))
continue;
for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1))
if (TREE_VEC_ELT (t1, 0) == id)
goto skip_it;
if (free_binding_vecs)
{
binding = free_binding_vecs;
free_binding_vecs = TREE_CHAIN (free_binding_vecs);
}
else
binding = make_tree_vec (4);
if (id)
{
my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
TREE_VEC_ELT (binding, 0) = id;
TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
TREE_VEC_ELT (binding, 2) = IDENTIFIER_LOCAL_VALUE (id);
TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE;
IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
}
TREE_CHAIN (binding) = old_bindings;
old_bindings = binding;
skip_it:
;
}
return old_bindings;
}
void
maybe_push_to_top_level (pseudo)
int pseudo;
{
extern int current_lang_stacksize;
struct saved_scope *s
= (struct saved_scope *) xmalloc (sizeof (struct saved_scope));
struct binding_level *b = inner_binding_level;
tree old_bindings = NULL_TREE;
if (current_function_decl)
push_cp_function_context (NULL_TREE);
if (previous_class_type)
old_bindings = store_bindings (previous_class_values, old_bindings);
/* Have to include global_binding_level, because class-level decls
aren't listed anywhere useful. */
for (; b; b = b->level_chain)
{
tree t;
/* Template IDs are inserted into the global level. If they were
inserted into namespace level, finish_file wouldn't find them
when doing pending instantiations. Therefore, don't stop at
namespace level, but continue until :: . */
if (b == global_binding_level || (pseudo && b->pseudo_global))
break;
old_bindings = store_bindings (b->names, old_bindings);
/* We also need to check class_shadowed to save class-level type
bindings, since pushclass doesn't fill in b->names. */
if (b->parm_flag == 2)
old_bindings = store_bindings (b->class_shadowed, old_bindings);
/* Unwind type-value slots back to top level. */
for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
}
s->old_binding_level = current_binding_level;
current_binding_level = b;
s->old_namespace = current_namespace;
s->class_name = current_class_name;
s->class_type = current_class_type;
s->function_decl = current_function_decl;
s->class_bindings = class_binding_level;
s->lang_stack = current_lang_stack;
s->lang_base = current_lang_base;
s->lang_stacksize = current_lang_stacksize;
s->lang_name = current_lang_name;
s->minimal_parse_mode = minimal_parse_mode;
s->last_function_parms = last_function_parms;
s->template_parms = current_template_parms;
s->processing_template_decl = processing_template_decl;
s->previous_class_type = previous_class_type;
s->previous_class_values = previous_class_values;
s->processing_specialization = processing_specialization;
s->processing_explicit_instantiation = processing_explicit_instantiation;
current_class_name = current_class_type = NULL_TREE;
current_function_decl = NULL_TREE;
class_binding_level = (struct binding_level *)0;
current_lang_stacksize = 10;
current_lang_stack = current_lang_base
= (tree *) xmalloc (current_lang_stacksize * sizeof (tree));
current_lang_name = lang_name_cplusplus;
strict_prototype = strict_prototypes_lang_cplusplus;
named_labels = NULL_TREE;
shadowed_labels = NULL_TREE;
minimal_parse_mode = 0;
previous_class_type = previous_class_values = NULL_TREE;
processing_specialization = 0;
processing_explicit_instantiation = 0;
current_template_parms = NULL_TREE;
processing_template_decl = 0;
current_namespace = global_namespace;
s->prev = current_saved_scope;
s->old_bindings = old_bindings;
current_saved_scope = s;
push_obstacks (&permanent_obstack, &permanent_obstack);
}
void
push_to_top_level ()
{
maybe_push_to_top_level (0);
}
void
pop_from_top_level ()
{
extern int current_lang_stacksize;
struct saved_scope *s = current_saved_scope;
tree t;
/* Clear out class-level bindings cache. */
if (previous_class_type)
{
popclass (-1);
previous_class_type = NULL_TREE;
}
pop_obstacks ();
current_binding_level = s->old_binding_level;
current_saved_scope = s->prev;
for (t = s->old_bindings; t; )
{
tree save = t;
tree id = TREE_VEC_ELT (t, 0);
if (id)
{
SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
IDENTIFIER_LOCAL_VALUE (id) = TREE_VEC_ELT (t, 2);
IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
}
t = TREE_CHAIN (t);
TREE_CHAIN (save) = free_binding_vecs;
free_binding_vecs = save;
}
current_namespace = s->old_namespace;
current_class_name = s->class_name;
current_class_type = s->class_type;
current_function_decl = s->function_decl;
class_binding_level = s->class_bindings;
free (current_lang_base);
current_lang_base = s->lang_base;
current_lang_stack = s->lang_stack;
current_lang_name = s->lang_name;
current_lang_stacksize = s->lang_stacksize;
if (current_lang_name == lang_name_cplusplus)
strict_prototype = strict_prototypes_lang_cplusplus;
else if (current_lang_name == lang_name_c)
strict_prototype = strict_prototypes_lang_c;
minimal_parse_mode = s->minimal_parse_mode;
last_function_parms = s->last_function_parms;
current_template_parms = s->template_parms;
processing_template_decl = s->processing_template_decl;
previous_class_type = s->previous_class_type;
previous_class_values = s->previous_class_values;
processing_specialization = s->processing_specialization;
processing_explicit_instantiation = s->processing_explicit_instantiation;
free (s);
if (current_function_decl)
pop_cp_function_context (NULL_TREE);
}
/* Push a definition of struct, union or enum tag "name".
into binding_level "b". "type" should be the type node,
We assume that the tag "name" is not already defined.
Note that the definition may really be just a forward reference.
In that case, the TYPE_SIZE will be a NULL_TREE.
C++ gratuitously puts all these tags in the name space. */
/* When setting the IDENTIFIER_TYPE_VALUE field of an identifier ID,
record the shadowed value for this binding contour. TYPE is
the type that ID maps to. */
static void
set_identifier_type_value_with_scope (id, type, b)
tree id;
tree type;
struct binding_level *b;
{
if (!b->namespace_p)
{
/* Shadow the marker, not the real thing, so that the marker
gets restored later. */
tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
b->type_shadowed
= tree_cons (id, old_type_value, b->type_shadowed);
}
else
{
tree binding = binding_for_name (id, current_namespace);
BINDING_TYPE (binding) = type;
/* Store marker instead of real type. */
type = global_type_node;
}
SET_IDENTIFIER_TYPE_VALUE (id, type);
}
/* As set_identifier_type_value_with_scope, but using inner_binding_level. */
void
set_identifier_type_value (id, type)
tree id;
tree type;
{
set_identifier_type_value_with_scope (id, type, inner_binding_level);
}
static void
set_identifier_local_value_with_scope (id, val, b)
tree id, val;
struct binding_level *b;
{
tree oldlocal;
my_friendly_assert (! b->namespace_p, 980716);
oldlocal = IDENTIFIER_LOCAL_VALUE (id);
b->shadowed = tree_cons (id, oldlocal, b->shadowed);
IDENTIFIER_LOCAL_VALUE (id) = val;
}
void
set_identifier_local_value (id, val)
tree id, val;
{
set_identifier_local_value_with_scope (id, val, current_binding_level);
}
/* Return the type associated with id. */
tree
identifier_type_value (id)
tree id;
{
/* There is no type with that name, anywhere. */
if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
return NULL_TREE;
/* This is not the type marker, but the real thing. */
if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
return REAL_IDENTIFIER_TYPE_VALUE (id);
/* Have to search for it. It must be on the global level, now.
Ask lookup_name not to return non-types. */
id = lookup_name_real (id, 2, 1, 0);
if (id)
return TREE_TYPE (id);
return NULL_TREE;
}
/* Pop off extraneous binding levels left over due to syntax errors.
We don't pop past namespaces, as they might be valid. */
void
pop_everything ()
{
#ifdef DEBUG_CP_BINDING_LEVELS
fprintf (stderr, "XXX entering pop_everything ()\n");
#endif
while (! toplevel_bindings_p () && ! pseudo_global_level_p ())
{
if (class_binding_level)
pop_nested_class (1);
else
poplevel (0, 0, 0);
}
#ifdef DEBUG_CP_BINDING_LEVELS
fprintf (stderr, "XXX leaving pop_everything ()\n");
#endif
}
/* Push a tag name NAME for struct/class/union/enum type TYPE.
Normally put it into the inner-most non-tag-transparent scope,
but if GLOBALIZE is true, put it in the inner-most non-class scope.
The latter is needed for implicit declarations. */
void
pushtag (name, type, globalize)
tree name, type;
int globalize;
{
register struct binding_level *b;
tree context = 0;
tree c_decl = 0;
b = inner_binding_level;
while (b->tag_transparent
|| (globalize && b->parm_flag == 2))
b = b->level_chain;
if (toplevel_bindings_p ())
b->tags = perm_tree_cons (name, type, b->tags);
else
b->tags = saveable_tree_cons (name, type, b->tags);
if (name)
{
context = type ? TYPE_CONTEXT (type) : NULL_TREE;
if (! context)
{
tree cs = current_scope ();
if (! globalize)
context = cs;
else if (cs != NULL_TREE
&& TREE_CODE_CLASS (TREE_CODE (cs)) == 't')
/* When declaring a friend class of a local class, we want
to inject the newly named class into the scope
containing the local class, not the namespace scope. */
context = hack_decl_function_context (get_type_decl (cs));
}
if (context)
c_decl = TREE_CODE (context) == FUNCTION_DECL
? context : TYPE_MAIN_DECL (context);
if (!context)
context = current_namespace;
/* Do C++ gratuitous typedefing. */
if (IDENTIFIER_TYPE_VALUE (name) != type)
{
register tree d = NULL_TREE;
int newdecl = 0, in_class = 0;
if ((b->pseudo_global && b->level_chain->parm_flag == 2)
|| b->parm_flag == 2)
in_class = 1;
else
d = lookup_nested_type (type, c_decl);
if (d == NULL_TREE)
{
newdecl = 1;
d = build_decl (TYPE_DECL, name, type);
if (current_lang_name == lang_name_java)
TYPE_FOR_JAVA (type) = 1;
SET_DECL_ARTIFICIAL (d);
if (! in_class)
set_identifier_type_value_with_scope (name, type, b);
}
else
d = TYPE_MAIN_DECL (d);
TYPE_NAME (type) = d;
DECL_CONTEXT (d) = FROB_CONTEXT (context);
if (processing_template_parmlist)
/* You can't declare a new template type in a template
parameter list. But, you can declare a non-template
type:
template <class A*> struct S;
is a forward-declaration of `A'. */
;
else if (IS_AGGR_TYPE (type)
&& (/* If !GLOBALIZE then we are looking at a
definition. It may not be a primary template.
(For example, in:
template <class T>
struct S1 { class S2 {}; }
we have to push_template_decl for S2.) */
(processing_template_decl && !globalize)
/* If we are declaring a friend template class, we
will have GLOBALIZE set, since something like:
template <class T>
struct S1 {
template <class U>
friend class S2;
};
declares S2 to be at global scope. */
|| (processing_template_decl >
template_class_depth (current_class_type))))
{
d = push_template_decl_real (d, globalize);
/* If the current binding level is the binding level for
the template parameters (see the comment in
begin_template_parm_list) and the enclosing level is
a class scope, and we're not looking at a friend,
push the declaration of the member class into the
class scope. In the friend case, push_template_decl
will already have put the friend into global scope,
if appropriate. */
if (!globalize && b->pseudo_global &&
b->level_chain->parm_flag == 2)
{
pushdecl_with_scope (CLASSTYPE_TI_TEMPLATE (type),
b->level_chain);
/* Put this tag on the list of tags for the class,
since that won't happen below because B is not
the class binding level, but is instead the
pseudo-global level. */
b->level_chain->tags =
saveable_tree_cons (name, type, b->level_chain->tags);
TREE_NONLOCAL_FLAG (type) = 1;
if (TYPE_SIZE (current_class_type) == NULL_TREE)
CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
}
}
if (b->parm_flag == 2)
d = pushdecl_class_level (d);
else
d = pushdecl_with_scope (d, b);
if (newdecl)
{
if (ANON_AGGRNAME_P (name))
DECL_IGNORED_P (d) = 1;
TYPE_CONTEXT (type) = DECL_CONTEXT (d);
DECL_ASSEMBLER_NAME (d) = DECL_NAME (d);
DECL_ASSEMBLER_NAME (d)
= get_identifier (build_overload_name (type, 1, 1));
}
}
if (b->parm_flag == 2)
{
TREE_NONLOCAL_FLAG (type) = 1;
if (TYPE_SIZE (current_class_type) == NULL_TREE)
CLASSTYPE_TAGS (current_class_type) = b->tags;
}
}
if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
/* Use the canonical TYPE_DECL for this node. */
TYPE_STUB_DECL (type) = TYPE_NAME (type);
else
{
/* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE
will be the tagged type we just added to the current
binding level. This fake NULL-named TYPE_DECL node helps
dwarfout.c to know when it needs to output a
representation of a tagged type, and it also gives us a
convenient place to record the "scope start" address for
the tagged type. */
tree d = build_decl (TYPE_DECL, NULL_TREE, type);
TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
}
}
/* Counter used to create anonymous type names. */
static int anon_cnt = 0;
/* Return an IDENTIFIER which can be used as a name for
anonymous structs and unions. */
tree
make_anon_name ()
{
char buf[32];
sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++);
return get_identifier (buf);
}
/* Clear the TREE_PURPOSE slot of tags which have anonymous typenames.
This keeps dbxout from getting confused. */
void
clear_anon_tags ()
{
register struct binding_level *b;
register tree tags;
static int last_cnt = 0;
/* Fast out if no new anon names were declared. */
if (last_cnt == anon_cnt)
return;
b = current_binding_level;
while (b->tag_transparent)
b = b->level_chain;
tags = b->tags;
while (tags)
{
/* A NULL purpose means we have already processed all tags
from here to the end of the list. */
if (TREE_PURPOSE (tags) == NULL_TREE)
break;
if (ANON_AGGRNAME_P (TREE_PURPOSE (tags)))
TREE_PURPOSE (tags) = NULL_TREE;
tags = TREE_CHAIN (tags);
}
last_cnt = anon_cnt;
}
/* Subroutine of duplicate_decls: return truthvalue of whether
or not types of these decls match.
For C++, we must compare the parameter list so that `int' can match
`int&' in a parameter position, but `int&' is not confused with
`const int&'. */
int
decls_match (newdecl, olddecl)
tree newdecl, olddecl;
{
int types_match;
if (TREE_CODE (newdecl) == FUNCTION_DECL
&& TREE_CODE (olddecl) == FUNCTION_DECL)
{
tree f1 = TREE_TYPE (newdecl);
tree f2 = TREE_TYPE (olddecl);
tree p1 = TYPE_ARG_TYPES (f1);
tree p2 = TYPE_ARG_TYPES (f2);
if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl)
&& ! (DECL_LANGUAGE (newdecl) == lang_c
&& DECL_LANGUAGE (olddecl) == lang_c))
return 0;
/* When we parse a static member function definition,
we put together a FUNCTION_DECL which thinks its type
is METHOD_TYPE. Change that to FUNCTION_TYPE, and
proceed. */
if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl))
revert_static_member_fn (&newdecl, &f1, &p1);
else if (TREE_CODE (f2) == METHOD_TYPE
&& DECL_STATIC_FUNCTION_P (newdecl))
revert_static_member_fn (&olddecl, &f2, &p2);
/* Here we must take care of the case where new default
parameters are specified. Also, warn if an old
declaration becomes ambiguous because default
parameters may cause the two to be ambiguous. */
if (TREE_CODE (f1) != TREE_CODE (f2))
{
if (TREE_CODE (f1) == OFFSET_TYPE)
cp_compiler_error ("`%D' redeclared as member function", newdecl);
else
cp_compiler_error ("`%D' redeclared as non-member function", newdecl);
return 0;
}
if (comptypes (TREE_TYPE (f1), TREE_TYPE (f2), 1))
{
if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c
&& p2 == NULL_TREE)
{
types_match = self_promoting_args_p (p1);
if (p1 == void_list_node)
TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
}
else if (!strict_prototypes_lang_c && DECL_LANGUAGE (olddecl)==lang_c
&& DECL_LANGUAGE (newdecl) == lang_c && p1 == NULL_TREE)
{
types_match = self_promoting_args_p (p2);
TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
}
else
types_match = compparms (p1, p2, 3);
}
else
types_match = 0;
}
else if (TREE_CODE (newdecl) == TEMPLATE_DECL
&& TREE_CODE (olddecl) == TEMPLATE_DECL)
{
if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
DECL_TEMPLATE_PARMS (olddecl)))
return 0;
if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
types_match = 1;
else
types_match = decls_match (DECL_TEMPLATE_RESULT (olddecl),
DECL_TEMPLATE_RESULT (newdecl));
}
else
{
if (TREE_TYPE (newdecl) == error_mark_node)
types_match = TREE_TYPE (olddecl) == error_mark_node;
else if (TREE_TYPE (olddecl) == NULL_TREE)
types_match = TREE_TYPE (newdecl) == NULL_TREE;
else if (TREE_TYPE (newdecl) == NULL_TREE)
types_match = 0;
/* Qualifiers must match, and they may be present on either, the type
or the decl. */
else if ((TREE_READONLY (newdecl)
|| TYPE_READONLY (TREE_TYPE (newdecl)))
== (TREE_READONLY (olddecl)
|| TYPE_READONLY (TREE_TYPE (olddecl)))
&& (TREE_THIS_VOLATILE (newdecl)
|| TYPE_VOLATILE (TREE_TYPE (newdecl)))
== (TREE_THIS_VOLATILE (olddecl)
|| TYPE_VOLATILE (TREE_TYPE (olddecl))))
types_match = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (newdecl)),
TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)), 1);
else
types_match = 0;
}
return types_match;
}
/* If NEWDECL is `static' and an `extern' was seen previously,
warn about it. (OLDDECL may be NULL_TREE; NAME contains
information about previous usage as an `extern'.)
Note that this does not apply to the C++ case of declaring
a variable `extern const' and then later `const'.
Don't complain about built-in functions, since they are beyond
the user's control. */
static void
warn_extern_redeclared_static (newdecl, olddecl)
tree newdecl, olddecl;
{
tree name;
static char *explicit_extern_static_warning
= "`%D' was declared `extern' and later `static'";
static char *implicit_extern_static_warning
= "`%D' was declared implicitly `extern' and later `static'";
if (TREE_CODE (newdecl) == TYPE_DECL)
return;
name = DECL_ASSEMBLER_NAME (newdecl);
if (TREE_PUBLIC (name) && DECL_THIS_STATIC (newdecl))
{
/* It's okay to redeclare an ANSI built-in function as static,
or to declare a non-ANSI built-in function as anything. */
if (! (TREE_CODE (newdecl) == FUNCTION_DECL
&& olddecl != NULL_TREE
&& TREE_CODE (olddecl) == FUNCTION_DECL
&& (DECL_BUILT_IN (olddecl)
|| DECL_BUILT_IN_NONANSI (olddecl))))
{
cp_pedwarn (IDENTIFIER_IMPLICIT_DECL (name)
? implicit_extern_static_warning
: explicit_extern_static_warning, newdecl);
if (olddecl != NULL_TREE)
cp_pedwarn_at ("previous declaration of `%D'", olddecl);
}
}
}
/* Handle when a new declaration NEWDECL has the same name as an old
one OLDDECL in the same binding contour. Prints an error message
if appropriate.
If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
Otherwise, return 0. */
int
duplicate_decls (newdecl, olddecl)
tree newdecl, olddecl;
{
extern struct obstack permanent_obstack;
unsigned olddecl_uid = DECL_UID (olddecl);
int olddecl_friend = 0, types_match = 0;
int new_defines_function = 0;
if (newdecl == olddecl)
return 1;
types_match = decls_match (newdecl, olddecl);
/* If either the type of the new decl or the type of the old decl is an
error_mark_node, then that implies that we have already issued an
error (earlier) for some bogus type specification, and in that case,
it is rather pointless to harass the user with yet more error message
about the same declaration, so just pretend the types match here. */
if (TREE_TYPE (newdecl) == error_mark_node
|| TREE_TYPE (olddecl) == error_mark_node)
types_match = 1;
/* Check for redeclaration and other discrepancies. */
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_ARTIFICIAL (olddecl)
&& (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)))
{
/* If you declare a built-in or predefined function name as static,
the old definition is overridden, but optionally warn this was a
bad choice of name. Ditto for overloads. */
if (! TREE_PUBLIC (newdecl)
|| (TREE_CODE (newdecl) == FUNCTION_DECL
&& DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)))
{
if (warn_shadow)
cp_warning ("shadowing %s function `%#D'",
DECL_BUILT_IN (olddecl) ? "built-in" : "library",
olddecl);
/* Discard the old built-in function. */
return 0;
}
else if (! types_match)
{
if (TREE_CODE (newdecl) != FUNCTION_DECL)
{
/* If the built-in is not ansi, then programs can override
it even globally without an error. */
if (! DECL_BUILT_IN (olddecl))
cp_warning ("library function `%#D' redeclared as non-function `%#D'",
olddecl, newdecl);
else
{
cp_error ("declaration of `%#D'", newdecl);
cp_error ("conflicts with built-in declaration `%#D'",
olddecl);
}
return 0;
}
cp_warning ("declaration of `%#D'", newdecl);
cp_warning ("conflicts with built-in declaration `%#D'",
olddecl);
}
}
else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
{
if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl)
&& TREE_CODE (newdecl) != TYPE_DECL
&& ! (TREE_CODE (newdecl) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL))
|| (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl)
&& TREE_CODE (olddecl) != TYPE_DECL
&& ! (TREE_CODE (olddecl) == TEMPLATE_DECL
&& (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
== TYPE_DECL))))
{
/* We do nothing special here, because C++ does such nasty
things with TYPE_DECLs. Instead, just let the TYPE_DECL
get shadowed, and know that if we need to find a TYPE_DECL
for a given name, we can look in the IDENTIFIER_TYPE_VALUE
slot of the identifier. */
return 0;
}
if ((TREE_CODE (newdecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (olddecl))
|| (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (newdecl)))
return 0;
cp_error ("`%#D' redeclared as different kind of symbol", newdecl);
if (TREE_CODE (olddecl) == TREE_LIST)
olddecl = TREE_VALUE (olddecl);
cp_error_at ("previous declaration of `%#D'", olddecl);
/* New decl is completely inconsistent with the old one =>
tell caller to replace the old one. */
return 0;
}
else if (!types_match)
{
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
/* The name of a class template may not be declared to refer to
any other template, class, function, object, namespace, value,
or type in the same scope. */
if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == TYPE_DECL
|| TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
{
cp_error ("declaration of template `%#D'", newdecl);
cp_error_at ("conflicts with previous declaration `%#D'",
olddecl);
}
else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))), 3)
&& comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
DECL_TEMPLATE_PARMS (olddecl)))
{
cp_error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
}
return 0;
}
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
if (DECL_LANGUAGE (newdecl) == lang_c
&& DECL_LANGUAGE (olddecl) == lang_c)
{
cp_error ("declaration of C function `%#D' conflicts with",
newdecl);
cp_error_at ("previous declaration `%#D' here", olddecl);
}
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 3))
{
cp_error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
}
else
return 0;
}
/* Already complained about this, so don't do so again. */
else if (current_class_type == NULL_TREE
|| IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)
{
cp_error ("conflicting types for `%#D'", newdecl);
cp_error_at ("previous declaration as `%#D'", olddecl);
}
}
else if (TREE_CODE (newdecl) == FUNCTION_DECL
&& ((DECL_TEMPLATE_SPECIALIZATION (olddecl)
&& (!DECL_TEMPLATE_INFO (newdecl)
|| (DECL_TI_TEMPLATE (newdecl)
!= DECL_TI_TEMPLATE (olddecl))))
|| (DECL_TEMPLATE_SPECIALIZATION (newdecl)
&& (!DECL_TEMPLATE_INFO (olddecl)
|| (DECL_TI_TEMPLATE (olddecl)
!= DECL_TI_TEMPLATE (newdecl))))))
/* It's OK to have a template specialization and a non-template
with the same type, or to have specializations of two
different templates with the same type. Note that if one is a
specialization, and the other is an instantiation of the same
template, that we do not exit at this point. That situation
can occur if we instantiate a template class, and then
specialize one of its methods. This situation is legal, but
the declarations must be merged in the usual way. */
return 0;
else if (TREE_CODE (newdecl) == FUNCTION_DECL
&& ((DECL_TEMPLATE_INSTANTIATION (olddecl)
&& !DECL_USE_TEMPLATE (newdecl))
|| (DECL_TEMPLATE_INSTANTIATION (newdecl)
&& !DECL_USE_TEMPLATE (olddecl))))
/* One of the declarations is a template instantiation, and the
other is not a template at all. That's OK. */
return 0;
else if (TREE_CODE (newdecl) == NAMESPACE_DECL
&& DECL_NAMESPACE_ALIAS (newdecl)
&& DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl))
/* Redeclaration of namespace alias, ignore it. */
return 1;
else
{
char *errmsg = redeclaration_error_message (newdecl, olddecl);
if (errmsg)
{
cp_error (errmsg, newdecl);
if (DECL_NAME (olddecl) != NULL_TREE)
cp_error_at ((DECL_INITIAL (olddecl)
&& namespace_bindings_p ())
? "`%#D' previously defined here"
: "`%#D' previously declared here", olddecl);
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_INITIAL (olddecl) != NULL_TREE
&& TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == NULL_TREE
&& TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != NULL_TREE)
{
/* Prototype decl follows defn w/o prototype. */
cp_warning_at ("prototype for `%#D'", newdecl);
cp_warning_at ("follows non-prototype definition here", olddecl);
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
{
/* extern "C" int foo ();
int foo () { bar (); }
is OK. */
if (current_lang_stack == current_lang_base)
DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl);
else
{
cp_error_at ("previous declaration of `%#D' with %L linkage",
olddecl, DECL_LANGUAGE (olddecl));
cp_error ("conflicts with new declaration with %L linkage",
DECL_LANGUAGE (newdecl));
}
}
if (DECL_LANG_SPECIFIC (olddecl) && DECL_USE_TEMPLATE (olddecl))
;
else if (TREE_CODE (olddecl) == FUNCTION_DECL)
{
tree t1 = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
tree t2 = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
int i = 1;
if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE)
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2);
for (; t1 && t1 != void_list_node;
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++)
if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
{
if (1 == simple_cst_equal (TREE_PURPOSE (t1),
TREE_PURPOSE (t2)))
{
if (pedantic)
{
cp_pedwarn ("default argument given for parameter %d of `%#D'",
i, newdecl);
cp_pedwarn_at ("after previous specification in `%#D'",
olddecl);
}
}
else
{
cp_error ("default argument given for parameter %d of `%#D'",
i, newdecl);
cp_error_at ("after previous specification in `%#D'",
olddecl);
}
}
if (DECL_THIS_INLINE (newdecl) && ! DECL_THIS_INLINE (olddecl)
&& TREE_ADDRESSABLE (olddecl) && warn_inline)
{
cp_warning ("`%#D' was used before it was declared inline",
newdecl);
cp_warning_at ("previous non-inline declaration here",
olddecl);
}
}
/* These bits are logically part of the type for non-functions. */
else if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
|| TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))
{
cp_pedwarn ("type qualifiers for `%#D'", newdecl);
cp_pedwarn_at ("conflict with previous decl `%#D'", olddecl);
}
}
/* If new decl is `static' and an `extern' was seen previously,
warn about it. */
warn_extern_redeclared_static (newdecl, olddecl);
/* We have committed to returning 1 at this point. */
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
/* Now that functions must hold information normally held
by field decls, there is extra work to do so that
declaration information does not get destroyed during
definition. */
if (DECL_VINDEX (olddecl))
DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl);
if (DECL_CONTEXT (olddecl))
DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
if (DECL_CLASS_CONTEXT (olddecl))
DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl);
if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0)
DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);
DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl);
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl);
DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
/* Optionally warn about more than one declaration for the same
name, but don't warn about a function declaration followed by a
definition. */
if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl)
&& !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
/* Don't warn about extern decl followed by definition. */
&& !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))
/* Don't warn about friends, let add_friend take care of it. */
&& ! DECL_FRIEND_P (newdecl))
{
cp_warning ("redundant redeclaration of `%D' in same scope", newdecl);
cp_warning_at ("previous declaration of `%D'", olddecl);
}
}
/* Deal with C++: must preserve virtual function table size. */
if (TREE_CODE (olddecl) == TYPE_DECL)
{
register tree newtype = TREE_TYPE (newdecl);
register tree oldtype = TREE_TYPE (olddecl);
if (newtype != error_mark_node && oldtype != error_mark_node
&& TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype))
{
CLASSTYPE_VSIZE (newtype) = CLASSTYPE_VSIZE (oldtype);
CLASSTYPE_FRIEND_CLASSES (newtype)
= CLASSTYPE_FRIEND_CLASSES (oldtype);
}
}
/* Copy all the DECL_... slots specified in the new decl
except for any that we copy here from the old type. */
DECL_MACHINE_ATTRIBUTES (newdecl)
= merge_machine_decl_attributes (olddecl, newdecl);
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
if (DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)) == NULL_TREE)
{
if (! duplicate_decls (DECL_TEMPLATE_RESULT (newdecl),
DECL_TEMPLATE_RESULT (olddecl)))
cp_error ("invalid redeclaration of %D", newdecl);
TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl));
DECL_TEMPLATE_PARMS (olddecl) = DECL_TEMPLATE_PARMS (newdecl);
DECL_TEMPLATE_INFO (olddecl) = DECL_TEMPLATE_INFO (newdecl);
}
DECL_TEMPLATE_SPECIALIZATIONS (newdecl)
= DECL_TEMPLATE_SPECIALIZATIONS (olddecl);
return 1;
}
if (types_match)
{
/* Automatically handles default parameters. */
tree oldtype = TREE_TYPE (olddecl);
tree newtype;
/* Make sure we put the new type in the same obstack as the old one. */
if (oldtype)
push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
else
{
push_obstacks_nochange ();
end_temporary_allocation ();
}
/* Merge the data types specified in the two decls. */
newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
if (TREE_CODE (newdecl) == VAR_DECL)
DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
/* Do this after calling `common_type' so that default
parameters don't confuse us. */
else if (TREE_CODE (newdecl) == FUNCTION_DECL
&& (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl))
!= TYPE_RAISES_EXCEPTIONS (TREE_TYPE (olddecl))))
{
TREE_TYPE (newdecl) = build_exception_variant (newtype,
TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl)));
TREE_TYPE (olddecl) = build_exception_variant (newtype,
TYPE_RAISES_EXCEPTIONS (oldtype));
if ((pedantic || ! DECL_IN_SYSTEM_HEADER (olddecl))
&& DECL_SOURCE_LINE (olddecl) != 0
&& flag_exceptions
&& ! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
{
cp_pedwarn ("declaration of `%D' throws different exceptions",
newdecl);
cp_pedwarn_at ("previous declaration here", olddecl);
}
}
TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
/* Lay the type out, unless already done. */
if (newtype != canonical_type_variant (oldtype)
&& TREE_TYPE (newdecl) != error_mark_node
&& !(processing_template_decl && uses_template_parms (newdecl)))
layout_type (TREE_TYPE (newdecl));
if ((TREE_CODE (newdecl) == VAR_DECL
|| TREE_CODE (newdecl) == PARM_DECL
|| TREE_CODE (newdecl) == RESULT_DECL
|| TREE_CODE (newdecl) == FIELD_DECL
|| TREE_CODE (newdecl) == TYPE_DECL)
&& !(processing_template_decl && uses_template_parms (newdecl)))
layout_decl (newdecl, 0);
/* Merge the type qualifiers. */
if (TREE_READONLY (newdecl))
TREE_READONLY (olddecl) = 1;
if (TREE_THIS_VOLATILE (newdecl))
TREE_THIS_VOLATILE (olddecl) = 1;
/* Merge the initialization information. */
if (DECL_INITIAL (newdecl) == NULL_TREE
&& DECL_INITIAL (olddecl) != NULL_TREE)
{
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
}
/* Merge the section attribute.
We want to issue an error if the sections conflict but that must be
done later in decl_attributes since we are called before attributes
are assigned. */
if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
/* Keep the old rtl since we can safely use it, unless it's the
call to abort() used for abstract virtuals. */
if ((DECL_LANG_SPECIFIC (olddecl)
&& !DECL_ABSTRACT_VIRTUAL_P (olddecl))
|| DECL_RTL (olddecl) != DECL_RTL (abort_fndecl))
DECL_RTL (newdecl) = DECL_RTL (olddecl);
pop_obstacks ();
}
/* If cannot merge, then use the new type and qualifiers,
and don't preserve the old rtl. */
else
{
/* Clean out any memory we had of the old declaration. */
tree oldstatic = value_member (olddecl, static_aggregates);
if (oldstatic)
TREE_VALUE (oldstatic) = error_mark_node;
TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
}
/* Merge the storage class information. */
DECL_WEAK (newdecl) |= DECL_WEAK (olddecl);
DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl);
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl);
if (! DECL_EXTERNAL (olddecl))
DECL_EXTERNAL (newdecl) = 0;
if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
{
DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
/* Don't really know how much of the language-specific
values we should copy from old to new. */
DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
if (DECL_TEMPLATE_INFO (newdecl) == NULL_TREE)
{
DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);
}
olddecl_friend = DECL_FRIEND_P (olddecl);
}
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
if (DECL_TEMPLATE_INSTANTIATION (olddecl)
&& !DECL_TEMPLATE_INSTANTIATION (newdecl))
{
/* If newdecl is not a specialization, then it is not a
template-related function at all. And that means that we
shoud have exited above, returning 0. */
my_friendly_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl),
0);
if (TREE_USED (olddecl))
/* From [temp.expl.spec]:
If a template, a member template or the member of a class
template is explicitly specialized then that
specialization shall be declared before the first use of
that specialization that would cause an implicit
instantiation to take place, in every translation unit in
which such a use occurs. */
cp_error ("explicit specialization of %D after first use",
olddecl);
SET_DECL_TEMPLATE_SPECIALIZATION (olddecl);
}
DECL_THIS_INLINE (newdecl) |= DECL_THIS_INLINE (olddecl);
/* If either decl says `inline', this fn is inline, unless its
definition was passed already. */
if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE)
DECL_INLINE (olddecl) = 1;
DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
if (! types_match)
{
DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
DECL_ASSEMBLER_NAME (olddecl) = DECL_ASSEMBLER_NAME (newdecl);
DECL_RTL (olddecl) = DECL_RTL (newdecl);
}
if (! types_match || new_defines_function)
{
/* These need to be copied so that the names are available. */
DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
}
if (new_defines_function)
/* If defining a function declared with other language
linkage, use the previously declared language linkage. */
DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl);
else
{
/* If redeclaring a builtin function, and not a definition,
it stays built in. */
if (DECL_BUILT_IN (olddecl))
{
DECL_BUILT_IN (newdecl) = 1;
DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
/* If we're keeping the built-in definition, keep the rtl,
regardless of declaration matches. */
DECL_RTL (newdecl) = DECL_RTL (olddecl);
}
else
DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
if ((DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl)))
/* Previously saved insns go together with
the function's previous definition. */
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
/* Don't clear out the arguments if we're redefining a function. */
if (DECL_ARGUMENTS (olddecl))
DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
}
if (DECL_LANG_SPECIFIC (olddecl))
DECL_MAIN_VARIANT (newdecl) = DECL_MAIN_VARIANT (olddecl);
}
if (TREE_CODE (newdecl) == NAMESPACE_DECL)
{
NAMESPACE_LEVEL (newdecl) = NAMESPACE_LEVEL (olddecl);
}
/* Now preserve various other info from the definition. */
TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl);
TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl);
DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
DECL_ASSEMBLER_NAME (newdecl) = DECL_ASSEMBLER_NAME (olddecl);
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
int function_size;
struct lang_decl *ol = DECL_LANG_SPECIFIC (olddecl);
struct lang_decl *nl = DECL_LANG_SPECIFIC (newdecl);
function_size = sizeof (struct tree_decl);
bcopy ((char *) newdecl + sizeof (struct tree_common),
(char *) olddecl + sizeof (struct tree_common),
function_size - sizeof (struct tree_common));
/* Can we safely free the storage used by newdecl? */
#define ROUND(x) ((x + obstack_alignment_mask (&permanent_obstack)) \
& ~ obstack_alignment_mask (&permanent_obstack))
if (DECL_TEMPLATE_INSTANTIATION (newdecl))
{
/* If newdecl is a template instantiation, it is possible that
the following sequence of events has occurred:
o A friend function was declared in a class template. The
class template was instantiated.
o The instantiation of the friend declaration was
recorded on the instantiation list, and is newdecl.
o Later, however, instantiate_class_template called pushdecl
on the newdecl to perform name injection. But, pushdecl in
turn called duplicate_decls when it discovered that another
declaration of a global function with the same name already
existed.
o Here, in duplicate_decls, we decided to clobber newdecl.
If we're going to do that, we'd better make sure that
olddecl, and not newdecl, is on the list of
instantiations so that if we try to do the instantiation
again we won't get the clobbered declaration. */
tree tmpl = DECL_TI_TEMPLATE (newdecl);
tree decls = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
for (; decls; decls = TREE_CHAIN (decls))
if (TREE_VALUE (decls) == newdecl)
TREE_VALUE (decls) = olddecl;
}
if (((char *)newdecl + ROUND (function_size) == (char *)nl
&& ((char *)newdecl + ROUND (function_size)
+ ROUND (sizeof (struct lang_decl))
== obstack_next_free (&permanent_obstack)))
|| ((char *)newdecl + ROUND (function_size)
== obstack_next_free (&permanent_obstack)))
{
DECL_MAIN_VARIANT (newdecl) = olddecl;
DECL_LANG_SPECIFIC (olddecl) = ol;
bcopy ((char *)nl, (char *)ol, sizeof (struct lang_decl));
obstack_free (&permanent_obstack, newdecl);
}
else if (LANG_DECL_PERMANENT (ol) && ol != nl)
{
if (DECL_MAIN_VARIANT (olddecl) == olddecl)
{
/* Save these lang_decls that would otherwise be lost. */
extern tree free_lang_decl_chain;
tree free_lang_decl = (tree) ol;
if (DECL_LANG_SPECIFIC (olddecl) == ol)
abort ();
TREE_CHAIN (free_lang_decl) = free_lang_decl_chain;
free_lang_decl_chain = free_lang_decl;
}
else
{
/* Storage leak. */;
}
}
}
else
{
bcopy ((char *) newdecl + sizeof (struct tree_common),
(char *) olddecl + sizeof (struct tree_common),
sizeof (struct tree_decl) - sizeof (struct tree_common)
+ tree_code_length [(int)TREE_CODE (newdecl)] * sizeof (char *));
}
DECL_UID (olddecl) = olddecl_uid;
if (olddecl_friend)
DECL_FRIEND_P (olddecl) = 1;
/* NEWDECL contains the merged attribute lists.
Update OLDDECL to be the same. */
DECL_MACHINE_ATTRIBUTES (olddecl) = DECL_MACHINE_ATTRIBUTES (newdecl);
return 1;
}
/* Record a decl-node X as belonging to the current lexical scope.
Check for errors (such as an incompatible declaration for the same
name already seen in the same scope).
Returns either X or an old decl for the same name.
I