mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-05 08:49:38 +08:00
re PR c++/11703 (Problem with using enum in placement delete)
PR c++/11703 * call.c (type_passed_as): Use TYPE_SIZE, not TYPE_PRECISION to determine whether or not to promote types. (convert_for_arg_passing): Likewise. * decl2.c (cp_build_parm_decl): Do not set DECL_ARG_TYPE in templates. * pt.c (tsubst_decl): Do not expect it to be set. PR c++/9512 PR c++/10923 * cp-tree.h (check_elaborated_type_specifier): Declare. (handle_class_head): Remove. (note_got_semicolon): Likewise. (note_list_got_semicolon): Likewise. (finish_class_definition): Likewise. * decl.c (check_elaborated_type_specifier): Make it public. Robustify. (handle_class_head): Remove. * parser.c (cp_parser_elaborated_type_specifier): Use check_elaborated_type_specifier. (cp_parser_class_specifier): Do not call finish_class_definition. (cp_parser_class_head): Or handle_class_head. Check for over-qualified names. * semantics.c (finish_class_definition): Remove. * parser.c (cp_parser_check_for_definition_in_return_type): New function. (cp_parser_simple_declaration): Adjust call to cp_parser_init_declarator. (cp_parser_decl_specifier_seq): Change type of declares_class_or_enum parameter. (cp_parser_explicit_instantiation): Adjust accordingly. (cp_parser_type_specifier): Change type of declares_class_or_enum parameter. (cp_parser_init_declarator): Add declares_class_or_enum parameter. (cp_parser_parameter_declaration): Adjust call to cp_parser_decl_specifier_seq. (cp_parser_function_definition): Likewise. (cp_parser_member_declaration): Likewise. (cp_parser_single_declaration): Likewise. * cp-tree.h (lang_type_class): Remove has_call_overloaded, has_array_ref_overloaded, has_arrow_overloaded, and got_semicolon. (TYPE_OVERLOADS_CALL_EXPR): Remove. (TYPE_OVERLOADS_ARRAY_REF): Likewise. (TYPE_OVERLOADS_ARROW): Likewise. (CLASSTYPE_GOT_SEMICOLON): Likewise. * class.c (check_bases): Do not set them. (finish_struct_1): Likewise. * decl.c (cp_finish_decl): Do not set CLASSTYPE_GOT_SEMICOLON. (build_ptrmemfunc_type): Likewise. (grok_op_properties): Do not set TYPE_OVERLOADS_*. (start_function): Do not check CLASSTYPE_GOT_SEMICOLON. * decl2.c (grokfield): Do not set CLASSTYPE_GOT_SEMICOLON. * lex.c (note_got_semicolon): Remove. (note_list_got_semicolon): Likewise. * parser.c (cp_parser_simple_declaration): Do not call note_list_got_semicolon. * pt.c (list_eq): Remove. (lookup_template_class): Do not set CLASSTYPE_GOT_SEMICOLON. (instantiate_class_template): Do not set TYPE_OVERLOADS*. (instantiate_class_template): Do not set CLASSTYPE_GOT_SEMICOLON. * ptree.c (cxx_print_type): Do not print them. * semantics.c (finish_member_class_template): Do not call note_list_got_semicolon. * g++.dg/parse/ret-type2.C: New test. PR c++/11703 * g++.dg/init/new8.C: New test. PR c++/10923 * g++.dg/parse/typedef5.C: New test. PR c++/9512 * g++.dg/parse/qualified2.C: New test. * g++.old-deja/g++.other/decl5.C: Mark one more instance of invalid code. From-SVN: r70391
This commit is contained in:
parent
35e6511a74
commit
560ad596bd
@ -1,3 +1,72 @@
|
||||
2003-08-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/11703
|
||||
* call.c (type_passed_as): Use TYPE_SIZE, not TYPE_PRECISION to
|
||||
determine whether or not to promote types.
|
||||
(convert_for_arg_passing): Likewise.
|
||||
* decl2.c (cp_build_parm_decl): Do not set DECL_ARG_TYPE in
|
||||
templates.
|
||||
* pt.c (tsubst_decl): Do not expect it to be set.
|
||||
|
||||
PR c++/9512
|
||||
PR c++/10923
|
||||
* cp-tree.h (check_elaborated_type_specifier): Declare.
|
||||
(handle_class_head): Remove.
|
||||
(note_got_semicolon): Likewise.
|
||||
(note_list_got_semicolon): Likewise.
|
||||
(finish_class_definition): Likewise.
|
||||
* decl.c (check_elaborated_type_specifier): Make it public.
|
||||
Robustify.
|
||||
(handle_class_head): Remove.
|
||||
* parser.c (cp_parser_elaborated_type_specifier): Use
|
||||
check_elaborated_type_specifier.
|
||||
(cp_parser_class_specifier): Do not call finish_class_definition.
|
||||
(cp_parser_class_head): Or handle_class_head. Check for
|
||||
over-qualified names.
|
||||
* semantics.c (finish_class_definition): Remove.
|
||||
|
||||
* parser.c (cp_parser_check_for_definition_in_return_type): New
|
||||
function.
|
||||
(cp_parser_simple_declaration): Adjust call to
|
||||
cp_parser_init_declarator.
|
||||
(cp_parser_decl_specifier_seq): Change type of
|
||||
declares_class_or_enum parameter.
|
||||
(cp_parser_explicit_instantiation): Adjust accordingly.
|
||||
(cp_parser_type_specifier): Change type of
|
||||
declares_class_or_enum parameter.
|
||||
(cp_parser_init_declarator): Add declares_class_or_enum
|
||||
parameter.
|
||||
(cp_parser_parameter_declaration): Adjust call to
|
||||
cp_parser_decl_specifier_seq.
|
||||
(cp_parser_function_definition): Likewise.
|
||||
(cp_parser_member_declaration): Likewise.
|
||||
(cp_parser_single_declaration): Likewise.
|
||||
|
||||
* cp-tree.h (lang_type_class): Remove has_call_overloaded,
|
||||
has_array_ref_overloaded, has_arrow_overloaded, and got_semicolon.
|
||||
(TYPE_OVERLOADS_CALL_EXPR): Remove.
|
||||
(TYPE_OVERLOADS_ARRAY_REF): Likewise.
|
||||
(TYPE_OVERLOADS_ARROW): Likewise.
|
||||
(CLASSTYPE_GOT_SEMICOLON): Likewise.
|
||||
* class.c (check_bases): Do not set them.
|
||||
(finish_struct_1): Likewise.
|
||||
* decl.c (cp_finish_decl): Do not set CLASSTYPE_GOT_SEMICOLON.
|
||||
(build_ptrmemfunc_type): Likewise.
|
||||
(grok_op_properties): Do not set TYPE_OVERLOADS_*.
|
||||
(start_function): Do not check CLASSTYPE_GOT_SEMICOLON.
|
||||
* decl2.c (grokfield): Do not set CLASSTYPE_GOT_SEMICOLON.
|
||||
* lex.c (note_got_semicolon): Remove.
|
||||
(note_list_got_semicolon): Likewise.
|
||||
* parser.c (cp_parser_simple_declaration): Do not call
|
||||
note_list_got_semicolon.
|
||||
* pt.c (list_eq): Remove.
|
||||
(lookup_template_class): Do not set CLASSTYPE_GOT_SEMICOLON.
|
||||
(instantiate_class_template): Do not set TYPE_OVERLOADS*.
|
||||
(instantiate_class_template): Do not set CLASSTYPE_GOT_SEMICOLON.
|
||||
* ptree.c (cxx_print_type): Do not print them.
|
||||
* semantics.c (finish_member_class_template): Do not call
|
||||
note_list_got_semicolon.
|
||||
|
||||
2003-08-11 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
* call.c (standard_conversion): Opaque pointers interconvert.
|
||||
|
@ -4330,7 +4330,8 @@ type_passed_as (tree type)
|
||||
type = build_reference_type (type);
|
||||
else if (PROMOTE_PROTOTYPES
|
||||
&& INTEGRAL_TYPE_P (type)
|
||||
&& TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
|
||||
&& INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
|
||||
TYPE_SIZE (integer_type_node)))
|
||||
type = integer_type_node;
|
||||
|
||||
return type;
|
||||
@ -4348,7 +4349,8 @@ convert_for_arg_passing (tree type, tree val)
|
||||
val = build1 (ADDR_EXPR, build_reference_type (type), val);
|
||||
else if (PROMOTE_PROTOTYPES
|
||||
&& INTEGRAL_TYPE_P (type)
|
||||
&& TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
|
||||
&& INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
|
||||
TYPE_SIZE (integer_type_node)))
|
||||
val = perform_integral_promotions (val);
|
||||
return val;
|
||||
}
|
||||
|
@ -1284,9 +1284,6 @@ check_bases (tree t,
|
||||
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|
||||
|= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
|
||||
TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
|
||||
TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype);
|
||||
TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
|
||||
TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
|
||||
TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
|
||||
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
|
||||
|= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
|
||||
@ -4977,7 +4974,6 @@ finish_struct_1 (tree t)
|
||||
/* If this type was previously laid out as a forward reference,
|
||||
make sure we lay it out again. */
|
||||
TYPE_SIZE (t) = NULL_TREE;
|
||||
CLASSTYPE_GOT_SEMICOLON (t) = 0;
|
||||
CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
|
||||
|
||||
fixup_inline_methods (t);
|
||||
|
@ -1071,12 +1071,12 @@ struct lang_type_class GTY(())
|
||||
unsigned has_array_new : 1;
|
||||
|
||||
unsigned gets_delete : 2;
|
||||
unsigned has_call_overloaded : 1;
|
||||
unsigned has_array_ref_overloaded : 1;
|
||||
unsigned has_arrow_overloaded : 1;
|
||||
unsigned interface_only : 1;
|
||||
unsigned interface_unknown : 1;
|
||||
unsigned contains_empty_class_p : 1;
|
||||
unsigned anon_aggr : 1;
|
||||
unsigned non_zero_init : 1;
|
||||
unsigned empty_p : 1;
|
||||
|
||||
unsigned marks: 6;
|
||||
unsigned vec_new_uses_cookie : 1;
|
||||
@ -1086,7 +1086,7 @@ struct lang_type_class GTY(())
|
||||
unsigned redefined : 1;
|
||||
unsigned debug_requested : 1;
|
||||
unsigned use_template : 2;
|
||||
unsigned got_semicolon : 1;
|
||||
unsigned fields_readonly : 1;
|
||||
unsigned ptrmemfunc_flag : 1;
|
||||
unsigned was_anonymous : 1;
|
||||
|
||||
@ -1097,11 +1097,6 @@ struct lang_type_class GTY(())
|
||||
unsigned has_abstract_assign_ref : 1;
|
||||
unsigned non_aggregate : 1;
|
||||
unsigned java_interface : 1;
|
||||
unsigned anon_aggr : 1;
|
||||
|
||||
unsigned non_zero_init : 1;
|
||||
unsigned empty_p : 1;
|
||||
unsigned fields_readonly : 1;
|
||||
|
||||
/* When adding a flag here, consider whether or not it ought to
|
||||
apply to a template instance if it applies to the template. If
|
||||
@ -1110,7 +1105,7 @@ struct lang_type_class GTY(())
|
||||
/* There are some bits left to fill out a 32-bit word. Keep track
|
||||
of this by updating the size of this bitfield whenever you add or
|
||||
remove a flag. */
|
||||
unsigned dummy : 5;
|
||||
unsigned dummy : 9;
|
||||
|
||||
tree primary_base;
|
||||
tree vfields;
|
||||
@ -1221,18 +1216,6 @@ struct lang_type GTY(())
|
||||
convenient, don't reprocess any methods that appear in its redefinition. */
|
||||
#define TYPE_REDEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->redefined)
|
||||
|
||||
/* Nonzero means that this _CLASSTYPE node overloads operator(). */
|
||||
#define TYPE_OVERLOADS_CALL_EXPR(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->has_call_overloaded)
|
||||
|
||||
/* Nonzero means that this _CLASSTYPE node overloads operator[]. */
|
||||
#define TYPE_OVERLOADS_ARRAY_REF(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->has_array_ref_overloaded)
|
||||
|
||||
/* Nonzero means that this _CLASSTYPE node overloads operator->. */
|
||||
#define TYPE_OVERLOADS_ARROW(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->has_arrow_overloaded)
|
||||
|
||||
/* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses
|
||||
multiple inheritance. If this is 0 for the root of a type
|
||||
hierarchy, then we can use more efficient search techniques. */
|
||||
@ -1382,9 +1365,6 @@ struct lang_type GTY(())
|
||||
class must provide its own definition for each of these functions. */
|
||||
#define CLASSTYPE_PURE_VIRTUALS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals)
|
||||
|
||||
/* Nonzero means that this aggr type has been `closed' by a semicolon. */
|
||||
#define CLASSTYPE_GOT_SEMICOLON(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->got_semicolon)
|
||||
|
||||
/* Nonzero means that this type has an X() constructor. */
|
||||
#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor)
|
||||
@ -3763,6 +3743,7 @@ extern tree declare_global_var (tree, tree);
|
||||
extern void register_dtor_fn (tree);
|
||||
extern tmpl_spec_kind current_tmpl_spec_kind (int);
|
||||
extern tree cp_fname_init (const char *);
|
||||
extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
|
||||
extern bool have_extern_spec;
|
||||
|
||||
/* in decl2.c */
|
||||
@ -3808,7 +3789,6 @@ extern tree do_class_using_decl (tree);
|
||||
extern void do_using_directive (tree);
|
||||
extern void check_default_args (tree);
|
||||
extern void mark_used (tree);
|
||||
extern tree handle_class_head (enum tag_types, tree, tree, tree);
|
||||
extern tree lookup_arg_dependent (tree, tree, tree);
|
||||
extern void finish_static_data_member_decl (tree, tree, tree, int);
|
||||
extern tree cp_build_parm_decl (tree, tree);
|
||||
@ -3896,8 +3876,6 @@ extern void do_pending_inlines (void);
|
||||
extern void yyungetc (int, int);
|
||||
extern void snarf_method (tree);
|
||||
|
||||
extern void note_got_semicolon (tree);
|
||||
extern void note_list_got_semicolon (tree);
|
||||
extern void see_typename (void);
|
||||
extern tree unqualified_name_lookup_error (tree);
|
||||
extern tree unqualified_fn_lookup_error (tree);
|
||||
@ -4139,7 +4117,6 @@ extern tree finish_template_type_parm (tree, tree);
|
||||
extern tree finish_template_template_parm (tree, tree);
|
||||
extern tree finish_parmlist (tree, int);
|
||||
extern tree begin_class_definition (tree);
|
||||
extern tree finish_class_definition (tree, tree, int, int);
|
||||
extern void finish_default_args (void);
|
||||
extern tree finish_member_class_template (tree);
|
||||
extern void finish_template_decl (tree);
|
||||
|
@ -8066,7 +8066,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
|
||||
if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
|
||||
warning ("shadowing previous type declaration of `%#D'", decl);
|
||||
set_identifier_type_value (DECL_NAME (decl), type);
|
||||
CLASSTYPE_GOT_SEMICOLON (type) = 1;
|
||||
}
|
||||
|
||||
/* If we have installed this as the canonical typedef for this
|
||||
@ -9245,9 +9244,6 @@ build_ptrmemfunc_type (tree type)
|
||||
later. */
|
||||
TYPE_SET_PTRMEMFUNC_TYPE (type, t);
|
||||
|
||||
/* Seems to be wanted. */
|
||||
CLASSTYPE_GOT_SEMICOLON (t) = 1;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -12241,19 +12237,6 @@ grok_op_properties (tree decl, int friendp)
|
||||
{
|
||||
switch (operator_code)
|
||||
{
|
||||
case CALL_EXPR:
|
||||
TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
|
||||
break;
|
||||
|
||||
case ARRAY_REF:
|
||||
TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
|
||||
break;
|
||||
|
||||
case COMPONENT_REF:
|
||||
case MEMBER_REF:
|
||||
TYPE_OVERLOADS_ARROW (current_class_type) = 1;
|
||||
break;
|
||||
|
||||
case NEW_EXPR:
|
||||
TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
|
||||
break;
|
||||
@ -12541,7 +12524,7 @@ tag_name (enum tag_types code)
|
||||
error_mark_node; otherwise, return TYPE itself.
|
||||
If ALLOW_TEMPLATE_P is true, TYPE may be a class template. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
check_elaborated_type_specifier (enum tag_types tag_code,
|
||||
tree type,
|
||||
bool allow_template_p)
|
||||
@ -12553,8 +12536,8 @@ check_elaborated_type_specifier (enum tag_types tag_code,
|
||||
ill-formed. */
|
||||
if (!t)
|
||||
{
|
||||
error ("using typedef-name `%D' after `%s'",
|
||||
TYPE_NAME (type), tag_name (tag_code));
|
||||
error ("using typedef-name `%T' after `%s'",
|
||||
type, tag_name (tag_code));
|
||||
t = error_mark_node;
|
||||
}
|
||||
else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
|
||||
@ -13412,20 +13395,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
|
||||
fntype = TREE_TYPE (decl1);
|
||||
|
||||
restype = TREE_TYPE (fntype);
|
||||
if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype))
|
||||
{
|
||||
error ("semicolon missing after declaration of `%#T'", restype);
|
||||
shadow_tag (build_tree_list (NULL_TREE, restype));
|
||||
CLASSTYPE_GOT_SEMICOLON (restype) = 1;
|
||||
if (TREE_CODE (fntype) == FUNCTION_TYPE)
|
||||
fntype = build_function_type (integer_type_node,
|
||||
TYPE_ARG_TYPES (fntype));
|
||||
else
|
||||
fntype = build_cplus_method_type (build_type_variant (TYPE_METHOD_BASETYPE (fntype), TREE_READONLY (decl1), TREE_SIDE_EFFECTS (decl1)),
|
||||
integer_type_node,
|
||||
TYPE_ARG_TYPES (fntype));
|
||||
TREE_TYPE (decl1) = fntype;
|
||||
}
|
||||
|
||||
if (TREE_CODE (fntype) == METHOD_TYPE)
|
||||
ctype = TYPE_METHOD_BASETYPE (fntype);
|
||||
|
@ -223,7 +223,10 @@ tree
|
||||
cp_build_parm_decl (tree name, tree type)
|
||||
{
|
||||
tree parm = build_decl (PARM_DECL, name, type);
|
||||
DECL_ARG_TYPE (parm) = type_passed_as (type);
|
||||
/* DECL_ARG_TYPE is only used by the back end and the back end never
|
||||
sees templates. */
|
||||
if (!processing_template_decl)
|
||||
DECL_ARG_TYPE (parm) = type_passed_as (type);
|
||||
return parm;
|
||||
}
|
||||
|
||||
@ -918,9 +921,6 @@ grokfield (tree declarator, tree declspecs, tree init, tree asmspec_tree,
|
||||
DECL_NONLOCAL (value) = 1;
|
||||
DECL_CONTEXT (value) = current_class_type;
|
||||
|
||||
if (CLASS_TYPE_P (TREE_TYPE (value)))
|
||||
CLASSTYPE_GOT_SEMICOLON (TREE_TYPE (value)) = 1;
|
||||
|
||||
if (processing_template_decl)
|
||||
value = push_template_decl (value);
|
||||
|
||||
@ -4215,94 +4215,4 @@ mark_used (tree decl)
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when a class-head is encountered. TAG_KIND is the class-key
|
||||
for the class. SCOPE, if non-NULL, is the type or namespace
|
||||
indicated in the nested-name-specifier for the declaration of the
|
||||
class. ID is the name of the class, if any; it may be a TYPE_DECL,
|
||||
or an IDENTIFIER_NODE. ATTRIBUTES are attributes that apply to the
|
||||
class.
|
||||
|
||||
Return a TYPE_DECL for the class being defined. */
|
||||
|
||||
tree
|
||||
handle_class_head (enum tag_types tag_kind, tree scope, tree id,
|
||||
tree attributes)
|
||||
{
|
||||
tree decl = NULL_TREE;
|
||||
tree current = current_scope ();
|
||||
bool xrefd_p = false;
|
||||
bool new_type_p;
|
||||
tree context;
|
||||
|
||||
if (current == NULL_TREE)
|
||||
current = current_namespace;
|
||||
|
||||
if (scope)
|
||||
{
|
||||
if (TREE_CODE (id) == TYPE_DECL)
|
||||
/* We must bash typedefs back to the main decl of the
|
||||
type. Otherwise we become confused about scopes. */
|
||||
decl = TYPE_MAIN_DECL (TREE_TYPE (id));
|
||||
else if (DECL_CLASS_TEMPLATE_P (id))
|
||||
decl = DECL_TEMPLATE_RESULT (id);
|
||||
else
|
||||
{
|
||||
if (TYPE_P (scope))
|
||||
{
|
||||
/* According to the suggested resolution of core issue
|
||||
180, 'typename' is assumed after a class-key. */
|
||||
decl = make_typename_type (scope, id, tf_error);
|
||||
if (decl != error_mark_node)
|
||||
decl = TYPE_MAIN_DECL (decl);
|
||||
else
|
||||
decl = NULL_TREE;
|
||||
}
|
||||
else if (scope == current)
|
||||
{
|
||||
/* We've been given AGGR SCOPE::ID, when we're already
|
||||
inside SCOPE. Be nice about it. */
|
||||
if (pedantic)
|
||||
pedwarn ("extra qualification `%T::' on member `%D' ignored",
|
||||
scope, id);
|
||||
}
|
||||
else
|
||||
error ("`%T' does not have a class or union named `%D'",
|
||||
scope, id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!decl)
|
||||
{
|
||||
decl = xref_tag (tag_kind, id, attributes, false, false);
|
||||
if (decl == error_mark_node)
|
||||
return error_mark_node;
|
||||
decl = TYPE_MAIN_DECL (decl);
|
||||
xrefd_p = true;
|
||||
}
|
||||
|
||||
if (!TYPE_BINFO (TREE_TYPE (decl)))
|
||||
{
|
||||
error ("`%T' is not a class or union type", decl);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* For a definition, we want to enter the containing scope before
|
||||
looking up any base classes etc. Only do so, if this is different
|
||||
to the current scope. */
|
||||
context = CP_DECL_CONTEXT (decl);
|
||||
|
||||
new_type_p = (current != context
|
||||
&& TREE_CODE (context) != TEMPLATE_TYPE_PARM
|
||||
&& TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM);
|
||||
if (new_type_p)
|
||||
push_scope (context);
|
||||
|
||||
if (!xrefd_p
|
||||
&& PROCESSING_REAL_TEMPLATE_DECL_P ()
|
||||
&& !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
|
||||
decl = push_template_decl (decl);
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
#include "gt-cp-decl2.h"
|
||||
|
22
gcc/cp/lex.c
22
gcc/cp/lex.c
@ -506,28 +506,6 @@ interface_strcmp (const char* s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
note_got_semicolon (tree type)
|
||||
{
|
||||
if (!TYPE_P (type))
|
||||
abort ();
|
||||
if (CLASS_TYPE_P (type))
|
||||
CLASSTYPE_GOT_SEMICOLON (type) = 1;
|
||||
}
|
||||
|
||||
void
|
||||
note_list_got_semicolon (tree declspecs)
|
||||
{
|
||||
tree link;
|
||||
|
||||
for (link = declspecs; link; link = TREE_CHAIN (link))
|
||||
{
|
||||
tree type = TREE_VALUE (link);
|
||||
if (type && TYPE_P (type))
|
||||
note_got_semicolon (type);
|
||||
}
|
||||
clear_anon_tags ();
|
||||
}
|
||||
|
||||
|
||||
/* Parse a #pragma whose sole argument is a string constant.
|
||||
|
160
gcc/cp/parser.c
160
gcc/cp/parser.c
@ -1405,13 +1405,13 @@ static void cp_parser_block_declaration
|
||||
static void cp_parser_simple_declaration
|
||||
(cp_parser *, bool);
|
||||
static tree cp_parser_decl_specifier_seq
|
||||
(cp_parser *, cp_parser_flags, tree *, bool *);
|
||||
(cp_parser *, cp_parser_flags, tree *, int *);
|
||||
static tree cp_parser_storage_class_specifier_opt
|
||||
(cp_parser *);
|
||||
static tree cp_parser_function_specifier_opt
|
||||
(cp_parser *);
|
||||
static tree cp_parser_type_specifier
|
||||
(cp_parser *, cp_parser_flags, bool, bool, bool *, bool *);
|
||||
(cp_parser *, cp_parser_flags, bool, bool, int *, bool *);
|
||||
static tree cp_parser_simple_type_specifier
|
||||
(cp_parser *, cp_parser_flags);
|
||||
static tree cp_parser_type_name
|
||||
@ -1446,7 +1446,7 @@ static void cp_parser_linkage_specification
|
||||
/* Declarators [gram.dcl.decl] */
|
||||
|
||||
static tree cp_parser_init_declarator
|
||||
(cp_parser *, tree, tree, bool, bool, bool *);
|
||||
(cp_parser *, tree, tree, bool, bool, int, bool *);
|
||||
static tree cp_parser_declarator
|
||||
(cp_parser *, cp_parser_declarator_kind, int *);
|
||||
static tree cp_parser_direct_declarator
|
||||
@ -1674,6 +1674,8 @@ static bool cp_parser_simulate_error
|
||||
(cp_parser *);
|
||||
static void cp_parser_check_type_definition
|
||||
(cp_parser *);
|
||||
static void cp_parser_check_for_definition_in_return_type
|
||||
(tree, int);
|
||||
static tree cp_parser_non_constant_expression
|
||||
(const char *);
|
||||
static bool cp_parser_diagnose_invalid_type_name
|
||||
@ -1763,6 +1765,28 @@ cp_parser_check_type_definition (cp_parser* parser)
|
||||
error ("%s", parser->type_definition_forbidden_message);
|
||||
}
|
||||
|
||||
/* This function is called when a declaration is parsed. If
|
||||
DECLARATOR is a function declarator and DECLARES_CLASS_OR_ENUM
|
||||
indicates that a type was defined in the decl-specifiers for DECL,
|
||||
then an error is issued. */
|
||||
|
||||
static void
|
||||
cp_parser_check_for_definition_in_return_type (tree declarator,
|
||||
int declares_class_or_enum)
|
||||
{
|
||||
/* [dcl.fct] forbids type definitions in return types.
|
||||
Unfortunately, it's not easy to know whether or not we are
|
||||
processing a return type until after the fact. */
|
||||
while (declarator
|
||||
&& (TREE_CODE (declarator) == INDIRECT_REF
|
||||
|| TREE_CODE (declarator) == ADDR_EXPR))
|
||||
declarator = TREE_OPERAND (declarator, 0);
|
||||
if (declarator
|
||||
&& TREE_CODE (declarator) == CALL_EXPR
|
||||
&& declares_class_or_enum & 2)
|
||||
error ("new types may not be defined in a return type");
|
||||
}
|
||||
|
||||
/* Issue an eror message about the fact that THING appeared in a
|
||||
constant-expression. Returns ERROR_MARK_NODE. */
|
||||
|
||||
@ -6041,7 +6065,7 @@ cp_parser_simple_declaration (cp_parser* parser,
|
||||
{
|
||||
tree decl_specifiers;
|
||||
tree attributes;
|
||||
bool declares_class_or_enum;
|
||||
int declares_class_or_enum;
|
||||
bool saw_declarator;
|
||||
|
||||
/* Defer access checks until we know what is being declared; the
|
||||
@ -6100,13 +6124,15 @@ cp_parser_simple_declaration (cp_parser* parser,
|
||||
{
|
||||
cp_token *token;
|
||||
bool function_definition_p;
|
||||
tree decl;
|
||||
|
||||
saw_declarator = true;
|
||||
/* Parse the init-declarator. */
|
||||
cp_parser_init_declarator (parser, decl_specifiers, attributes,
|
||||
function_definition_allowed_p,
|
||||
/*member_p=*/false,
|
||||
&function_definition_p);
|
||||
decl = cp_parser_init_declarator (parser, decl_specifiers, attributes,
|
||||
function_definition_allowed_p,
|
||||
/*member_p=*/false,
|
||||
declares_class_or_enum,
|
||||
&function_definition_p);
|
||||
/* If an error occurred while parsing tentatively, exit quickly.
|
||||
(That usually happens when in the body of a function; each
|
||||
statement is treated as a declaration-statement until proven
|
||||
@ -6170,10 +6196,6 @@ cp_parser_simple_declaration (cp_parser* parser,
|
||||
/* Consume the `;'. */
|
||||
cp_parser_require (parser, CPP_SEMICOLON, "`;'");
|
||||
|
||||
/* Mark all the classes that appeared in the decl-specifier-seq as
|
||||
having received a `;'. */
|
||||
note_list_got_semicolon (decl_specifiers);
|
||||
|
||||
done:
|
||||
pop_deferring_access_checks ();
|
||||
}
|
||||
@ -6208,20 +6230,29 @@ cp_parser_simple_declaration (cp_parser* parser,
|
||||
appears, and the entity that will be a friend is not going to be a
|
||||
class, then *FRIEND_IS_NOT_CLASS_P will be set to TRUE. Note that
|
||||
even if *FRIEND_IS_NOT_CLASS_P is FALSE, the entity to which
|
||||
friendship is granted might not be a class. */
|
||||
friendship is granted might not be a class.
|
||||
|
||||
*DECLARES_CLASS_OR_ENUM is set to the bitwise or of the following
|
||||
*flags:
|
||||
|
||||
1: one of the decl-specifiers is an elaborated-type-specifier
|
||||
2: one of the decl-specifiers is an enum-specifier or a
|
||||
class-specifier
|
||||
|
||||
*/
|
||||
|
||||
static tree
|
||||
cp_parser_decl_specifier_seq (cp_parser* parser,
|
||||
cp_parser_flags flags,
|
||||
tree* attributes,
|
||||
bool* declares_class_or_enum)
|
||||
int* declares_class_or_enum)
|
||||
{
|
||||
tree decl_specs = NULL_TREE;
|
||||
bool friend_p = false;
|
||||
bool constructor_possible_p = !parser->in_declarator_p;
|
||||
|
||||
/* Assume no class or enumeration type is declared. */
|
||||
*declares_class_or_enum = false;
|
||||
*declares_class_or_enum = 0;
|
||||
|
||||
/* Assume there are no attributes. */
|
||||
*attributes = NULL_TREE;
|
||||
@ -6317,7 +6348,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
|
||||
a type-specifier. */
|
||||
if (!decl_spec && !constructor_p)
|
||||
{
|
||||
bool decl_spec_declares_class_or_enum;
|
||||
int decl_spec_declares_class_or_enum;
|
||||
bool is_cv_qualifier;
|
||||
|
||||
decl_spec
|
||||
@ -7913,7 +7944,7 @@ cp_parser_template_argument (cp_parser* parser)
|
||||
static void
|
||||
cp_parser_explicit_instantiation (cp_parser* parser)
|
||||
{
|
||||
bool declares_class_or_enum;
|
||||
int declares_class_or_enum;
|
||||
tree decl_specifiers;
|
||||
tree attributes;
|
||||
tree extension_specifier = NULL_TREE;
|
||||
@ -7965,6 +7996,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
|
||||
declarator
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
/*ctor_dtor_or_conv_p=*/NULL);
|
||||
cp_parser_check_for_definition_in_return_type (declarator,
|
||||
declares_class_or_enum);
|
||||
decl = grokdeclarator (declarator, decl_specifiers,
|
||||
NORMAL, 0, NULL);
|
||||
/* Turn access control back on for names used during
|
||||
@ -8055,8 +8088,9 @@ cp_parser_explicit_specialization (cp_parser* parser)
|
||||
|
||||
If DECLARES_CLASS_OR_ENUM is non-NULL, and the type-specifier is a
|
||||
class-specifier, enum-specifier, or elaborated-type-specifier, then
|
||||
*DECLARES_CLASS_OR_ENUM is set to TRUE. Otherwise, it is set to
|
||||
FALSE.
|
||||
*DECLARES_CLASS_OR_ENUM is set to a non-zero value. The value is 1
|
||||
if a type is declared; 2 if it is defined. Otherwise, it is set to
|
||||
zero.
|
||||
|
||||
If IS_CV_QUALIFIER is non-NULL, and the type-specifier is a
|
||||
cv-qualifier, then IS_CV_QUALIFIER is set to TRUE. Otherwise, it
|
||||
@ -8067,7 +8101,7 @@ cp_parser_type_specifier (cp_parser* parser,
|
||||
cp_parser_flags flags,
|
||||
bool is_friend,
|
||||
bool is_declaration,
|
||||
bool* declares_class_or_enum,
|
||||
int* declares_class_or_enum,
|
||||
bool* is_cv_qualifier)
|
||||
{
|
||||
tree type_spec = NULL_TREE;
|
||||
@ -8107,7 +8141,7 @@ cp_parser_type_specifier (cp_parser* parser,
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
{
|
||||
if (declares_class_or_enum)
|
||||
*declares_class_or_enum = true;
|
||||
*declares_class_or_enum = 2;
|
||||
return type_spec;
|
||||
}
|
||||
|
||||
@ -8121,7 +8155,7 @@ cp_parser_type_specifier (cp_parser* parser,
|
||||
/* We're declaring a class or enum -- unless we're using
|
||||
`typename'. */
|
||||
if (declares_class_or_enum && keyword != RID_TYPENAME)
|
||||
*declares_class_or_enum = true;
|
||||
*declares_class_or_enum = 1;
|
||||
return type_spec;
|
||||
|
||||
case RID_CONST:
|
||||
@ -8512,13 +8546,13 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
|
||||
error ("expected type-name");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE
|
||||
&& tag_type != enum_type)
|
||||
error ("`%T' referred to as `%s'", TREE_TYPE (decl),
|
||||
tag_type == record_type ? "struct" : "class");
|
||||
else if (TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
|
||||
&& tag_type == enum_type)
|
||||
error ("`%T' referred to as enum", TREE_TYPE (decl));
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
|
||||
check_elaborated_type_specifier
|
||||
(tag_type,
|
||||
TREE_TYPE (decl),
|
||||
(parser->num_template_parameter_lists
|
||||
|| DECL_SELF_REFERENCE_P (decl)));
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
}
|
||||
@ -9161,6 +9195,7 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
tree prefix_attributes,
|
||||
bool function_definition_allowed_p,
|
||||
bool member_p,
|
||||
int declares_class_or_enum,
|
||||
bool* function_definition_p)
|
||||
{
|
||||
cp_token *token;
|
||||
@ -9198,6 +9233,9 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
if (declarator == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
cp_parser_check_for_definition_in_return_type (declarator,
|
||||
declares_class_or_enum);
|
||||
|
||||
/* Figure out what scope the entity declared by the DECLARATOR is
|
||||
located in. `grokdeclarator' sometimes changes the scope, so
|
||||
we compute it now. */
|
||||
@ -10326,7 +10364,7 @@ static tree
|
||||
cp_parser_parameter_declaration (cp_parser *parser,
|
||||
bool template_parm_p)
|
||||
{
|
||||
bool declares_class_or_enum;
|
||||
int declares_class_or_enum;
|
||||
bool greater_than_is_operator_p;
|
||||
tree decl_specifiers;
|
||||
tree attributes;
|
||||
@ -10561,7 +10599,7 @@ cp_parser_function_definition (cp_parser* parser, bool* friend_p)
|
||||
tree declarator;
|
||||
tree fn;
|
||||
cp_token *token;
|
||||
bool declares_class_or_enum;
|
||||
int declares_class_or_enum;
|
||||
bool member_p;
|
||||
/* The saved value of the PEDANTIC flag. */
|
||||
int saved_pedantic;
|
||||
@ -10635,6 +10673,9 @@ cp_parser_function_definition (cp_parser* parser, bool* friend_p)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
cp_parser_check_for_definition_in_return_type (declarator,
|
||||
declares_class_or_enum);
|
||||
|
||||
/* If we are in a class scope, then we must handle
|
||||
function-definitions specially. In particular, we save away the
|
||||
tokens that make up the function body, and parse them again
|
||||
@ -11126,11 +11167,16 @@ cp_parser_class_specifier (cp_parser* parser)
|
||||
/* Look for attributes to apply to this class. */
|
||||
if (cp_parser_allow_gnu_extensions_p (parser))
|
||||
attributes = cp_parser_attributes_opt (parser);
|
||||
/* Finish the class definition. */
|
||||
type = finish_class_definition (type,
|
||||
attributes,
|
||||
has_trailing_semicolon,
|
||||
nested_name_specifier_p);
|
||||
/* If we got any attributes in class_head, xref_tag will stick them in
|
||||
TREE_TYPE of the type. Grab them now. */
|
||||
if (type != error_mark_node)
|
||||
{
|
||||
attributes = chainon (TYPE_ATTRIBUTES (type), attributes);
|
||||
TYPE_ATTRIBUTES (type) = NULL_TREE;
|
||||
type = finish_struct (type, attributes);
|
||||
}
|
||||
if (nested_name_specifier_p)
|
||||
pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
|
||||
/* If this class is not itself within the scope of another class,
|
||||
then we need to parse the bodies of all of the queued function
|
||||
definitions. Note that the queued functions defined in a class
|
||||
@ -11444,21 +11490,31 @@ cp_parser_class_head (cp_parser* parser,
|
||||
"enclose `%D'", type, scope, nested_name_specifier);
|
||||
return NULL_TREE;
|
||||
}
|
||||
/* [dcl.meaning]
|
||||
|
||||
A declarator-id shall not be qualified exception of the
|
||||
definition of a ... nested class outside of its class
|
||||
... [or] a the definition or explicit instantiation of a
|
||||
class member of a namespace outside of its namespace. */
|
||||
if (scope == CP_DECL_CONTEXT (type))
|
||||
{
|
||||
pedwarn ("extra qualification ignored");
|
||||
nested_name_specifier = NULL_TREE;
|
||||
}
|
||||
|
||||
maybe_process_partial_specialization (TREE_TYPE (type));
|
||||
class_type = current_class_type;
|
||||
type = TREE_TYPE (handle_class_head (class_key,
|
||||
nested_name_specifier,
|
||||
type,
|
||||
attributes));
|
||||
if (type != error_mark_node)
|
||||
{
|
||||
if (!class_type && TYPE_CONTEXT (type))
|
||||
*nested_name_specifier_p = true;
|
||||
else if (class_type && !same_type_p (TYPE_CONTEXT (type),
|
||||
class_type))
|
||||
*nested_name_specifier_p = true;
|
||||
}
|
||||
/* Enter the scope indicated by the nested-name-specifier. */
|
||||
if (nested_name_specifier)
|
||||
push_scope (nested_name_specifier);
|
||||
/* Get the canonical version of this type. */
|
||||
type = TYPE_MAIN_DECL (TREE_TYPE (type));
|
||||
if (PROCESSING_REAL_TEMPLATE_DECL_P ()
|
||||
&& !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
|
||||
type = push_template_decl (type);
|
||||
type = TREE_TYPE (type);
|
||||
if (nested_name_specifier)
|
||||
*nested_name_specifier_p = true;
|
||||
}
|
||||
/* Indicate whether this class was declared as a `class' or as a
|
||||
`struct'. */
|
||||
@ -11599,7 +11655,7 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
tree decl_specifiers;
|
||||
tree prefix_attributes;
|
||||
tree decl;
|
||||
bool declares_class_or_enum;
|
||||
int declares_class_or_enum;
|
||||
bool friend_p;
|
||||
cp_token *token;
|
||||
int saved_pedantic;
|
||||
@ -11812,6 +11868,9 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
break;
|
||||
}
|
||||
|
||||
cp_parser_check_for_definition_in_return_type
|
||||
(declarator, declares_class_or_enum);
|
||||
|
||||
/* Look for an asm-specification. */
|
||||
asm_specification = cp_parser_asm_specification_opt (parser);
|
||||
/* Look for attributes that apply to the declaration. */
|
||||
@ -13543,7 +13602,7 @@ cp_parser_single_declaration (cp_parser* parser,
|
||||
bool member_p,
|
||||
bool* friend_p)
|
||||
{
|
||||
bool declares_class_or_enum;
|
||||
int declares_class_or_enum;
|
||||
tree decl = NULL_TREE;
|
||||
tree decl_specifiers;
|
||||
tree attributes;
|
||||
@ -13592,6 +13651,7 @@ cp_parser_single_declaration (cp_parser* parser,
|
||||
attributes,
|
||||
/*function_definition_allowed_p=*/false,
|
||||
member_p,
|
||||
declares_class_or_enum,
|
||||
/*function_definition_p=*/NULL);
|
||||
|
||||
pop_deferring_access_checks ();
|
||||
|
34
gcc/cp/pt.c
34
gcc/cp/pt.c
@ -100,7 +100,6 @@ static void reopen_tinst_level (tree);
|
||||
static tree classtype_mangled_name (tree);
|
||||
static char* mangle_class_name_for_template (const char *, tree, tree);
|
||||
static tree tsubst_initializer_list (tree, tree);
|
||||
static int list_eq (tree, tree);
|
||||
static tree get_class_bindings (tree, tree, tree);
|
||||
static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, int);
|
||||
static void tsubst_enum (tree, tree, tree);
|
||||
@ -4227,7 +4226,6 @@ lookup_template_class (tree d1,
|
||||
t = make_aggr_type (TREE_CODE (template_type));
|
||||
CLASSTYPE_DECLARED_CLASS (t)
|
||||
= CLASSTYPE_DECLARED_CLASS (template_type);
|
||||
CLASSTYPE_GOT_SEMICOLON (t) = 1;
|
||||
SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
|
||||
TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type);
|
||||
|
||||
@ -5141,9 +5139,6 @@ instantiate_class_template (tree type)
|
||||
|
||||
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
|
||||
TYPE_HAS_DESTRUCTOR (type) = TYPE_HAS_DESTRUCTOR (pattern);
|
||||
TYPE_OVERLOADS_CALL_EXPR (type) = TYPE_OVERLOADS_CALL_EXPR (pattern);
|
||||
TYPE_OVERLOADS_ARRAY_REF (type) = TYPE_OVERLOADS_ARRAY_REF (pattern);
|
||||
TYPE_OVERLOADS_ARROW (type) = TYPE_OVERLOADS_ARROW (pattern);
|
||||
TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
|
||||
TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
|
||||
TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
|
||||
@ -5385,7 +5380,6 @@ instantiate_class_template (tree type)
|
||||
|
||||
unreverse_member_declarations (type);
|
||||
finish_struct_1 (type);
|
||||
CLASSTYPE_GOT_SEMICOLON (type) = 1;
|
||||
|
||||
/* Clear this now so repo_template_used is happy. */
|
||||
TYPE_BEING_DEFINED (type) = 0;
|
||||
@ -5414,21 +5408,6 @@ instantiate_class_template (tree type)
|
||||
return type;
|
||||
}
|
||||
|
||||
static int
|
||||
list_eq (tree t1, tree t2)
|
||||
{
|
||||
if (t1 == NULL_TREE)
|
||||
return t2 == NULL_TREE;
|
||||
if (t2 == NULL_TREE)
|
||||
return 0;
|
||||
/* Don't care if one declares its arg const and the other doesn't -- the
|
||||
main variant of the arg type is all that matters. */
|
||||
if (TYPE_MAIN_VARIANT (TREE_VALUE (t1))
|
||||
!= TYPE_MAIN_VARIANT (TREE_VALUE (t2)))
|
||||
return 0;
|
||||
return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2));
|
||||
}
|
||||
|
||||
static tree
|
||||
tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
{
|
||||
@ -6020,11 +5999,14 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
|
||||
TREE_TYPE (r) = type;
|
||||
c_apply_type_quals_to_decl (cp_type_quals (type), r);
|
||||
|
||||
if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
|
||||
DECL_INITIAL (r) = TREE_TYPE (r);
|
||||
else
|
||||
DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
|
||||
complain, in_decl);
|
||||
if (DECL_INITIAL (r))
|
||||
{
|
||||
if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
|
||||
DECL_INITIAL (r) = TREE_TYPE (r);
|
||||
else
|
||||
DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
|
||||
complain, in_decl);
|
||||
}
|
||||
|
||||
DECL_CONTEXT (r) = NULL_TREE;
|
||||
|
||||
|
@ -123,12 +123,6 @@ cxx_print_type (FILE *file, tree node, int indent)
|
||||
fputs (" delete[]", file);
|
||||
if (TYPE_HAS_ASSIGN_REF (node))
|
||||
fputs (" this=(X&)", file);
|
||||
if (TYPE_OVERLOADS_CALL_EXPR (node))
|
||||
fputs (" op()", file);
|
||||
if (TYPE_OVERLOADS_ARRAY_REF (node))
|
||||
fputs (" op[]", file);
|
||||
if (TYPE_OVERLOADS_ARROW (node))
|
||||
fputs (" op->", file);
|
||||
if (TYPE_USES_MULTIPLE_INHERITANCE (node))
|
||||
fputs (" uses-multiple-inheritance", file);
|
||||
|
||||
|
@ -2133,41 +2133,6 @@ finish_member_declaration (tree decl)
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish a class definition T with the indicate ATTRIBUTES. If SEMI,
|
||||
the definition is immediately followed by a semicolon. Returns the
|
||||
type. */
|
||||
|
||||
tree
|
||||
finish_class_definition (tree t, tree attributes, int semi, int pop_scope_p)
|
||||
{
|
||||
if (t == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* finish_struct nukes this anyway; if finish_exception does too,
|
||||
then it can go. */
|
||||
if (semi)
|
||||
note_got_semicolon (t);
|
||||
|
||||
/* If we got any attributes in class_head, xref_tag will stick them in
|
||||
TREE_TYPE of the type. Grab them now. */
|
||||
attributes = chainon (TYPE_ATTRIBUTES (t), attributes);
|
||||
TYPE_ATTRIBUTES (t) = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (t) == ENUMERAL_TYPE)
|
||||
;
|
||||
else
|
||||
{
|
||||
t = finish_struct (t, attributes);
|
||||
if (semi)
|
||||
note_got_semicolon (t);
|
||||
}
|
||||
|
||||
if (pop_scope_p)
|
||||
pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (t)));
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Finish processing the declaration of a member class template
|
||||
TYPES whose template parameters are given by PARMS. */
|
||||
|
||||
@ -2183,7 +2148,6 @@ finish_member_class_template (tree types)
|
||||
if (IS_AGGR_TYPE_CODE (TREE_CODE (TREE_VALUE (t))))
|
||||
maybe_process_partial_specialization (TREE_VALUE (t));
|
||||
|
||||
note_list_got_semicolon (types);
|
||||
grok_x_components (types);
|
||||
if (TYPE_CONTEXT (TREE_VALUE (types)) != current_class_type)
|
||||
/* The component was in fact a friend declaration. We avoid
|
||||
|
@ -1,3 +1,18 @@
|
||||
2003-08-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* g++.dg/parse/ret-type2.C: New test.
|
||||
|
||||
PR c++/11703
|
||||
* g++.dg/init/new8.C: New test.
|
||||
|
||||
PR c++/10923
|
||||
* g++.dg/parse/typedef5.C: New test.
|
||||
|
||||
PR c++/9512
|
||||
* g++.dg/parse/qualified2.C: New test.
|
||||
* g++.old-deja/g++.other/decl5.C: Mark one more instance of
|
||||
invalid code.
|
||||
|
||||
2003-08-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* g++.dg/conversion/ptrmem1.C: New test.
|
||||
|
17
gcc/testsuite/g++.dg/init/new8.C
Normal file
17
gcc/testsuite/g++.dg/init/new8.C
Normal file
@ -0,0 +1,17 @@
|
||||
typedef unsigned int size_t;
|
||||
|
||||
enum Refcount_Type {
|
||||
NO_REFCOUNT
|
||||
};
|
||||
|
||||
struct d0_Unknown_Object
|
||||
{
|
||||
void* operator new (size_t, size_t, Refcount_Type type);
|
||||
void operator delete (void*, size_t, Refcount_Type);
|
||||
d0_Unknown_Object ();
|
||||
};
|
||||
|
||||
void make ()
|
||||
{
|
||||
new (10, NO_REFCOUNT) d0_Unknown_Object;
|
||||
}
|
4
gcc/testsuite/g++.dg/parse/qualified2.C
Normal file
4
gcc/testsuite/g++.dg/parse/qualified2.C
Normal file
@ -0,0 +1,4 @@
|
||||
namespace Glib {
|
||||
template <typename> class Value {};
|
||||
template <> class Glib::Value<int> {}; // { dg-error "" }
|
||||
}
|
5
gcc/testsuite/g++.dg/parse/ret-type2.C
Normal file
5
gcc/testsuite/g++.dg/parse/ret-type2.C
Normal file
@ -0,0 +1,5 @@
|
||||
struct S {} f(); // { dg-error "" }
|
||||
struct T {} *g(); // { dg-error "" }
|
||||
struct U {} h() {} // { dg-error "" }
|
||||
struct V {} *i() {} // { dg-error "" }
|
||||
struct W {} (*p) (); // { dg-error "" }
|
6
gcc/testsuite/g++.dg/parse/typedef5.C
Normal file
6
gcc/testsuite/g++.dg/parse/typedef5.C
Normal file
@ -0,0 +1,6 @@
|
||||
namespace A
|
||||
{
|
||||
typedef int T;
|
||||
}
|
||||
|
||||
class A::T x; // { dg-error "" }
|
@ -11,7 +11,7 @@ struct A {
|
||||
int A::fn(); // { dg-warning "" } extra qualification
|
||||
int A::m; // { dg-warning "" } extra qualification
|
||||
struct e;
|
||||
struct A::e {int i;};
|
||||
struct A::e {int i;}; // { dg-warning "" } extra qualification
|
||||
struct A::expand { // { dg-warning "" } extra qualification
|
||||
int m;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user