aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-08-12 22:26:25 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-08-12 22:26:25 +0000
commit560ad596bdde2ca44f9890e9e1399b29736c63ea (patch)
tree98aa4b6b847333e82f9374a9201eb1371ef7d159 /gcc/cp
parent35e6511a747ac8fd49a70401ba99857b57c16e5c (diff)
downloadgcc-560ad596bdde2ca44f9890e9e1399b29736c63ea.zip
gcc-560ad596bdde2ca44f9890e9e1399b29736c63ea.tar.gz
gcc-560ad596bdde2ca44f9890e9e1399b29736c63ea.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog69
-rw-r--r--gcc/cp/call.c6
-rw-r--r--gcc/cp/class.c4
-rw-r--r--gcc/cp/cp-tree.h35
-rw-r--r--gcc/cp/decl.c37
-rw-r--r--gcc/cp/decl2.c98
-rw-r--r--gcc/cp/lex.c22
-rw-r--r--gcc/cp/parser.c160
-rw-r--r--gcc/cp/pt.c34
-rw-r--r--gcc/cp/ptree.c6
-rw-r--r--gcc/cp/semantics.c36
11 files changed, 204 insertions, 303 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d493d65..6a27652 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9ece67f..afdc291 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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;
}
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index bf16721..a224676 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a740142..934acb9 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9afa303..0619147 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 556f62a..54e627f 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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"
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 82a03e5..49b8311 100644
--- a/gcc/cp/lex.c
+++ b/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.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 94fea3d..b485fb5 100644
--- a/gcc/cp/parser.c
+++ b/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]
- 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)
+ 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))
{
- 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;
+ pedwarn ("extra qualification ignored");
+ nested_name_specifier = NULL_TREE;
}
+
+ maybe_process_partial_specialization (TREE_TYPE (type));
+ class_type = current_class_type;
+ /* 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 ();
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5eba7ad..edb43d9 100644
--- a/gcc/cp/pt.c
+++ b/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;
diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c
index 356ed45..6dbf060 100644
--- a/gcc/cp/ptree.c
+++ b/gcc/cp/ptree.c
@@ -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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0931e89..29d5dd7 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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