cp-tree.h (struct lang_decl): Overhaul.
* cp-tree.h (struct lang_decl): Overhaul. (struct lang_decl_flags): Remove. (struct lang_decl_base): New. (struct lang_decl_min): New. (struct lang_decl_fn): New. (struct lang_decl_ns): New. (CAN_HAVE_FULL_LANG_DECL_P): Replace with LANG_DECL_HAS_MIN. (LANG_DECL_MIN_CHECK): New. (LANG_DECL_FN_CHECK): New. (LANG_DECL_NS_CHECK): New. (STRIP_TEMPLATE): New. (NON_THUNK_FUNCTION_CHECK): Remove. (DECL_DECLARES_FUNCTION_P): New. (lots): Adjust. * lex.c (retrofit_lang_decl, cxx_dup_lang_specific_decl): Adjust. * decl.c (push_local_name, duplicate_decls): Adjust. * decl2.c (start_objects): Don't set u2sel. * semantics.c (finish_omp_threadprivate): Adjust. * class.c (build_clone): Don't do much on TEMPLATE_DECLs. (decl_cloned_function_p): Out-of-line implementation of macros. (clone_function_decl, adjust_clone_args): Use DECL_CLONED_FUNCTION_P. * mangle.c (write_unqualified_name): Don't check function flags on non-functions. * method.c (make_alias_for): Don't set DECL_CLONED_FUNCTION. * pt.c (build_template_decl): Don't set function flags. (check_default_tmpl_args): Check that it's a function. (instantiate_template): Use DECL_ABSTRACT_ORIGIN to find the cloned template. * pt.c (tsubst_decl) [FUNCTION_DECL]: Don't tsubst DECL_CLONED_FUNCTION. * cp-tree.h (struct lang_type_class): Move sorted_fields here. * class.c (finish_struct_1): Adjust. * ptree.c (cxx_print_decl, cxx_print_type): Adjust. * search.c (lookup_field_1): Adjust. * cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Remove. * decl.c (finish_method): Don't add to it. * class.c (fixup_pending_inline): Remove. (fixup_inline_methods): Remove. (finish_struct_1): Don't call it. * error.c (dump_function_name): Handle null name. From-SVN: r149217
This commit is contained in:
parent
07302a1bb6
commit
b97e8a149d
|
@ -1,3 +1,50 @@
|
|||
2009-07-03 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cp-tree.h (struct lang_decl): Overhaul.
|
||||
(struct lang_decl_flags): Remove.
|
||||
(struct lang_decl_base): New.
|
||||
(struct lang_decl_min): New.
|
||||
(struct lang_decl_fn): New.
|
||||
(struct lang_decl_ns): New.
|
||||
(CAN_HAVE_FULL_LANG_DECL_P): Replace with LANG_DECL_HAS_MIN.
|
||||
(LANG_DECL_MIN_CHECK): New.
|
||||
(LANG_DECL_FN_CHECK): New.
|
||||
(LANG_DECL_NS_CHECK): New.
|
||||
(STRIP_TEMPLATE): New.
|
||||
(NON_THUNK_FUNCTION_CHECK): Remove.
|
||||
(DECL_DECLARES_FUNCTION_P): New.
|
||||
(lots): Adjust.
|
||||
* lex.c (retrofit_lang_decl, cxx_dup_lang_specific_decl): Adjust.
|
||||
* decl.c (push_local_name, duplicate_decls): Adjust.
|
||||
* decl2.c (start_objects): Don't set u2sel.
|
||||
* semantics.c (finish_omp_threadprivate): Adjust.
|
||||
* class.c (build_clone): Don't do much on TEMPLATE_DECLs.
|
||||
(decl_cloned_function_p): Out-of-line implementation of macros.
|
||||
(clone_function_decl, adjust_clone_args): Use DECL_CLONED_FUNCTION_P.
|
||||
* mangle.c (write_unqualified_name): Don't check function flags
|
||||
on non-functions.
|
||||
* method.c (make_alias_for): Don't set DECL_CLONED_FUNCTION.
|
||||
* pt.c (build_template_decl): Don't set function flags.
|
||||
(check_default_tmpl_args): Check that it's a function.
|
||||
(instantiate_template): Use DECL_ABSTRACT_ORIGIN to find the
|
||||
cloned template.
|
||||
|
||||
* pt.c (tsubst_decl) [FUNCTION_DECL]: Don't tsubst
|
||||
DECL_CLONED_FUNCTION.
|
||||
|
||||
* cp-tree.h (struct lang_type_class): Move sorted_fields here.
|
||||
* class.c (finish_struct_1): Adjust.
|
||||
* ptree.c (cxx_print_decl, cxx_print_type): Adjust.
|
||||
* search.c (lookup_field_1): Adjust.
|
||||
|
||||
* cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Remove.
|
||||
* decl.c (finish_method): Don't add to it.
|
||||
* class.c (fixup_pending_inline): Remove.
|
||||
(fixup_inline_methods): Remove.
|
||||
(finish_struct_1): Don't call it.
|
||||
|
||||
* error.c (dump_function_name): Handle null name.
|
||||
|
||||
2009-07-02 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* typeck.c (cp_build_binary_op): Move warnings about use of NULL
|
||||
|
|
179
gcc/cp/class.c
179
gcc/cp/class.c
|
@ -151,8 +151,6 @@ static void check_bases_and_members (tree);
|
|||
static tree create_vtable_ptr (tree, tree *);
|
||||
static void include_empty_classes (record_layout_info);
|
||||
static void layout_class_type (tree, tree *);
|
||||
static void fixup_pending_inline (tree);
|
||||
static void fixup_inline_methods (tree);
|
||||
static void propagate_binfo_offsets (tree, tree);
|
||||
static void layout_virtual_bases (record_layout_info, splay_tree);
|
||||
static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
|
||||
|
@ -3799,12 +3797,27 @@ build_clone (tree fn, tree name)
|
|||
|
||||
/* Copy the function. */
|
||||
clone = copy_decl (fn);
|
||||
/* Remember where this function came from. */
|
||||
DECL_CLONED_FUNCTION (clone) = fn;
|
||||
DECL_ABSTRACT_ORIGIN (clone) = fn;
|
||||
/* Reset the function name. */
|
||||
DECL_NAME (clone) = name;
|
||||
SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
|
||||
/* Remember where this function came from. */
|
||||
DECL_ABSTRACT_ORIGIN (clone) = fn;
|
||||
/* Make it easy to find the CLONE given the FN. */
|
||||
TREE_CHAIN (clone) = TREE_CHAIN (fn);
|
||||
TREE_CHAIN (fn) = clone;
|
||||
|
||||
/* If this is a template, do the rest on the DECL_TEMPLATE_RESULT. */
|
||||
if (TREE_CODE (clone) == TEMPLATE_DECL)
|
||||
{
|
||||
tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name);
|
||||
DECL_TEMPLATE_RESULT (clone) = result;
|
||||
DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
|
||||
DECL_TI_TEMPLATE (result) = clone;
|
||||
TREE_TYPE (clone) = TREE_TYPE (result);
|
||||
return clone;
|
||||
}
|
||||
|
||||
DECL_CLONED_FUNCTION (clone) = fn;
|
||||
/* There's no pending inline data for this function. */
|
||||
DECL_PENDING_INLINE_INFO (clone) = NULL;
|
||||
DECL_PENDING_INLINE_P (clone) = 0;
|
||||
|
@ -3852,63 +3865,81 @@ build_clone (tree fn, tree name)
|
|||
TYPE_ATTRIBUTES (TREE_TYPE (fn)));
|
||||
}
|
||||
|
||||
/* Copy the function parameters. But, DECL_ARGUMENTS on a TEMPLATE_DECL
|
||||
aren't function parameters; those are the template parameters. */
|
||||
if (TREE_CODE (clone) != TEMPLATE_DECL)
|
||||
/* Copy the function parameters. */
|
||||
DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
|
||||
/* Remove the in-charge parameter. */
|
||||
if (DECL_HAS_IN_CHARGE_PARM_P (clone))
|
||||
{
|
||||
DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
|
||||
/* Remove the in-charge parameter. */
|
||||
if (DECL_HAS_IN_CHARGE_PARM_P (clone))
|
||||
TREE_CHAIN (DECL_ARGUMENTS (clone))
|
||||
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
|
||||
DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
|
||||
}
|
||||
/* And the VTT parm, in a complete [cd]tor. */
|
||||
if (DECL_HAS_VTT_PARM_P (fn))
|
||||
{
|
||||
if (DECL_NEEDS_VTT_PARM_P (clone))
|
||||
DECL_HAS_VTT_PARM_P (clone) = 1;
|
||||
else
|
||||
{
|
||||
TREE_CHAIN (DECL_ARGUMENTS (clone))
|
||||
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
|
||||
DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
|
||||
}
|
||||
/* And the VTT parm, in a complete [cd]tor. */
|
||||
if (DECL_HAS_VTT_PARM_P (fn))
|
||||
{
|
||||
if (DECL_NEEDS_VTT_PARM_P (clone))
|
||||
DECL_HAS_VTT_PARM_P (clone) = 1;
|
||||
else
|
||||
{
|
||||
TREE_CHAIN (DECL_ARGUMENTS (clone))
|
||||
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
|
||||
DECL_HAS_VTT_PARM_P (clone) = 0;
|
||||
}
|
||||
DECL_HAS_VTT_PARM_P (clone) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
|
||||
{
|
||||
DECL_CONTEXT (parms) = clone;
|
||||
cxx_dup_lang_specific_decl (parms);
|
||||
}
|
||||
for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
|
||||
{
|
||||
DECL_CONTEXT (parms) = clone;
|
||||
cxx_dup_lang_specific_decl (parms);
|
||||
}
|
||||
|
||||
/* Create the RTL for this function. */
|
||||
SET_DECL_RTL (clone, NULL_RTX);
|
||||
rest_of_decl_compilation (clone, /*top_level=*/1, at_eof);
|
||||
|
||||
/* Make it easy to find the CLONE given the FN. */
|
||||
TREE_CHAIN (clone) = TREE_CHAIN (fn);
|
||||
TREE_CHAIN (fn) = clone;
|
||||
|
||||
/* If this is a template, handle the DECL_TEMPLATE_RESULT as well. */
|
||||
if (TREE_CODE (clone) == TEMPLATE_DECL)
|
||||
{
|
||||
tree result;
|
||||
|
||||
DECL_TEMPLATE_RESULT (clone)
|
||||
= build_clone (DECL_TEMPLATE_RESULT (clone), name);
|
||||
result = DECL_TEMPLATE_RESULT (clone);
|
||||
DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
|
||||
DECL_TI_TEMPLATE (result) = clone;
|
||||
}
|
||||
else if (pch_file)
|
||||
if (pch_file)
|
||||
note_decl_for_pch (clone);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
/* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do
|
||||
not invoke this function directly.
|
||||
|
||||
For a non-thunk function, returns the address of the slot for storing
|
||||
the function it is a clone of. Otherwise returns NULL_TREE.
|
||||
|
||||
If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if
|
||||
cloned_function is unset. This is to support the separate
|
||||
DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter
|
||||
on a template makes sense, but not the former. */
|
||||
|
||||
tree *
|
||||
decl_cloned_function_p (const_tree decl, bool just_testing)
|
||||
{
|
||||
tree *ptr;
|
||||
if (just_testing)
|
||||
decl = STRIP_TEMPLATE (decl);
|
||||
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL
|
||||
|| !DECL_LANG_SPECIFIC (decl)
|
||||
|| DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p)
|
||||
{
|
||||
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
|
||||
if (!just_testing)
|
||||
lang_check_failed (__FILE__, __LINE__, __FUNCTION__);
|
||||
else
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = &DECL_LANG_SPECIFIC (decl)->u.fn.u5.cloned_function;
|
||||
if (just_testing && *ptr == NULL_TREE)
|
||||
return NULL;
|
||||
else
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Produce declarations for all appropriate clones of FN. If
|
||||
UPDATE_METHOD_VEC_P is nonzero, the clones are added to the
|
||||
CLASTYPE_METHOD_VEC as well. */
|
||||
|
@ -3920,7 +3951,7 @@ clone_function_decl (tree fn, int update_method_vec_p)
|
|||
|
||||
/* Avoid inappropriate cloning. */
|
||||
if (TREE_CHAIN (fn)
|
||||
&& DECL_CLONED_FUNCTION (TREE_CHAIN (fn)))
|
||||
&& DECL_CLONED_FUNCTION_P (TREE_CHAIN (fn)))
|
||||
return;
|
||||
|
||||
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
|
||||
|
@ -3977,7 +4008,7 @@ adjust_clone_args (tree decl)
|
|||
{
|
||||
tree clone;
|
||||
|
||||
for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION (clone);
|
||||
for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone);
|
||||
clone = TREE_CHAIN (clone))
|
||||
{
|
||||
tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
|
||||
|
@ -4447,54 +4478,6 @@ create_vtable_ptr (tree t, tree* virtuals_p)
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Fixup the inline function given by INFO now that the class is
|
||||
complete. */
|
||||
|
||||
static void
|
||||
fixup_pending_inline (tree fn)
|
||||
{
|
||||
if (DECL_PENDING_INLINE_INFO (fn))
|
||||
{
|
||||
tree args = DECL_ARGUMENTS (fn);
|
||||
while (args)
|
||||
{
|
||||
DECL_CONTEXT (args) = fn;
|
||||
args = TREE_CHAIN (args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup the inline methods and friends in TYPE now that TYPE is
|
||||
complete. */
|
||||
|
||||
static void
|
||||
fixup_inline_methods (tree type)
|
||||
{
|
||||
tree method = TYPE_METHODS (type);
|
||||
VEC(tree,gc) *friends;
|
||||
unsigned ix;
|
||||
|
||||
if (method && TREE_CODE (method) == TREE_VEC)
|
||||
{
|
||||
if (TREE_VEC_ELT (method, 1))
|
||||
method = TREE_VEC_ELT (method, 1);
|
||||
else if (TREE_VEC_ELT (method, 0))
|
||||
method = TREE_VEC_ELT (method, 0);
|
||||
else
|
||||
method = TREE_VEC_ELT (method, 2);
|
||||
}
|
||||
|
||||
/* Do inline member functions. */
|
||||
for (; method; method = TREE_CHAIN (method))
|
||||
fixup_pending_inline (method);
|
||||
|
||||
/* Do friends. */
|
||||
for (friends = CLASSTYPE_INLINE_FRIENDS (type), ix = 0;
|
||||
VEC_iterate (tree, friends, ix, method); ix++)
|
||||
fixup_pending_inline (method);
|
||||
CLASSTYPE_INLINE_FRIENDS (type) = NULL;
|
||||
}
|
||||
|
||||
/* Add OFFSET to all base types of BINFO which is a base in the
|
||||
hierarchy dominated by T.
|
||||
|
||||
|
@ -5219,8 +5202,6 @@ finish_struct_1 (tree t)
|
|||
TYPE_SIZE (t) = NULL_TREE;
|
||||
CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
|
||||
|
||||
fixup_inline_methods (t);
|
||||
|
||||
/* Make assumptions about the class; we'll reset the flags if
|
||||
necessary. */
|
||||
CLASSTYPE_EMPTY_P (t) = 1;
|
||||
|
@ -5332,9 +5313,7 @@ finish_struct_1 (tree t)
|
|||
add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
|
||||
qsort (field_vec->elts, n_fields, sizeof (tree),
|
||||
field_decl_cmp);
|
||||
if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t)))
|
||||
retrofit_lang_decl (TYPE_MAIN_DECL (t));
|
||||
DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
|
||||
CLASSTYPE_SORTED_FIELDS (t) = field_vec;
|
||||
}
|
||||
|
||||
/* Complain if one of the field types requires lower visibility. */
|
||||
|
|
397
gcc/cp/cp-tree.h
397
gcc/cp/cp-tree.h
|
@ -199,21 +199,13 @@ framework extensions, you must include this file before toplev.h, not after.
|
|||
TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM)
|
||||
|
||||
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
|
||||
#define NON_THUNK_FUNCTION_CHECK(NODE) __extension__ \
|
||||
({ __typeof(NODE) const __t = (NODE); \
|
||||
if (TREE_CODE (__t) != FUNCTION_DECL && \
|
||||
TREE_CODE (__t) != TEMPLATE_DECL && __t->decl_common.lang_specific \
|
||||
&& __t->decl_common.lang_specific->decl_flags.thunk_p) \
|
||||
tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0); \
|
||||
__t; })
|
||||
#define THUNK_FUNCTION_CHECK(NODE) __extension__ \
|
||||
({ __typeof (NODE) const __t = (NODE); \
|
||||
if (TREE_CODE (__t) != FUNCTION_DECL || !__t->decl_common.lang_specific \
|
||||
|| !__t->decl_common.lang_specific->decl_flags.thunk_p) \
|
||||
if (TREE_CODE (__t) != FUNCTION_DECL || !__t->decl_common.lang_specific \
|
||||
|| !__t->decl_common.lang_specific->u.fn.thunk_p) \
|
||||
tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0); \
|
||||
__t; })
|
||||
#else
|
||||
#define NON_THUNK_FUNCTION_CHECK(NODE) (NODE)
|
||||
#define THUNK_FUNCTION_CHECK(NODE) (NODE)
|
||||
#endif
|
||||
|
||||
|
@ -1160,6 +1152,10 @@ struct GTY(()) lang_type_class {
|
|||
as a list of adopted protocols or a pointer to a corresponding
|
||||
@interface. See objc/objc-act.h for details. */
|
||||
tree objc_info;
|
||||
/* sorted_fields is sorted based on a pointer, so we need to be able
|
||||
to resort it if pointers get rearranged. */
|
||||
struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields")))
|
||||
sorted_fields;
|
||||
};
|
||||
|
||||
struct GTY(()) lang_type_ptrmem {
|
||||
|
@ -1197,13 +1193,6 @@ struct GTY(()) lang_type {
|
|||
|
||||
#endif /* ENABLE_TREE_CHECKING */
|
||||
|
||||
/* Fields used for storing information before the class is defined.
|
||||
After the class is defined, these fields hold other information. */
|
||||
|
||||
/* VEC(tree) of friends which were defined inline in this class
|
||||
definition. */
|
||||
#define CLASSTYPE_INLINE_FRIENDS(NODE) CLASSTYPE_PURE_VIRTUALS (NODE)
|
||||
|
||||
/* Nonzero for _CLASSTYPE means that operator delete is defined. */
|
||||
#define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete)
|
||||
#define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)
|
||||
|
@ -1563,64 +1552,49 @@ struct GTY(()) lang_type {
|
|||
|
||||
/* The binding level associated with the namespace. */
|
||||
#define NAMESPACE_LEVEL(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.u.level)
|
||||
(LANG_DECL_NS_CHECK (NODE)->level)
|
||||
|
||||
/* Flags shared by all forms of DECL_LANG_SPECIFIC.
|
||||
|
||||
/* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or
|
||||
a lang_decl (which has lang_decl_flags as its initial prefix).
|
||||
This macro is nonzero for tree nodes whose DECL_LANG_SPECIFIC is
|
||||
the full lang_decl, and not just lang_decl_flags. Keep these
|
||||
checks in ascending code order. */
|
||||
#define CAN_HAVE_FULL_LANG_DECL_P(NODE) \
|
||||
(!(TREE_CODE (NODE) == FIELD_DECL \
|
||||
|| TREE_CODE (NODE) == VAR_DECL \
|
||||
|| TREE_CODE (NODE) == CONST_DECL \
|
||||
|| TREE_CODE (NODE) == USING_DECL))
|
||||
Some of the flags live here only to make lang_decl_min/fn smaller. Do
|
||||
not make this struct larger than 32 bits; instead, make sel smaller. */
|
||||
|
||||
struct GTY(()) lang_decl_flags {
|
||||
struct GTY(()) lang_decl_base {
|
||||
unsigned selector : 16; /* Larger than necessary for faster access. */
|
||||
ENUM_BITFIELD(languages) language : 4;
|
||||
unsigned global_ctor_p : 1;
|
||||
unsigned global_dtor_p : 1;
|
||||
unsigned anticipated_p : 1;
|
||||
unsigned template_conv_p : 1;
|
||||
|
||||
unsigned operator_attr : 1;
|
||||
unsigned constructor_attr : 1;
|
||||
unsigned destructor_attr : 1;
|
||||
unsigned friend_attr : 1;
|
||||
unsigned static_function : 1;
|
||||
unsigned pure_virtual : 1;
|
||||
unsigned has_in_charge_parm_p : 1;
|
||||
unsigned has_vtt_parm_p : 1;
|
||||
|
||||
unsigned deferred : 1;
|
||||
unsigned use_template : 2;
|
||||
unsigned nonconverting : 1;
|
||||
unsigned not_really_extern : 1;
|
||||
unsigned initialized_in_class : 1;
|
||||
unsigned assignment_operator_p : 1;
|
||||
unsigned u1sel : 1;
|
||||
|
||||
unsigned not_really_extern : 1; /* var or fn */
|
||||
unsigned initialized_in_class : 1; /* var or fn */
|
||||
unsigned repo_available_p : 1; /* var or fn */
|
||||
unsigned threadprivate_or_deleted_p : 1; /* var or fn */
|
||||
unsigned anticipated_p : 1; /* fn or type */
|
||||
unsigned friend_attr : 1; /* fn or type */
|
||||
unsigned template_conv_p : 1; /* template only? */
|
||||
unsigned u2sel : 1;
|
||||
unsigned can_be_full : 1;
|
||||
unsigned thunk_p : 1;
|
||||
unsigned this_thunk_p : 1;
|
||||
unsigned repo_available_p : 1;
|
||||
unsigned hidden_friend_p : 1;
|
||||
unsigned threadprivate_or_deleted_p : 1;
|
||||
unsigned defaulted_p : 1;
|
||||
/* 2 spare bits */
|
||||
};
|
||||
|
||||
union lang_decl_u {
|
||||
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
|
||||
THUNK_ALIAS.
|
||||
In a FUNCTION_DECL for which DECL_THUNK_P does not hold,
|
||||
VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is
|
||||
DECL_TEMPLATE_INFO. */
|
||||
tree GTY ((tag ("0"))) template_info;
|
||||
/* True for DECL codes which have template info and access. */
|
||||
#define LANG_DECL_HAS_MIN(NODE) \
|
||||
(TREE_CODE (NODE) == FUNCTION_DECL \
|
||||
|| TREE_CODE (NODE) == FIELD_DECL \
|
||||
|| TREE_CODE (NODE) == VAR_DECL \
|
||||
|| TREE_CODE (NODE) == CONST_DECL \
|
||||
|| TREE_CODE (NODE) == TYPE_DECL \
|
||||
|| TREE_CODE (NODE) == TEMPLATE_DECL \
|
||||
|| TREE_CODE (NODE) == USING_DECL)
|
||||
|
||||
/* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL. */
|
||||
struct cp_binding_level * GTY ((tag ("1"))) level;
|
||||
} GTY ((desc ("%1.u1sel"))) u;
|
||||
/* DECL_LANG_SPECIFIC for the above codes. */
|
||||
|
||||
struct GTY(()) lang_decl_min {
|
||||
struct lang_decl_base base;
|
||||
|
||||
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
|
||||
THUNK_ALIAS.
|
||||
In a FUNCTION_DECL for which DECL_THUNK_P does not hold,
|
||||
VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is
|
||||
DECL_TEMPLATE_INFO. */
|
||||
tree template_info;
|
||||
|
||||
union lang_decl_u2 {
|
||||
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
|
||||
|
@ -1630,75 +1604,136 @@ struct GTY(()) lang_decl_flags {
|
|||
|
||||
/* For VAR_DECL in function, this is DECL_DISCRIMINATOR. */
|
||||
int GTY ((tag ("1"))) discriminator;
|
||||
} GTY ((desc ("%1.u2sel"))) u2;
|
||||
} GTY ((desc ("%0.u.base.u2sel"))) u2;
|
||||
};
|
||||
|
||||
/* sorted_fields is sorted based on a pointer, so we need to be able
|
||||
to resort it if pointers get rearranged. */
|
||||
/* Additional DECL_LANG_SPECIFIC information for functions. */
|
||||
|
||||
struct GTY(()) lang_decl_fn {
|
||||
struct lang_decl_min min;
|
||||
|
||||
/* In an overloaded operator, this is the value of
|
||||
DECL_OVERLOADED_OPERATOR_P. */
|
||||
ENUM_BITFIELD (tree_code) operator_code : 16;
|
||||
|
||||
unsigned global_ctor_p : 1;
|
||||
unsigned global_dtor_p : 1;
|
||||
unsigned constructor_attr : 1;
|
||||
unsigned destructor_attr : 1;
|
||||
unsigned assignment_operator_p : 1;
|
||||
unsigned static_function : 1;
|
||||
unsigned pure_virtual : 1;
|
||||
unsigned defaulted_p : 1;
|
||||
|
||||
unsigned has_in_charge_parm_p : 1;
|
||||
unsigned has_vtt_parm_p : 1;
|
||||
unsigned pending_inline_p : 1;
|
||||
unsigned nonconverting : 1;
|
||||
unsigned thunk_p : 1;
|
||||
unsigned this_thunk_p : 1;
|
||||
unsigned hidden_friend_p : 1;
|
||||
unsigned deferred : 1;
|
||||
/* No spare bits; consider adding to lang_decl_base instead. */
|
||||
|
||||
/* For a non-thunk function decl, this is a tree list of
|
||||
friendly classes. For a thunk function decl, it is the
|
||||
thunked to function decl. */
|
||||
tree befriending_classes;
|
||||
|
||||
/* For a non-virtual FUNCTION_DECL, this is
|
||||
DECL_FRIEND_CONTEXT. For a virtual FUNCTION_DECL for which
|
||||
DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both
|
||||
this pointer and result pointer adjusting thunks are
|
||||
chained here. This pointer thunks to return pointer thunks
|
||||
will be chained on the return pointer thunk. */
|
||||
tree context;
|
||||
|
||||
union lang_decl_u5
|
||||
{
|
||||
/* In a non-thunk FUNCTION_DECL or TEMPLATE_DECL, this is
|
||||
DECL_CLONED_FUNCTION. */
|
||||
tree GTY ((tag ("0"))) cloned_function;
|
||||
|
||||
/* In a FUNCTION_DECL for which THUNK_P holds this is the
|
||||
THUNK_FIXED_OFFSET. */
|
||||
HOST_WIDE_INT GTY ((tag ("1"))) fixed_offset;
|
||||
} GTY ((desc ("%1.thunk_p"))) u5;
|
||||
|
||||
union lang_decl_u3
|
||||
{
|
||||
struct cp_token_cache * GTY ((tag ("1"))) pending_inline_info;
|
||||
struct language_function * GTY ((tag ("0")))
|
||||
saved_language_function;
|
||||
} GTY ((desc ("%1.pending_inline_p"))) u;
|
||||
|
||||
};
|
||||
|
||||
/* DECL_LANG_SPECIFIC for namespaces. */
|
||||
|
||||
struct GTY(()) lang_decl_ns {
|
||||
struct lang_decl_base base;
|
||||
struct cp_binding_level *level;
|
||||
};
|
||||
|
||||
/* DECL_LANG_SPECIFIC for all types. It would be nice to just make this a
|
||||
union rather than a struct containing a union as its only field, but
|
||||
tree.h declares it as a struct. */
|
||||
|
||||
struct GTY(()) lang_decl {
|
||||
struct lang_decl_flags decl_flags;
|
||||
|
||||
union lang_decl_u4
|
||||
{
|
||||
struct full_lang_decl
|
||||
{
|
||||
/* In an overloaded operator, this is the value of
|
||||
DECL_OVERLOADED_OPERATOR_P. */
|
||||
ENUM_BITFIELD (tree_code) operator_code : 16;
|
||||
|
||||
unsigned u3sel : 1;
|
||||
unsigned pending_inline_p : 1;
|
||||
unsigned spare : 14;
|
||||
|
||||
/* For a non-thunk function decl, this is a tree list of
|
||||
friendly classes. For a thunk function decl, it is the
|
||||
thunked to function decl. */
|
||||
tree befriending_classes;
|
||||
|
||||
/* For a non-virtual FUNCTION_DECL, this is
|
||||
DECL_FRIEND_CONTEXT. For a virtual FUNCTION_DECL for which
|
||||
DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both
|
||||
this pointer and result pointer adjusting thunks are
|
||||
chained here. This pointer thunks to return pointer thunks
|
||||
will be chained on the return pointer thunk. */
|
||||
tree context;
|
||||
|
||||
union lang_decl_u5
|
||||
{
|
||||
/* In a non-thunk FUNCTION_DECL or TEMPLATE_DECL, this is
|
||||
DECL_CLONED_FUNCTION. */
|
||||
tree GTY ((tag ("0"))) cloned_function;
|
||||
|
||||
/* In a FUNCTION_DECL for which THUNK_P holds this is the
|
||||
THUNK_FIXED_OFFSET. */
|
||||
HOST_WIDE_INT GTY ((tag ("1"))) fixed_offset;
|
||||
} GTY ((desc ("%0.decl_flags.thunk_p"))) u5;
|
||||
|
||||
union lang_decl_u3
|
||||
{
|
||||
struct sorted_fields_type * GTY ((tag ("0"), reorder ("resort_sorted_fields")))
|
||||
sorted_fields;
|
||||
struct cp_token_cache * GTY ((tag ("2"))) pending_inline_info;
|
||||
struct language_function * GTY ((tag ("1")))
|
||||
saved_language_function;
|
||||
} GTY ((desc ("%1.u3sel + %1.pending_inline_p"))) u;
|
||||
} GTY ((tag ("1"))) f;
|
||||
} GTY ((desc ("%1.decl_flags.can_be_full"))) u;
|
||||
union GTY((desc ("%h.base.selector"))) lang_decl_u {
|
||||
struct lang_decl_base GTY ((default)) base;
|
||||
struct lang_decl_min GTY((tag ("0"))) min;
|
||||
struct lang_decl_fn GTY ((tag ("1"))) fn;
|
||||
struct lang_decl_ns GTY((tag ("2"))) ns;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* Looks through a template (if present) to find what it declares. */
|
||||
#define STRIP_TEMPLATE(NODE) \
|
||||
(TREE_CODE (NODE) == TEMPLATE_DECL ? DECL_TEMPLATE_RESULT (NODE) : NODE)
|
||||
|
||||
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
|
||||
|
||||
#define LANG_DECL_MIN_CHECK(NODE) __extension__ \
|
||||
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
|
||||
if (!LANG_DECL_HAS_MIN (NODE)) \
|
||||
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
|
||||
<->u.min; })
|
||||
|
||||
/* We want to be able to check DECL_CONSTRUCTOR_P and such on a function
|
||||
template, not just on a FUNCTION_DECL. So when looking for things in
|
||||
lang_decl_fn, look down through a TEMPLATE_DECL into its result. */
|
||||
#define LANG_DECL_FN_CHECK(NODE) __extension__ \
|
||||
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE)); \
|
||||
if (!DECL_DECLARES_FUNCTION_P (NODE) || lt->u.base.selector != 1) \
|
||||
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
|
||||
<->u.fn; })
|
||||
|
||||
#define LANG_DECL_NS_CHECK(NODE) __extension__ \
|
||||
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
|
||||
if (TREE_CODE (NODE) != NAMESPACE_DECL || lt->u.base.selector != 2) \
|
||||
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
|
||||
<->u.ns; })
|
||||
|
||||
#define LANG_DECL_U2_CHECK(NODE, TF) __extension__ \
|
||||
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
|
||||
if (lt->decl_flags.u2sel != TF) \
|
||||
if (lt->u.base.u2sel != TF) \
|
||||
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
|
||||
<->decl_flags.u2; })
|
||||
<->u.min.u2; })
|
||||
|
||||
#else
|
||||
|
||||
#define LANG_DECL_MIN_CHECK(NODE) \
|
||||
(&DECL_LANG_SPECIFIC (NODE)->u.min)
|
||||
|
||||
#define LANG_DECL_FN_CHECK(NODE) \
|
||||
(&DECL_LANG_SPECIFIC (NODE)->u.fn)
|
||||
|
||||
#define LANG_DECL_NS_CHECK(NODE) \
|
||||
(&DECL_LANG_SPECIFIC (NODE)->u.ns)
|
||||
|
||||
#define LANG_DECL_U2_CHECK(NODE, TF) \
|
||||
(&DECL_LANG_SPECIFIC (NODE)->decl_flags.u2)
|
||||
(&DECL_LANG_SPECIFIC (NODE)->u.min.u2)
|
||||
|
||||
#endif /* ENABLE_TREE_CHECKING */
|
||||
|
||||
|
@ -1713,17 +1748,17 @@ struct GTY(()) lang_decl {
|
|||
we do create DECL_LANG_SPECIFIC for variables with non-C++ linkage. */
|
||||
#define DECL_LANGUAGE(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE) \
|
||||
? DECL_LANG_SPECIFIC (NODE)->decl_flags.language \
|
||||
? DECL_LANG_SPECIFIC (NODE)->u.base.language \
|
||||
: (TREE_CODE (NODE) == FUNCTION_DECL \
|
||||
? lang_c : lang_cplusplus))
|
||||
|
||||
/* Set the language linkage for NODE to LANGUAGE. */
|
||||
#define SET_DECL_LANGUAGE(NODE, LANGUAGE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.language = (LANGUAGE))
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.base.language = (LANGUAGE))
|
||||
|
||||
/* For FUNCTION_DECLs: nonzero means that this function is a constructor. */
|
||||
#define DECL_CONSTRUCTOR_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.constructor_attr)
|
||||
(LANG_DECL_FN_CHECK (NODE)->constructor_attr)
|
||||
|
||||
/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a complete
|
||||
object. */
|
||||
|
@ -1741,7 +1776,8 @@ struct GTY(()) lang_decl {
|
|||
specialized in-charge constructor or the specialized not-in-charge
|
||||
constructor. */
|
||||
#define DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P(NODE) \
|
||||
(DECL_CONSTRUCTOR_P (NODE) && !DECL_CLONED_FUNCTION_P (NODE))
|
||||
(DECL_DECLARES_FUNCTION_P (NODE) && DECL_CONSTRUCTOR_P (NODE) \
|
||||
&& !DECL_CLONED_FUNCTION_P (NODE))
|
||||
|
||||
/* Nonzero if NODE (a FUNCTION_DECL) is a copy constructor. */
|
||||
#define DECL_COPY_CONSTRUCTOR_P(NODE) \
|
||||
|
@ -1753,13 +1789,14 @@ struct GTY(()) lang_decl {
|
|||
|
||||
/* Nonzero if NODE is a destructor. */
|
||||
#define DECL_DESTRUCTOR_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.destructor_attr)
|
||||
(LANG_DECL_FN_CHECK (NODE)->destructor_attr)
|
||||
|
||||
/* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the
|
||||
specialized in-charge constructor, in-charge deleting constructor,
|
||||
or the base destructor. */
|
||||
#define DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P(NODE) \
|
||||
(DECL_DESTRUCTOR_P (NODE) && !DECL_CLONED_FUNCTION_P (NODE))
|
||||
(DECL_DECLARES_FUNCTION_P (NODE) && DECL_DESTRUCTOR_P (NODE) \
|
||||
&& !DECL_CLONED_FUNCTION_P (NODE))
|
||||
|
||||
/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete
|
||||
object. */
|
||||
|
@ -1781,17 +1818,11 @@ struct GTY(()) lang_decl {
|
|||
|
||||
/* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or
|
||||
destructor. */
|
||||
#define DECL_CLONED_FUNCTION_P(NODE) \
|
||||
((TREE_CODE (NODE) == FUNCTION_DECL \
|
||||
|| TREE_CODE (NODE) == TEMPLATE_DECL) \
|
||||
&& DECL_LANG_SPECIFIC (NODE) \
|
||||
&& !DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p \
|
||||
&& DECL_CLONED_FUNCTION (NODE) != NULL_TREE)
|
||||
#define DECL_CLONED_FUNCTION_P(NODE) (!!decl_cloned_function_p (NODE, true))
|
||||
|
||||
/* If DECL_CLONED_FUNCTION_P holds, this is the function that was
|
||||
cloned. */
|
||||
#define DECL_CLONED_FUNCTION(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NON_THUNK_FUNCTION_CHECK(NODE))->u.f.u5.cloned_function)
|
||||
#define DECL_CLONED_FUNCTION(NODE) (*decl_cloned_function_p (NODE, false))
|
||||
|
||||
/* Perform an action for each clone of FN, if FN is a function with
|
||||
clones. This macro should be used like:
|
||||
|
@ -1818,7 +1849,7 @@ struct GTY(()) lang_decl {
|
|||
|
||||
/* Nonzero if the VTT parm has been added to NODE. */
|
||||
#define DECL_HAS_VTT_PARM_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.has_vtt_parm_p)
|
||||
(LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
|
||||
|
||||
/* Nonzero if NODE is a FUNCTION_DECL for which a VTT parameter is
|
||||
required. */
|
||||
|
@ -1840,11 +1871,11 @@ struct GTY(()) lang_decl {
|
|||
conversion operator to a type dependent on the innermost template
|
||||
args. */
|
||||
#define DECL_TEMPLATE_CONV_FN_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.template_conv_p)
|
||||
(DECL_LANG_SPECIFIC (TEMPLATE_DECL_CHECK (NODE))->u.base.template_conv_p)
|
||||
|
||||
/* Set the overloaded operator code for NODE to CODE. */
|
||||
#define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.operator_code = (CODE))
|
||||
(LANG_DECL_FN_CHECK (NODE)->operator_code = (CODE))
|
||||
|
||||
/* If NODE is an overloaded operator, then this returns the TREE_CODE
|
||||
associated with the overloaded operator.
|
||||
|
@ -1855,17 +1886,17 @@ struct GTY(()) lang_decl {
|
|||
to test whether or not NODE is an overloaded operator. */
|
||||
#define DECL_OVERLOADED_OPERATOR_P(NODE) \
|
||||
(IDENTIFIER_OPNAME_P (DECL_NAME (NODE)) \
|
||||
? DECL_LANG_SPECIFIC (NODE)->u.f.operator_code : ERROR_MARK)
|
||||
? LANG_DECL_FN_CHECK (NODE)->operator_code : ERROR_MARK)
|
||||
|
||||
/* Nonzero if NODE is an assignment operator (including += and such). */
|
||||
#define DECL_ASSIGNMENT_OPERATOR_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.assignment_operator_p)
|
||||
(LANG_DECL_FN_CHECK (NODE)->assignment_operator_p)
|
||||
|
||||
/* For FUNCTION_DECLs: nonzero means that this function is a
|
||||
constructor or a destructor with an extra in-charge parameter to
|
||||
control whether or not virtual bases are constructed. */
|
||||
#define DECL_HAS_IN_CHARGE_PARM_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.has_in_charge_parm_p)
|
||||
(LANG_DECL_FN_CHECK (NODE)->has_in_charge_parm_p)
|
||||
|
||||
/* Nonzero if DECL is a declaration of __builtin_constant_p. */
|
||||
#define DECL_IS_BUILTIN_CONSTANT_P(NODE) \
|
||||
|
@ -1917,20 +1948,21 @@ struct GTY(()) lang_decl {
|
|||
rather than outside the class. This is used for both static member
|
||||
VAR_DECLS, and FUNCTION_DECLS that are defined in the class. */
|
||||
#define DECL_INITIALIZED_IN_CLASS_P(DECL) \
|
||||
(DECL_LANG_SPECIFIC (DECL)->decl_flags.initialized_in_class)
|
||||
(DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
|
||||
->u.base.initialized_in_class)
|
||||
|
||||
/* Nonzero for DECL means that this decl is just a friend declaration,
|
||||
and should not be added to the list of members for this class. */
|
||||
#define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.friend_attr)
|
||||
#define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.friend_attr)
|
||||
|
||||
/* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */
|
||||
#define DECL_BEFRIENDING_CLASSES(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
|
||||
(LANG_DECL_FN_CHECK (NODE)->befriending_classes)
|
||||
|
||||
/* Nonzero for FUNCTION_DECL means that this decl is a static
|
||||
member function. */
|
||||
#define DECL_STATIC_FUNCTION_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.static_function)
|
||||
(LANG_DECL_FN_CHECK (NODE)->static_function)
|
||||
|
||||
/* Nonzero for FUNCTION_DECL means that this decl is a non-static
|
||||
member function. */
|
||||
|
@ -1940,7 +1972,7 @@ struct GTY(()) lang_decl {
|
|||
/* Nonzero for FUNCTION_DECL means that this decl is a member function
|
||||
(static or non-static). */
|
||||
#define DECL_FUNCTION_MEMBER_P(NODE) \
|
||||
(DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE))
|
||||
(DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE))
|
||||
|
||||
/* Nonzero for FUNCTION_DECL means that this member function
|
||||
has `this' as const X *const. */
|
||||
|
@ -1968,12 +2000,12 @@ struct GTY(()) lang_decl {
|
|||
/* Nonzero for _DECL means that this constructor or conversion function is
|
||||
non-converting. */
|
||||
#define DECL_NONCONVERTING_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.nonconverting)
|
||||
(LANG_DECL_FN_CHECK (NODE)->nonconverting)
|
||||
|
||||
/* Nonzero for FUNCTION_DECL means that this member function is a pure
|
||||
virtual function. */
|
||||
#define DECL_PURE_VIRTUAL_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.pure_virtual)
|
||||
(LANG_DECL_FN_CHECK (NODE)->pure_virtual)
|
||||
|
||||
/* True (in a FUNCTION_DECL) if NODE is a virtual function that is an
|
||||
invalid overrider for a function from a base class. Once we have
|
||||
|
@ -1984,27 +2016,26 @@ struct GTY(()) lang_decl {
|
|||
|
||||
/* The thunks associated with NODE, a FUNCTION_DECL. */
|
||||
#define DECL_THUNKS(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.context)
|
||||
(LANG_DECL_FN_CHECK (NODE)->context)
|
||||
|
||||
/* Nonzero if NODE is a thunk, rather than an ordinary function. */
|
||||
#define DECL_THUNK_P(NODE) \
|
||||
(TREE_CODE (NODE) == FUNCTION_DECL \
|
||||
&& DECL_LANG_SPECIFIC (NODE) \
|
||||
&& DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p)
|
||||
&& LANG_DECL_FN_CHECK (NODE)->thunk_p)
|
||||
|
||||
/* Set DECL_THUNK_P for node. */
|
||||
#define SET_DECL_THUNK_P(NODE, THIS_ADJUSTING) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p = 1, \
|
||||
DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1, \
|
||||
DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p = (THIS_ADJUSTING))
|
||||
(LANG_DECL_FN_CHECK (NODE)->thunk_p = 1, \
|
||||
LANG_DECL_FN_CHECK (NODE)->this_thunk_p = (THIS_ADJUSTING))
|
||||
|
||||
/* Nonzero if NODE is a this pointer adjusting thunk. */
|
||||
#define DECL_THIS_THUNK_P(NODE) \
|
||||
(DECL_THUNK_P (NODE) && DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p)
|
||||
(DECL_THUNK_P (NODE) && LANG_DECL_FN_CHECK (NODE)->this_thunk_p)
|
||||
|
||||
/* Nonzero if NODE is a result pointer adjusting thunk. */
|
||||
#define DECL_RESULT_THUNK_P(NODE) \
|
||||
(DECL_THUNK_P (NODE) && !DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p)
|
||||
(DECL_THUNK_P (NODE) && !LANG_DECL_FN_CHECK (NODE)->this_thunk_p)
|
||||
|
||||
/* Nonzero if NODE is a FUNCTION_DECL, but not a thunk. */
|
||||
#define DECL_NON_THUNK_FUNCTION_P(NODE) \
|
||||
|
@ -2021,7 +2052,7 @@ struct GTY(()) lang_decl {
|
|||
/* True iff DECL is an entity with vague linkage whose definition is
|
||||
available in this translation unit. */
|
||||
#define DECL_REPO_AVAILABLE_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.repo_available_p)
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.base.repo_available_p)
|
||||
|
||||
/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
|
||||
template function. */
|
||||
|
@ -2040,13 +2071,14 @@ struct GTY(()) lang_decl {
|
|||
|
||||
the DECL_FRIEND_CONTEXT for `f' will be `S'. */
|
||||
#define DECL_FRIEND_CONTEXT(NODE) \
|
||||
((DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE)) \
|
||||
? DECL_LANG_SPECIFIC (NODE)->u.f.context \
|
||||
((DECL_DECLARES_FUNCTION_P (NODE) \
|
||||
&& DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE)) \
|
||||
? LANG_DECL_FN_CHECK (NODE)->context \
|
||||
: NULL_TREE)
|
||||
|
||||
/* Set the DECL_FRIEND_CONTEXT for NODE to CONTEXT. */
|
||||
#define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.context = (CONTEXT))
|
||||
(LANG_DECL_FN_CHECK (NODE)->context = (CONTEXT))
|
||||
|
||||
/* NULL_TREE in DECL_CONTEXT represents the global namespace. */
|
||||
#define CP_DECL_CONTEXT(NODE) \
|
||||
|
@ -2153,21 +2185,21 @@ extern void decl_shadowed_for_var_insert (tree, tree);
|
|||
the class definition. We have saved away the text of the function,
|
||||
but have not yet processed it. */
|
||||
#define DECL_PENDING_INLINE_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.pending_inline_p)
|
||||
(LANG_DECL_FN_CHECK (NODE)->pending_inline_p)
|
||||
|
||||
/* If DECL_PENDING_INLINE_P holds, this is the saved text of the
|
||||
function. */
|
||||
#define DECL_PENDING_INLINE_INFO(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.u.pending_inline_info)
|
||||
(LANG_DECL_FN_CHECK (NODE)->u.pending_inline_info)
|
||||
|
||||
/* For a TYPE_DECL: if this structure has many fields, we'll sort them
|
||||
/* For a class type: if this structure has many fields, we'll sort them
|
||||
and put them into a TREE_VEC. */
|
||||
#define DECL_SORTED_FIELDS(NODE) \
|
||||
(DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE))->u.f.u.sorted_fields)
|
||||
#define CLASSTYPE_SORTED_FIELDS(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->sorted_fields)
|
||||
|
||||
/* True if on the deferred_fns (see decl2.c) list. */
|
||||
#define DECL_DEFERRED_FN(DECL) \
|
||||
(DECL_LANG_SPECIFIC (DECL)->decl_flags.deferred)
|
||||
(LANG_DECL_FN_CHECK (DECL)->deferred)
|
||||
|
||||
/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
|
||||
TEMPLATE_DECL, the entity is either a template specialization (if
|
||||
|
@ -2190,7 +2222,7 @@ extern void decl_shadowed_for_var_insert (tree, tree);
|
|||
will be non-NULL, but DECL_USE_TEMPLATE will be zero. */
|
||||
#define DECL_TEMPLATE_INFO(NODE) \
|
||||
(DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
|
||||
->decl_flags.u.template_info)
|
||||
->u.min.template_info)
|
||||
|
||||
/* For a VAR_DECL, indicates that the variable is actually a
|
||||
non-static data member of anonymous union that has been promoted to
|
||||
|
@ -2440,8 +2472,8 @@ extern void decl_shadowed_for_var_insert (tree, tree);
|
|||
|
||||
/* In a FUNCTION_DECL, the saved language-specific per-function data. */
|
||||
#define DECL_SAVED_FUNCTION_DATA(NODE) \
|
||||
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE)) \
|
||||
->u.f.u.saved_language_function)
|
||||
(LANG_DECL_FN_CHECK (FUNCTION_DECL_CHECK (NODE)) \
|
||||
->u.saved_language_function)
|
||||
|
||||
/* Indicates an indirect_expr is for converting a reference. */
|
||||
#define REFERENCE_REF_P(NODE) \
|
||||
|
@ -2617,26 +2649,26 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
declared inside a class. In the latter case DECL_HIDDEN_FRIEND_P
|
||||
will be set. */
|
||||
#define DECL_ANTICIPATED(NODE) \
|
||||
(DECL_LANG_SPECIFIC (DECL_COMMON_CHECK (NODE))->decl_flags.anticipated_p)
|
||||
(DECL_LANG_SPECIFIC (DECL_COMMON_CHECK (NODE))->u.base.anticipated_p)
|
||||
|
||||
/* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend
|
||||
within a class but has not been declared in the surrounding scope.
|
||||
The function is invisible except via argument dependent lookup. */
|
||||
#define DECL_HIDDEN_FRIEND_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (DECL_COMMON_CHECK (NODE))->decl_flags.hidden_friend_p)
|
||||
(LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p)
|
||||
|
||||
/* Nonzero if DECL has been declared threadprivate by
|
||||
#pragma omp threadprivate. */
|
||||
#define CP_DECL_THREADPRIVATE_P(DECL) \
|
||||
(DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->decl_flags.threadprivate_or_deleted_p)
|
||||
(DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->u.base.threadprivate_or_deleted_p)
|
||||
|
||||
/* Nonzero if DECL was declared with '= delete'. */
|
||||
#define DECL_DELETED_FN(DECL) \
|
||||
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.threadprivate_or_deleted_p)
|
||||
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.base.threadprivate_or_deleted_p)
|
||||
|
||||
/* Nonzero if DECL was declared with '= default'. */
|
||||
#define DECL_DEFAULTED_FN(DECL) \
|
||||
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.defaulted_p)
|
||||
(LANG_DECL_FN_CHECK (DECL)->defaulted_p)
|
||||
|
||||
/* Record whether a typedef for type `int' was actually `signed int'. */
|
||||
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
|
||||
|
@ -3046,11 +3078,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
|
||||
/* Nonzero if the FUNCTION_DECL is a global constructor. */
|
||||
#define DECL_GLOBAL_CTOR_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.global_ctor_p)
|
||||
(LANG_DECL_FN_CHECK (NODE)->global_ctor_p)
|
||||
|
||||
/* Nonzero if the FUNCTION_DECL is a global destructor. */
|
||||
#define DECL_GLOBAL_DTOR_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.global_dtor_p)
|
||||
(LANG_DECL_FN_CHECK (NODE)->global_dtor_p)
|
||||
|
||||
/* Accessor macros for C++ template decl nodes. */
|
||||
|
||||
|
@ -3151,6 +3183,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
#define DECL_DECLARES_TYPE_P(NODE) \
|
||||
(TREE_CODE (NODE) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (NODE))
|
||||
|
||||
/* Nonzero if NODE declares a function. */
|
||||
#define DECL_DECLARES_FUNCTION_P(NODE) \
|
||||
(TREE_CODE (NODE) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (NODE))
|
||||
|
||||
/* Nonzero if NODE is the typedef implicitly generated for a type when
|
||||
the type is declared. In C++, `struct S {};' is roughly
|
||||
equivalent to `struct S {}; typedef struct S S;' in C.
|
||||
|
@ -3204,7 +3240,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
|
||||
If DECL_USE_TEMPLATE is nonzero, then DECL_TEMPLATE_INFO will also
|
||||
be non-NULL. */
|
||||
#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.use_template)
|
||||
#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.use_template)
|
||||
|
||||
/* Like DECL_USE_TEMPLATE, but for class types. */
|
||||
#define CLASSTYPE_USE_TEMPLATE(NODE) \
|
||||
|
@ -3277,7 +3313,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
current translation unit; it indicates whether or not we should emit the
|
||||
decl at the end of compilation if it is defined and needed. */
|
||||
#define DECL_NOT_REALLY_EXTERN(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.not_really_extern)
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern)
|
||||
|
||||
#define DECL_REALLY_EXTERN(NODE) \
|
||||
(DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE))
|
||||
|
@ -3324,7 +3360,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
/* An integer indicating how many bytes should be subtracted from the
|
||||
this or result pointer when this function is called. */
|
||||
#define THUNK_FIXED_OFFSET(DECL) \
|
||||
(DECL_LANG_SPECIFIC (THUNK_FUNCTION_CHECK (DECL))->u.f.u5.fixed_offset)
|
||||
(DECL_LANG_SPECIFIC (THUNK_FUNCTION_CHECK (DECL))->u.fn.u5.fixed_offset)
|
||||
|
||||
/* A tree indicating how to perform the virtual adjustment. For a this
|
||||
adjusting thunk it is the number of bytes to be added to the vtable
|
||||
|
@ -3341,12 +3377,12 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
|
||||
/* A thunk which is equivalent to another thunk. */
|
||||
#define THUNK_ALIAS(DECL) \
|
||||
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.template_info)
|
||||
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.min.template_info)
|
||||
|
||||
/* For thunk NODE, this is the FUNCTION_DECL thunked to. It is
|
||||
possible for the target to be a thunk too. */
|
||||
#define THUNK_TARGET(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
|
||||
(LANG_DECL_FN_CHECK (NODE)->befriending_classes)
|
||||
|
||||
/* True for a SCOPE_REF iff the "template" keyword was used to
|
||||
indicate that the qualified name denotes a template. */
|
||||
|
@ -4258,6 +4294,7 @@ extern bool type_has_user_provided_constructor (tree);
|
|||
extern bool type_has_user_provided_default_constructor (tree);
|
||||
extern bool defaultable_fn_p (tree);
|
||||
extern void fixup_type_variants (tree);
|
||||
extern tree* decl_cloned_function_p (const_tree, bool);
|
||||
extern void clone_function_decl (tree, int);
|
||||
extern void adjust_clone_args (tree);
|
||||
|
||||
|
|
|
@ -873,7 +873,7 @@ push_local_name (tree decl)
|
|||
{
|
||||
if (!DECL_LANG_SPECIFIC (decl))
|
||||
retrofit_lang_decl (decl);
|
||||
DECL_LANG_SPECIFIC (decl)->decl_flags.u2sel = 1;
|
||||
DECL_LANG_SPECIFIC (decl)->u.base.u2sel = 1;
|
||||
if (DECL_LANG_SPECIFIC (t))
|
||||
DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
|
||||
else
|
||||
|
@ -1786,9 +1786,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
|||
{
|
||||
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
|
||||
DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
|
||||
if (CAN_HAVE_FULL_LANG_DECL_P (newdecl)
|
||||
&& DECL_LANG_SPECIFIC (newdecl)
|
||||
&& DECL_LANG_SPECIFIC (olddecl))
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
|
||||
DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
|
||||
|
@ -1894,24 +1892,27 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
|||
/* 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_LANG_SPECIFIC (newdecl)->decl_flags.u2 =
|
||||
DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2;
|
||||
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
|
||||
DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl);
|
||||
if (DECL_TEMPLATE_INFO (newdecl))
|
||||
new_template_info = DECL_TEMPLATE_INFO (newdecl);
|
||||
DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
|
||||
DECL_INITIALIZED_IN_CLASS_P (newdecl)
|
||||
|= DECL_INITIALIZED_IN_CLASS_P (olddecl);
|
||||
olddecl_friend = DECL_FRIEND_P (olddecl);
|
||||
hidden_friend = (DECL_ANTICIPATED (olddecl)
|
||||
&& DECL_HIDDEN_FRIEND_P (olddecl)
|
||||
&& newdecl_is_friend);
|
||||
|
||||
/* Only functions have DECL_BEFRIENDING_CLASSES. */
|
||||
if (LANG_DECL_HAS_MIN (newdecl))
|
||||
{
|
||||
DECL_LANG_SPECIFIC (newdecl)->u.min.u2 =
|
||||
DECL_LANG_SPECIFIC (olddecl)->u.min.u2;
|
||||
if (DECL_TEMPLATE_INFO (newdecl))
|
||||
new_template_info = DECL_TEMPLATE_INFO (newdecl);
|
||||
DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
|
||||
}
|
||||
/* Only functions have these fields. */
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
|| DECL_FUNCTION_TEMPLATE_P (newdecl))
|
||||
{
|
||||
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
|
||||
olddecl_friend = DECL_FRIEND_P (olddecl);
|
||||
hidden_friend = (DECL_ANTICIPATED (olddecl)
|
||||
&& DECL_HIDDEN_FRIEND_P (olddecl)
|
||||
&& newdecl_is_friend);
|
||||
DECL_BEFRIENDING_CLASSES (newdecl)
|
||||
= chainon (DECL_BEFRIENDING_CLASSES (newdecl),
|
||||
DECL_BEFRIENDING_CLASSES (olddecl));
|
||||
|
@ -12582,16 +12583,6 @@ finish_method (tree decl)
|
|||
|
||||
DECL_INITIAL (fndecl) = old_initial;
|
||||
|
||||
/* We used to check if the context of FNDECL was different from
|
||||
current_class_type as another way to get inside here. This didn't work
|
||||
for String.cc in libg++. */
|
||||
if (DECL_FRIEND_P (fndecl))
|
||||
{
|
||||
VEC_safe_push (tree, gc, CLASSTYPE_INLINE_FRIENDS (current_class_type),
|
||||
fndecl);
|
||||
decl = void_type_node;
|
||||
}
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
|
|
@ -2634,7 +2634,6 @@ start_objects (int method_type, int initp)
|
|||
DECL_GLOBAL_CTOR_P (current_function_decl) = 1;
|
||||
else
|
||||
DECL_GLOBAL_DTOR_P (current_function_decl) = 1;
|
||||
DECL_LANG_SPECIFIC (current_function_decl)->decl_flags.u2sel = 1;
|
||||
|
||||
body = begin_compound_stmt (BCS_FN_BODY);
|
||||
|
||||
|
|
|
@ -1406,7 +1406,7 @@ dump_function_name (tree t, int flags)
|
|||
pp_cxx_ws_string (cxx_pp, "operator");
|
||||
dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
|
||||
}
|
||||
else if (IDENTIFIER_OPNAME_P (name))
|
||||
else if (name && IDENTIFIER_OPNAME_P (name))
|
||||
pp_cxx_tree_identifier (cxx_pp, name);
|
||||
else
|
||||
dump_decl (name, flags);
|
||||
|
|
28
gcc/cp/lex.c
28
gcc/cp/lex.c
|
@ -532,19 +532,20 @@ retrofit_lang_decl (tree t)
|
|||
{
|
||||
struct lang_decl *ld;
|
||||
size_t size;
|
||||
int sel;
|
||||
|
||||
if (CAN_HAVE_FULL_LANG_DECL_P (t))
|
||||
size = sizeof (struct lang_decl);
|
||||
if (TREE_CODE (t) == FUNCTION_DECL)
|
||||
sel = 1, size = sizeof (struct lang_decl_fn);
|
||||
else if (TREE_CODE (t) == NAMESPACE_DECL)
|
||||
sel = 2, size = sizeof (struct lang_decl_ns);
|
||||
else if (LANG_DECL_HAS_MIN (t))
|
||||
sel = 0, size = sizeof (struct lang_decl_min);
|
||||
else
|
||||
size = sizeof (struct lang_decl_flags);
|
||||
gcc_unreachable ();
|
||||
|
||||
ld = GGC_CNEWVAR (struct lang_decl, size);
|
||||
|
||||
ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0;
|
||||
ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;
|
||||
ld->decl_flags.u2sel = 0;
|
||||
if (ld->decl_flags.can_be_full)
|
||||
ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0;
|
||||
ld->u.base.selector = sel;
|
||||
|
||||
DECL_LANG_SPECIFIC (t) = ld;
|
||||
if (current_lang_name == lang_name_cplusplus
|
||||
|
@ -572,10 +573,15 @@ cxx_dup_lang_specific_decl (tree node)
|
|||
if (! DECL_LANG_SPECIFIC (node))
|
||||
return;
|
||||
|
||||
if (!CAN_HAVE_FULL_LANG_DECL_P (node))
|
||||
size = sizeof (struct lang_decl_flags);
|
||||
if (TREE_CODE (node) == FUNCTION_DECL)
|
||||
size = sizeof (struct lang_decl_fn);
|
||||
else if (TREE_CODE (node) == NAMESPACE_DECL)
|
||||
size = sizeof (struct lang_decl_ns);
|
||||
else if (LANG_DECL_HAS_MIN (node))
|
||||
size = sizeof (struct lang_decl_min);
|
||||
else
|
||||
size = sizeof (struct lang_decl);
|
||||
gcc_unreachable ();
|
||||
|
||||
ld = GGC_NEWVAR (struct lang_decl, size);
|
||||
memcpy (ld, DECL_LANG_SPECIFIC (node), size);
|
||||
DECL_LANG_SPECIFIC (node) = ld;
|
||||
|
|
|
@ -1088,43 +1088,54 @@ write_unqualified_name (const tree decl)
|
|||
{
|
||||
MANGLE_TRACE_TREE ("unqualified-name", decl);
|
||||
|
||||
if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_CONSTRUCTOR_P (decl))
|
||||
write_special_name_constructor (decl);
|
||||
else if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_DESTRUCTOR_P (decl))
|
||||
write_special_name_destructor (decl);
|
||||
else if (DECL_NAME (decl) == NULL_TREE)
|
||||
if (DECL_NAME (decl) == NULL_TREE)
|
||||
{
|
||||
gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
|
||||
write_source_name (DECL_ASSEMBLER_NAME (decl));
|
||||
return;
|
||||
}
|
||||
else if (DECL_CONV_FN_P (decl))
|
||||
else if (DECL_DECLARES_FUNCTION_P (decl))
|
||||
{
|
||||
/* Conversion operator. Handle it right here.
|
||||
<operator> ::= cv <type> */
|
||||
tree type;
|
||||
if (decl_is_template_id (decl, NULL))
|
||||
bool found = true;
|
||||
if (DECL_CONSTRUCTOR_P (decl))
|
||||
write_special_name_constructor (decl);
|
||||
else if (DECL_DESTRUCTOR_P (decl))
|
||||
write_special_name_destructor (decl);
|
||||
else if (DECL_CONV_FN_P (decl))
|
||||
{
|
||||
tree fn_type;
|
||||
fn_type = get_mostly_instantiated_function_type (decl);
|
||||
type = TREE_TYPE (fn_type);
|
||||
/* Conversion operator. Handle it right here.
|
||||
<operator> ::= cv <type> */
|
||||
tree type;
|
||||
if (decl_is_template_id (decl, NULL))
|
||||
{
|
||||
tree fn_type;
|
||||
fn_type = get_mostly_instantiated_function_type (decl);
|
||||
type = TREE_TYPE (fn_type);
|
||||
}
|
||||
else
|
||||
type = DECL_CONV_FN_TYPE (decl);
|
||||
write_conversion_operator_name (type);
|
||||
}
|
||||
else if (DECL_OVERLOADED_OPERATOR_P (decl))
|
||||
{
|
||||
operator_name_info_t *oni;
|
||||
if (DECL_ASSIGNMENT_OPERATOR_P (decl))
|
||||
oni = assignment_operator_name_info;
|
||||
else
|
||||
oni = operator_name_info;
|
||||
|
||||
write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
|
||||
}
|
||||
else
|
||||
type = DECL_CONV_FN_TYPE (decl);
|
||||
write_conversion_operator_name (type);
|
||||
}
|
||||
else if (DECL_OVERLOADED_OPERATOR_P (decl))
|
||||
{
|
||||
operator_name_info_t *oni;
|
||||
if (DECL_ASSIGNMENT_OPERATOR_P (decl))
|
||||
oni = assignment_operator_name_info;
|
||||
else
|
||||
oni = operator_name_info;
|
||||
found = false;
|
||||
|
||||
write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
|
||||
if (found)
|
||||
return;
|
||||
}
|
||||
else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
|
||||
&& DECL_NAMESPACE_SCOPE_P (decl)
|
||||
&& decl_linkage (decl) == lk_internal)
|
||||
|
||||
if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
|
||||
&& DECL_NAMESPACE_SCOPE_P (decl)
|
||||
&& decl_linkage (decl) == lk_internal)
|
||||
{
|
||||
MANGLE_TRACE_TREE ("local-source-name", decl);
|
||||
write_char ('L');
|
||||
|
|
|
@ -277,7 +277,6 @@ make_alias_for (tree function, tree newid)
|
|||
DECL_SAVED_FUNCTION_DATA (alias) = NULL;
|
||||
DECL_DESTRUCTOR_P (alias) = 0;
|
||||
DECL_CONSTRUCTOR_P (alias) = 0;
|
||||
DECL_CLONED_FUNCTION (alias) = NULL_TREE;
|
||||
DECL_EXTERNAL (alias) = 0;
|
||||
DECL_ARTIFICIAL (alias) = 1;
|
||||
DECL_NO_STATIC_CHAIN (alias) = 1;
|
||||
|
|
27
gcc/cp/pt.c
27
gcc/cp/pt.c
|
@ -3458,17 +3458,6 @@ build_template_decl (tree decl, tree parms, bool member_template_p)
|
|||
DECL_TEMPLATE_PARMS (tmpl) = parms;
|
||||
DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
|
||||
DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p;
|
||||
if (DECL_LANG_SPECIFIC (decl))
|
||||
{
|
||||
DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);
|
||||
DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl);
|
||||
DECL_DESTRUCTOR_P (tmpl) = DECL_DESTRUCTOR_P (decl);
|
||||
DECL_NONCONVERTING_P (tmpl) = DECL_NONCONVERTING_P (decl);
|
||||
DECL_ASSIGNMENT_OPERATOR_P (tmpl) = DECL_ASSIGNMENT_OPERATOR_P (decl);
|
||||
if (DECL_OVERLOADED_OPERATOR_P (decl))
|
||||
SET_OVERLOADED_OPERATOR_CODE (tmpl,
|
||||
DECL_OVERLOADED_OPERATOR_P (decl));
|
||||
}
|
||||
|
||||
return tmpl;
|
||||
}
|
||||
|
@ -3792,6 +3781,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary,
|
|||
if (current_class_type
|
||||
&& !TYPE_BEING_DEFINED (current_class_type)
|
||||
&& DECL_LANG_SPECIFIC (decl)
|
||||
&& DECL_DECLARES_FUNCTION_P (decl)
|
||||
/* If this is either a friend defined in the scope of the class
|
||||
or a member function. */
|
||||
&& (DECL_FUNCTION_MEMBER_P (decl)
|
||||
|
@ -8594,13 +8584,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
|||
DECL_SAVED_TREE (r) = NULL_TREE;
|
||||
DECL_STRUCT_FUNCTION (r) = NULL;
|
||||
TREE_USED (r) = 0;
|
||||
if (DECL_CLONED_FUNCTION (r))
|
||||
{
|
||||
DECL_CLONED_FUNCTION (r) = tsubst (DECL_CLONED_FUNCTION (t),
|
||||
args, complain, t);
|
||||
TREE_CHAIN (r) = TREE_CHAIN (DECL_CLONED_FUNCTION (r));
|
||||
TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r;
|
||||
}
|
||||
/* We'll re-clone as appropriate in instantiate_template. */
|
||||
DECL_CLONED_FUNCTION (r) = NULL_TREE;
|
||||
|
||||
/* Set up the DECL_TEMPLATE_INFO for R. There's no need to do
|
||||
this in the special friend case mentioned above where
|
||||
|
@ -12330,8 +12315,10 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
|
|||
tree spec;
|
||||
tree clone;
|
||||
|
||||
spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr,
|
||||
complain);
|
||||
/* Use DECL_ABSTRACT_ORIGIN because only FUNCTION_DECLs have
|
||||
DECL_CLONED_FUNCTION. */
|
||||
spec = instantiate_template (DECL_ABSTRACT_ORIGIN (tmpl),
|
||||
targ_ptr, complain);
|
||||
if (spec == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
|
|
@ -65,10 +65,6 @@ cxx_print_decl (FILE *file, tree node, int indent)
|
|||
&& DECL_PENDING_INLINE_INFO (node))
|
||||
fprintf (file, " pending-inline-info %p",
|
||||
(void *) DECL_PENDING_INLINE_INFO (node));
|
||||
if (TREE_CODE (node) == TYPE_DECL
|
||||
&& DECL_SORTED_FIELDS (node))
|
||||
fprintf (file, " sorted-fields %p",
|
||||
(void *) DECL_SORTED_FIELDS (node));
|
||||
if ((TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL)
|
||||
&& DECL_TEMPLATE_INFO (node))
|
||||
fprintf (file, " template-info %p",
|
||||
|
@ -95,13 +91,6 @@ cxx_print_type (FILE *file, tree node, int indent)
|
|||
print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4);
|
||||
return;
|
||||
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
indent_to (file, indent + 4);
|
||||
fprintf (file, "full-name \"%s\"",
|
||||
type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -113,6 +102,10 @@ cxx_print_type (FILE *file, tree node, int indent)
|
|||
if (! CLASS_TYPE_P (node))
|
||||
return;
|
||||
|
||||
indent_to (file, indent + 4);
|
||||
fprintf (file, "full-name \"%s\"",
|
||||
type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
|
||||
|
||||
indent_to (file, indent + 3);
|
||||
|
||||
if (TYPE_NEEDS_CONSTRUCTING (node))
|
||||
|
@ -140,6 +133,9 @@ cxx_print_type (FILE *file, tree node, int indent)
|
|||
fputs (" delete[]", file);
|
||||
if (TYPE_HAS_ASSIGN_REF (node))
|
||||
fputs (" this=(X&)", file);
|
||||
if (CLASSTYPE_SORTED_FIELDS (node))
|
||||
fprintf (file, " sorted-fields %p",
|
||||
(void *) CLASSTYPE_SORTED_FIELDS (node));
|
||||
|
||||
if (TREE_CODE (node) == RECORD_TYPE)
|
||||
{
|
||||
|
|
|
@ -395,12 +395,10 @@ lookup_field_1 (tree type, tree name, bool want_type)
|
|||
The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME. */
|
||||
return NULL_TREE;
|
||||
|
||||
if (TYPE_NAME (type)
|
||||
&& DECL_LANG_SPECIFIC (TYPE_NAME (type))
|
||||
&& DECL_SORTED_FIELDS (TYPE_NAME (type)))
|
||||
if (CLASSTYPE_SORTED_FIELDS (type))
|
||||
{
|
||||
tree *fields = &DECL_SORTED_FIELDS (TYPE_NAME (type))->elts[0];
|
||||
int lo = 0, hi = DECL_SORTED_FIELDS (TYPE_NAME (type))->len;
|
||||
tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0];
|
||||
int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len;
|
||||
int i;
|
||||
|
||||
while (lo < hi)
|
||||
|
|
|
@ -3861,7 +3861,7 @@ finish_omp_threadprivate (tree vars)
|
|||
/* Make sure that DECL_DISCRIMINATOR_P continues to be true
|
||||
after the allocation of the lang_decl structure. */
|
||||
if (DECL_DISCRIMINATOR_P (v))
|
||||
DECL_LANG_SPECIFIC (v)->decl_flags.u2sel = 1;
|
||||
DECL_LANG_SPECIFIC (v)->u.base.u2sel = 1;
|
||||
}
|
||||
|
||||
if (! DECL_THREAD_LOCAL_P (v))
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2009-07-03 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/template/pure1.C: Expect another error.
|
||||
|
||||
2009-07-03 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/40640
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
struct A
|
||||
{
|
||||
template<int> void foo() = 1; // { dg-error "pure" }
|
||||
template<int> void foo() = 1; // { dg-error "pure|non-virtual" }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue