Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
a28e3c7f
Commit
a28e3c7f
authored
Apr 15, 1994
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
32nd Cygnus<->FSF merge
From-SVN: r7047
parent
7062b881
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
921 additions
and
1682 deletions
+921
-1682
gcc/cp/Makefile.in
+1
-1
gcc/cp/call.c
+5
-4
gcc/cp/class.c
+17
-8
gcc/cp/cp-tree.def
+2
-0
gcc/cp/cp-tree.h
+25
-18
gcc/cp/cvt.c
+10
-1
gcc/cp/decl.c
+264
-157
gcc/cp/decl2.c
+16
-6
gcc/cp/gxxint.texi
+27
-13
gcc/cp/init.c
+41
-48
gcc/cp/lex.c
+17
-12
gcc/cp/lex.h
+3
-0
gcc/cp/method.c
+25
-30
gcc/cp/parse.y
+361
-598
gcc/cp/pt.c
+38
-15
gcc/cp/ptree.c
+8
-4
gcc/cp/search.c
+39
-25
gcc/cp/spew.c
+22
-742
No files found.
gcc/cp/Makefile.in
View file @
a28e3c7f
...
@@ -200,7 +200,7 @@ parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) ../flags.h lex.h
...
@@ -200,7 +200,7 @@ parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) ../flags.h lex.h
`
echo
$(srcdir)
/parse.c | sed
's,^\./,,'
`
`
echo
$(srcdir)
/parse.c | sed
's,^\./,,'
`
$(srcdir)/parse.c $(srcdir)/parse.h
:
$(srcdir)/parse.y
$(srcdir)/parse.c $(srcdir)/parse.h
:
$(srcdir)/parse.y
@
echo
expect
24
reduce/reduce conflicts.
@
echo
expect
33
reduce/reduce conflicts.
cd
$(srcdir)
;
$(BISON)
$(BISONFLAGS)
-d
-o
parse.c parse.y
cd
$(srcdir)
;
$(BISON)
$(BISONFLAGS)
-d
-o
parse.c parse.y
cd
$(srcdir)
;
grep
'^#define[ ]*YYEMPTY'
parse.c
>>
parse.h
cd
$(srcdir)
;
grep
'^#define[ ]*YYEMPTY'
parse.c
>>
parse.h
...
...
gcc/cp/call.c
View file @
a28e3c7f
...
@@ -2673,10 +2673,7 @@ build_scoped_method_call (exp, scopes, name, parms)
...
@@ -2673,10 +2673,7 @@ build_scoped_method_call (exp, scopes, name, parms)
{
{
/* Explicit call to destructor. */
/* Explicit call to destructor. */
name
=
TREE_OPERAND
(
name
,
0
);
name
=
TREE_OPERAND
(
name
,
0
);
if
(
TREE_TYPE
(
decl
)
!=
if
(
name
!=
constructor_name
(
TREE_TYPE
(
decl
)))
(
IDENTIFIER_CLASS_VALUE
(
name
)
?
IDENTIFIER_CLASS_TYPE_VALUE
(
name
)
:
IDENTIFIER_TYPE_VALUE
(
name
)))
{
{
cp_error
cp_error
(
"qualified type `%T' does not match destructor type `%T'"
,
(
"qualified type `%T' does not match destructor type `%T'"
,
...
@@ -2808,6 +2805,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
...
@@ -2808,6 +2805,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* If it doesn't work, two argument delete must work */
/* If it doesn't work, two argument delete must work */
TREE_CHAIN
(
parms
)
=
save_last
;
TREE_CHAIN
(
parms
)
=
save_last
;
}
}
/* We already know whether it's needed or not for vec delete. */
else
if
(
name
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
]
&&
!
TYPE_VEC_DELETE_TAKES_SIZE
(
TREE_TYPE
(
instance
)))
TREE_CHAIN
(
parms
)
=
NULL_TREE
;
if
(
TREE_CODE
(
name
)
==
BIT_NOT_EXPR
)
if
(
TREE_CODE
(
name
)
==
BIT_NOT_EXPR
)
{
{
...
...
gcc/cp/class.c
View file @
a28e3c7f
...
@@ -2494,7 +2494,9 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
...
@@ -2494,7 +2494,9 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
for
(
x
=
*
testp
;
x
;
x
=
DECL_CHAIN
(
x
))
for
(
x
=
*
testp
;
x
;
x
=
DECL_CHAIN
(
x
))
{
{
if
(
DECL_NAME
(
fn_fields
)
==
ansi_opname
[(
int
)
DELETE_EXPR
])
if
(
DECL_NAME
(
fn_fields
)
==
ansi_opname
[(
int
)
DELETE_EXPR
]
||
DECL_NAME
(
fn_fields
)
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])
{
{
/* ANSI C++ June 5 1992 WP 12.5.5.1 */
/* ANSI C++ June 5 1992 WP 12.5.5.1 */
cp_error_at
(
"`%D' overloaded"
,
fn_fields
);
cp_error_at
(
"`%D' overloaded"
,
fn_fields
);
...
@@ -4149,8 +4151,10 @@ finish_struct (t, list_of_fieldlists, warn_anon)
...
@@ -4149,8 +4151,10 @@ finish_struct (t, list_of_fieldlists, warn_anon)
else
if
(
flag_dossier
&&
!
CLASSTYPE_DOSSIER
(
t
))
else
if
(
flag_dossier
&&
!
CLASSTYPE_DOSSIER
(
t
))
build_t_desc
(
t
,
1
);
build_t_desc
(
t
,
1
);
#if 0
if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
#endif
if
(
current_class_type
)
if
(
current_class_type
)
popclass
(
0
);
popclass
(
0
);
else
else
...
@@ -4426,10 +4430,7 @@ pushclass (type, modify)
...
@@ -4426,10 +4430,7 @@ pushclass (type, modify)
current_function_decl
=
NULL_TREE
;
current_function_decl
=
NULL_TREE
;
if
(
TREE_CODE
(
type
)
==
UNINSTANTIATED_P_TYPE
)
if
(
TREE_CODE
(
type
)
==
UNINSTANTIATED_P_TYPE
)
{
declare_uninstantiated_type_level
();
declare_uninstantiated_type_level
();
overload_template_name
(
current_class_name
,
0
);
}
else
if
(
type
!=
previous_class_type
||
current_class_depth
>
1
)
else
if
(
type
!=
previous_class_type
||
current_class_depth
>
1
)
{
{
build_mi_matrix
(
type
);
build_mi_matrix
(
type
);
...
@@ -4457,6 +4458,9 @@ pushclass (type, modify)
...
@@ -4457,6 +4458,9 @@ pushclass (type, modify)
unuse_fields
(
type
);
unuse_fields
(
type
);
}
}
if
(
IDENTIFIER_TEMPLATE
(
TYPE_IDENTIFIER
(
type
)))
overload_template_name
(
current_class_name
,
0
);
for
(
tags
=
CLASSTYPE_TAGS
(
type
);
tags
;
tags
=
TREE_CHAIN
(
tags
))
for
(
tags
=
CLASSTYPE_TAGS
(
type
);
tags
;
tags
=
TREE_CHAIN
(
tags
))
{
{
TREE_NONLOCAL_FLAG
(
TREE_VALUE
(
tags
))
=
1
;
TREE_NONLOCAL_FLAG
(
TREE_VALUE
(
tags
))
=
1
;
...
@@ -4513,9 +4517,9 @@ popclass (modify)
...
@@ -4513,9 +4517,9 @@ popclass (modify)
TREE_NONLOCAL_FLAG
(
TREE_VALUE
(
tags
))
=
0
;
TREE_NONLOCAL_FLAG
(
TREE_VALUE
(
tags
))
=
0
;
tags
=
TREE_CHAIN
(
tags
);
tags
=
TREE_CHAIN
(
tags
);
}
}
if
(
IDENTIFIER_TEMPLATE
(
TYPE_IDENTIFIER
(
current_class_type
)))
undo_template_name_overload
(
current_class_name
,
0
);
}
}
if
(
TREE_CODE
(
current_class_type
)
==
UNINSTANTIATED_P_TYPE
)
undo_template_name_overload
(
current_class_name
,
0
);
poplevel_class
();
poplevel_class
();
...
@@ -4583,7 +4587,12 @@ push_nested_class (type, modify)
...
@@ -4583,7 +4587,12 @@ push_nested_class (type, modify)
tree
type
;
tree
type
;
int
modify
;
int
modify
;
{
{
tree
context
=
DECL_CONTEXT
(
TYPE_NAME
(
type
));
tree
context
;
if
(
type
==
error_mark_node
||
!
IS_AGGR_TYPE
(
type
))
return
;
context
=
DECL_CONTEXT
(
TYPE_NAME
(
type
));
if
(
context
&&
TREE_CODE
(
context
)
==
RECORD_TYPE
)
if
(
context
&&
TREE_CODE
(
context
)
==
RECORD_TYPE
)
push_nested_class
(
context
,
2
);
push_nested_class
(
context
,
2
);
...
...
gcc/cp/cp-tree.def
View file @
a28e3c7f
...
@@ -32,6 +32,7 @@ DEFTREECODE (CP_OFFSET_REF, "cp_offset_ref", "r", 2)
...
@@ -32,6 +32,7 @@ DEFTREECODE (CP_OFFSET_REF, "cp_offset_ref", "r", 2)
Operand 1 is the value to pass to the destroying function
Operand 1 is the value to pass to the destroying function
saying whether the store should be deallocated as well. */
saying whether the store should be deallocated as well. */
DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2)
DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2)
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", "e", 2)
/* Value is reference to particular overloaded class method.
/* Value is reference to particular overloaded class method.
Operand 0 is the class name (an IDENTIFIER_NODE);
Operand 0 is the class name (an IDENTIFIER_NODE);
...
@@ -52,6 +53,7 @@ DEFTREECODE (TYPE_EXPR, "type_expr", "e", 1)
...
@@ -52,6 +53,7 @@ DEFTREECODE (TYPE_EXPR, "type_expr", "e", 1)
operand 1 is argument list to initialization function,
operand 1 is argument list to initialization function,
and operand 2 is the slot which was allocated for this expression. */
and operand 2 is the slot which was allocated for this expression. */
DEFTREECODE (NEW_EXPR, "nw_expr", "e", 3)
DEFTREECODE (NEW_EXPR, "nw_expr", "e", 3)
DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", "e", 3)
/* Distinguish variables that are only used to identify exceptions
/* Distinguish variables that are only used to identify exceptions
that were caught. Only the DECL_NAME (and TREE_CHAIN)
that were caught. Only the DECL_NAME (and TREE_CHAIN)
...
...
gcc/cp/cp-tree.h
View file @
a28e3c7f
...
@@ -68,10 +68,6 @@ struct lang_id2
...
@@ -68,10 +68,6 @@ struct lang_id2
#define IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE))
#define IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE))
#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = TYPE)
#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = TYPE)
#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (TREE_TYPE (NODE) ? 1 : 0)
#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (TREE_TYPE (NODE) ? 1 : 0)
#define IDENTIFIER_HAS_CLASS_TYPE_VALUE(NODE) \
(IDENTIFIER_CLASS_VALUE (NODE) && TREE_TYPE (IDENTIFIER_CLASS_VALUE (NODE)))
#define IDENTIFIER_CLASS_TYPE_VALUE(NODE) \
TREE_TYPE (IDENTIFIER_CLASS_VALUE (NODE))
#define LANG_ID_FIELD(NAME,NODE) \
#define LANG_ID_FIELD(NAME,NODE) \
(((struct lang_identifier *)(NODE))->x \
(((struct lang_identifier *)(NODE))->x \
...
@@ -325,7 +321,7 @@ enum languages { lang_c, lang_cplusplus };
...
@@ -325,7 +321,7 @@ enum languages { lang_c, lang_cplusplus };
#define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
#define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
#define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t))
#define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t))
#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE)
#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE
|| t == UNINSTANTIATED_P_TYPE
)
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
(TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \
(TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \
&& IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2))
&& IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2))
...
@@ -395,14 +391,13 @@ struct lang_type
...
@@ -395,14 +391,13 @@ struct lang_type
unsigned
vtable_needs_writing
:
1
;
unsigned
vtable_needs_writing
:
1
;
unsigned
has_assign_ref
:
1
;
unsigned
has_assign_ref
:
1
;
unsigned
gets_new
:
1
;
unsigned
gets_new
:
2
;
unsigned
gets_placed_new
:
1
;
unsigned
gets_delete
:
2
;
unsigned
gets_delete
:
1
;
unsigned
has_call_overloaded
:
1
;
unsigned
has_call_overloaded
:
1
;
unsigned
has_array_ref_overloaded
:
1
;
unsigned
has_array_ref_overloaded
:
1
;
unsigned
has_arrow_overloaded
:
1
;
unsigned
has_arrow_overloaded
:
1
;
unsigned
local_typedecls
:
1
;
unsigned
local_typedecls
:
1
;
unsigned
interface_only
:
1
;
unsigned
interface_only
:
1
;
unsigned
interface_unknown
:
1
;
unsigned
interface_unknown
:
1
;
unsigned
needs_virtual_reinit
:
1
;
unsigned
needs_virtual_reinit
:
1
;
...
@@ -410,16 +405,16 @@ struct lang_type
...
@@ -410,16 +405,16 @@ struct lang_type
unsigned
declared_class
:
1
;
unsigned
declared_class
:
1
;
unsigned
being_defined
:
1
;
unsigned
being_defined
:
1
;
unsigned
redefined
:
1
;
unsigned
redefined
:
1
;
unsigned
no_globalize
:
1
;
unsigned
no_globalize
:
1
;
unsigned
marked
:
1
;
unsigned
marked
:
1
;
unsigned
marked2
:
1
;
unsigned
marked2
:
1
;
unsigned
marked3
:
1
;
unsigned
marked3
:
1
;
unsigned
marked4
:
1
;
unsigned
marked4
:
1
;
unsigned
marked5
:
1
;
unsigned
marked5
:
1
;
unsigned
marked6
:
1
;
unsigned
marked6
:
1
;
unsigned
use_template
:
2
;
unsigned
use_template
:
2
;
unsigned
debug_requested
:
1
;
unsigned
debug_requested
:
1
;
unsigned
has_method_call_overloaded
:
1
;
unsigned
has_method_call_overloaded
:
1
;
unsigned
private_attr
:
1
;
unsigned
private_attr
:
1
;
...
@@ -427,8 +422,8 @@ struct lang_type
...
@@ -427,8 +422,8 @@ struct lang_type
unsigned
ptrmemfunc_flag
:
1
;
unsigned
ptrmemfunc_flag
:
1
;
unsigned
is_signature
:
1
;
unsigned
is_signature
:
1
;
unsigned
is_signature_pointer
:
1
;
unsigned
is_signature_pointer
:
1
;
unsigned
is_signature_reference
:
1
;
unsigned
is_signature_reference
:
1
;
unsigned
has_default_implementation
:
1
;
unsigned
has_default_implementation
:
1
;
unsigned
grokking_typedef
:
1
;
unsigned
grokking_typedef
:
1
;
unsigned
has_opaque_typedecls
:
1
;
unsigned
has_opaque_typedecls
:
1
;
...
@@ -436,15 +431,16 @@ struct lang_type
...
@@ -436,15 +431,16 @@ struct lang_type
unsigned
was_anonymous
:
1
;
unsigned
was_anonymous
:
1
;
unsigned
has_real_assignment
:
1
;
unsigned
has_real_assignment
:
1
;
unsigned
has_real_assign_ref
:
1
;
unsigned
has_real_assign_ref
:
1
;
unsigned
has_const_init_ref
:
1
;
unsigned
has_const_init_ref
:
1
;
unsigned
has_complex_init_ref
:
1
;
unsigned
has_complex_init_ref
:
1
;
unsigned
has_complex_assign_ref
:
1
;
unsigned
has_complex_assign_ref
:
1
;
unsigned
vec_delete_takes_size
:
1
;
/* The MIPS compiler gets it wrong if this struct also
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
member `dummy' with new bits if you go over the edge. */
unsigned
dummy
:
2
2
;
unsigned
dummy
:
2
0
;
unsigned
n_vancestors
:
16
;
unsigned
n_vancestors
:
16
;
}
type_flags
;
}
type_flags
;
...
@@ -519,9 +515,17 @@ struct lang_type
...
@@ -519,9 +515,17 @@ struct lang_type
/* Nonzero for _CLASSTYPE means that operator new and delete are defined,
/* Nonzero for _CLASSTYPE means that operator new and delete are defined,
respectively. */
respectively. */
#define TREE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new)
#define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new)
#define TREE_GETS_PLACED_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_placed_new)
#define TYPE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete)
#define TREE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete)
#define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)
/* Nonzero for _CLASSTYPE means that operator vec delete is defined and
takes the optional size_t argument. */
#define TYPE_VEC_DELETE_TAKES_SIZE(NODE) \
(TYPE_LANG_SPECIFIC(NODE)->type_flags.vec_delete_takes_size)
#define TYPE_VEC_NEW_USES_COOKIE(NODE) \
(TYPE_NEEDS_DESTRUCTOR (NODE) \
|| (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (NODE)))
/* Nonzero for TREE_LIST or _TYPE node means that this node is class-local. */
/* Nonzero for TREE_LIST or _TYPE node means that this node is class-local. */
#define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE))
#define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE))
...
@@ -1972,7 +1976,7 @@ extern tree expand_vec_init PROTO((tree, tree, tree, tree, int));
...
@@ -1972,7 +1976,7 @@ extern tree expand_vec_init PROTO((tree, tree, tree, tree, int));
extern
tree
build_x_delete
PROTO
((
tree
,
tree
,
int
,
tree
));
extern
tree
build_x_delete
PROTO
((
tree
,
tree
,
int
,
tree
));
extern
tree
build_delete
PROTO
((
tree
,
tree
,
tree
,
int
,
int
));
extern
tree
build_delete
PROTO
((
tree
,
tree
,
tree
,
int
,
int
));
extern
tree
build_vbase_delete
PROTO
((
tree
,
tree
));
extern
tree
build_vbase_delete
PROTO
((
tree
,
tree
));
extern
tree
build_vec_delete
PROTO
((
tree
,
tree
,
tree
,
tree
,
tree
,
tree
));
extern
tree
build_vec_delete
PROTO
((
tree
,
tree
,
tree
,
tree
,
tree
,
int
));
/* in input.c */
/* in input.c */
...
@@ -2081,6 +2085,7 @@ extern int do_pending_expansions PROTO((void));
...
@@ -2081,6 +2085,7 @@ extern int do_pending_expansions PROTO((void));
extern
void
do_pending_templates
PROTO
((
void
));
extern
void
do_pending_templates
PROTO
((
void
));
struct
tinst_level
*
tinst_for_decl
PROTO
((
void
));
struct
tinst_level
*
tinst_for_decl
PROTO
((
void
));
extern
void
do_function_instantiation
PROTO
((
tree
,
tree
));
extern
void
do_function_instantiation
PROTO
((
tree
,
tree
));
extern
tree
create_nested_upt
PROTO
((
tree
,
tree
));
/* in search.c */
/* in search.c */
extern
tree
make_memoized_table_entry
PROTO
((
tree
,
tree
,
int
));
extern
tree
make_memoized_table_entry
PROTO
((
tree
,
tree
,
int
));
...
@@ -2092,6 +2097,7 @@ extern enum access_type compute_access PROTO((tree, tree));
...
@@ -2092,6 +2097,7 @@ extern enum access_type compute_access PROTO((tree, tree));
extern
tree
lookup_field
PROTO
((
tree
,
tree
,
int
,
int
));
extern
tree
lookup_field
PROTO
((
tree
,
tree
,
int
,
int
));
extern
tree
lookup_nested_field
PROTO
((
tree
,
int
));
extern
tree
lookup_nested_field
PROTO
((
tree
,
int
));
extern
tree
lookup_fnfields
PROTO
((
tree
,
tree
,
int
));
extern
tree
lookup_fnfields
PROTO
((
tree
,
tree
,
int
));
extern
tree
lookup_nested_tag
PROTO
((
tree
,
tree
));
extern
HOST_WIDE_INT
breadth_first_search
PROTO
((
tree
,
int
(
*
)(),
int
(
*
)()));
extern
HOST_WIDE_INT
breadth_first_search
PROTO
((
tree
,
int
(
*
)(),
int
(
*
)()));
extern
int
tree_needs_constructor_p
PROTO
((
tree
,
int
));
extern
int
tree_needs_constructor_p
PROTO
((
tree
,
int
));
extern
int
tree_has_any_destructor_p
PROTO
((
tree
,
int
));
extern
int
tree_has_any_destructor_p
PROTO
((
tree
,
int
));
...
@@ -2193,6 +2199,7 @@ extern int comp_target_types PROTO((tree, tree, int));
...
@@ -2193,6 +2199,7 @@ extern int comp_target_types PROTO((tree, tree, int));
extern
tree
common_base_types
PROTO
((
tree
,
tree
));
extern
tree
common_base_types
PROTO
((
tree
,
tree
));
extern
int
compparms
PROTO
((
tree
,
tree
,
int
));
extern
int
compparms
PROTO
((
tree
,
tree
,
int
));
extern
int
comp_target_types
PROTO
((
tree
,
tree
,
int
));
extern
int
comp_target_types
PROTO
((
tree
,
tree
,
int
));
extern
int
self_promoting_args_p
PROTO
((
tree
));
extern
tree
unsigned_type
PROTO
((
tree
));
extern
tree
unsigned_type
PROTO
((
tree
));
extern
tree
signed_type
PROTO
((
tree
));
extern
tree
signed_type
PROTO
((
tree
));
extern
tree
signed_or_unsigned_type
PROTO
((
int
,
tree
));
extern
tree
signed_or_unsigned_type
PROTO
((
int
,
tree
));
...
...
gcc/cp/cvt.c
View file @
a28e3c7f
...
@@ -720,8 +720,16 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
...
@@ -720,8 +720,16 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
{
{
/* When casting an lvalue to a reference type, just convert into
/* When casting an lvalue to a reference type, just convert into
a pointer to the new type and deference it. This is allowed
a pointer to the new type and deference it. This is allowed
by San Diego WP section 5.2.
8 paragraph 9
, though perhaps it
by San Diego WP section 5.2.
9 paragraph 12
, though perhaps it
should be done directly (jason). (int &)ri ---> *(int*)&ri */
should be done directly (jason). (int &)ri ---> *(int*)&ri */
/* B* bp; A& ar = (A&)bp; is legal, but it's probably not what they
meant. */
if
(
form
==
POINTER_TYPE
&&
(
comptypes
(
TREE_TYPE
(
intype
),
type
,
strict
)))
cp_warning
(
"casting `%T' to `%T' does not dereference pointer"
,
intype
,
reftype
);
rval
=
build_unary_op
(
ADDR_EXPR
,
expr
,
0
);
rval
=
build_unary_op
(
ADDR_EXPR
,
expr
,
0
);
if
(
rval
!=
error_mark_node
)
if
(
rval
!=
error_mark_node
)
rval
=
convert_force
(
build_pointer_type
(
TREE_TYPE
(
reftype
)),
rval
);
rval
=
convert_force
(
build_pointer_type
(
TREE_TYPE
(
reftype
)),
rval
);
...
@@ -744,6 +752,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
...
@@ -744,6 +752,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
/* Definitely need to go through a constructor here. */
/* Definitely need to go through a constructor here. */
if
(
TYPE_HAS_CONSTRUCTOR
(
type
)
if
(
TYPE_HAS_CONSTRUCTOR
(
type
)
&&
!
CLASSTYPE_ABSTRACT_VIRTUALS
(
type
)
&&
(
rval
=
build_method_call
&&
(
rval
=
build_method_call
(
NULL_TREE
,
constructor_name_full
(
type
),
(
NULL_TREE
,
constructor_name_full
(
type
),
build_tree_list
(
NULL_TREE
,
expr
),
TYPE_BINFO
(
type
),
build_tree_list
(
NULL_TREE
,
expr
),
TYPE_BINFO
(
type
),
...
...
gcc/cp/decl.c
View file @
a28e3c7f
...
@@ -1964,7 +1964,8 @@ decls_match (newdecl, olddecl)
...
@@ -1964,7 +1964,8 @@ decls_match (newdecl, olddecl)
{
{
int
types_match
;
int
types_match
;
if
(
TREE_CODE
(
newdecl
)
==
FUNCTION_DECL
&&
TREE_CODE
(
olddecl
)
==
FUNCTION_DECL
)
if
(
TREE_CODE
(
newdecl
)
==
FUNCTION_DECL
&&
TREE_CODE
(
olddecl
)
==
FUNCTION_DECL
)
{
{
tree
f1
=
TREE_TYPE
(
newdecl
);
tree
f1
=
TREE_TYPE
(
newdecl
);
tree
f2
=
TREE_TYPE
(
olddecl
);
tree
f2
=
TREE_TYPE
(
olddecl
);
...
@@ -1997,10 +1998,19 @@ decls_match (newdecl, olddecl)
...
@@ -1997,10 +1998,19 @@ decls_match (newdecl, olddecl)
if
(
comptypes
(
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
f1
)),
if
(
comptypes
(
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
f1
)),
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
f2
)),
2
))
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
f2
)),
2
))
{
{
if
(
DECL_LANGUAGE
(
olddecl
)
==
lang_c
if
(
!
strict_prototypes_lang_c
&&
DECL_LANGUAGE
(
olddecl
)
==
lang_c
&&
!
strict_prototypes_lang_c
&&
p2
==
NULL_TREE
)
&&
p2
==
NULL_TREE
)
types_match
=
self_promoting_args_p
(
p1
);
{
types_match
=
self_promoting_args_p
(
p1
);
if
(
p1
==
void_list_node
)
TREE_TYPE
(
newdecl
)
=
TREE_TYPE
(
olddecl
);
}
else
if
(
!
strict_prototypes_lang_c
&&
DECL_LANGUAGE
(
olddecl
)
==
lang_c
&&
DECL_LANGUAGE
(
newdecl
)
==
lang_c
&&
p1
==
NULL_TREE
)
{
types_match
=
self_promoting_args_p
(
p2
);
TREE_TYPE
(
newdecl
)
=
TREE_TYPE
(
olddecl
);
}
else
else
types_match
=
compparms
(
p1
,
p2
,
1
);
types_match
=
compparms
(
p1
,
p2
,
1
);
}
}
...
@@ -2249,12 +2259,7 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2249,12 +2259,7 @@ duplicate_decls (newdecl, olddecl)
int foo () { bar (); }
int foo () { bar (); }
is OK. */
is OK. */
if
(
current_lang_stack
==
current_lang_base
)
if
(
current_lang_stack
==
current_lang_base
)
{
DECL_LANGUAGE
(
newdecl
)
=
DECL_LANGUAGE
(
olddecl
);
DECL_LANGUAGE
(
newdecl
)
=
DECL_LANGUAGE
(
olddecl
);
if
(
TYPE_ARG_TYPES
(
TREE_TYPE
(
olddecl
))
==
NULL_TREE
&&
TYPE_ARG_TYPES
(
TREE_TYPE
(
newdecl
))
==
void_list_node
)
TREE_TYPE
(
newdecl
)
=
TREE_TYPE
(
olddecl
);
}
else
else
{
{
cp_error_at
(
"previous declaration of `%#D' with %L linkage"
,
cp_error_at
(
"previous declaration of `%#D' with %L linkage"
,
...
@@ -2268,7 +2273,8 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2268,7 +2273,8 @@ duplicate_decls (newdecl, olddecl)
if
(
pedantic
if
(
pedantic
&&
(
TREE_READONLY
(
newdecl
)
!=
TREE_READONLY
(
olddecl
)
&&
(
TREE_READONLY
(
newdecl
)
!=
TREE_READONLY
(
olddecl
)
||
TREE_THIS_VOLATILE
(
newdecl
)
!=
TREE_THIS_VOLATILE
(
olddecl
)))
||
TREE_THIS_VOLATILE
(
newdecl
)
!=
TREE_THIS_VOLATILE
(
olddecl
)))
cp_error_at
(
"type qualifiers for `%D' conflict with previous decl"
,
newdecl
);
cp_error_at
(
"type qualifiers for `%D' conflict with previous decl"
,
newdecl
);
}
}
/* If new decl is `static' and an `extern' was seen previously,
/* If new decl is `static' and an `extern' was seen previously,
...
@@ -2318,7 +2324,8 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2318,7 +2324,8 @@ duplicate_decls (newdecl, olddecl)
} Thing;
} Thing;
*/
*/
#if 0
#if 0
my_friendly_assert (DECL_IGNORED_P (olddecl) == DECL_IGNORED_P (newdecl), 139);
my_friendly_assert (DECL_IGNORED_P (olddecl) == DECL_IGNORED_P (newdecl),
139);
#endif
#endif
}
}
...
@@ -2363,9 +2370,10 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2363,9 +2370,10 @@ duplicate_decls (newdecl, olddecl)
TREE_TYPE
(
olddecl
)
=
build_exception_variant
(
ctype
,
newtype
,
TREE_TYPE
(
olddecl
)
=
build_exception_variant
(
ctype
,
newtype
,
TYPE_RAISES_EXCEPTIONS
(
oldtype
));
TYPE_RAISES_EXCEPTIONS
(
oldtype
));
if
(
!
compexcepttypes
(
TREE_TYPE
(
newdecl
),
TREE_TYPE
(
olddecl
),
0
))
if
(
!
compexcepttypes
(
TREE_TYPE
(
newdecl
),
TREE_TYPE
(
olddecl
),
0
))
{
{
cp_error
(
"declaration of `%D' raises different exceptions..."
,
newdecl
);
cp_error
(
"declaration of `%D' raises different exceptions..."
,
newdecl
);
cp_error_at
(
"...from previous declaration here"
,
olddecl
);
cp_error_at
(
"...from previous declaration here"
,
olddecl
);
}
}
}
}
...
@@ -2683,7 +2691,8 @@ pushdecl (x)
...
@@ -2683,7 +2691,8 @@ pushdecl (x)
if (extra_warnings)
if (extra_warnings)
{
{
cp_warning ("`static' missing from declaration of `%D'", t);
cp_warning ("`static' missing from declaration of `%D'",
t);
warning_with_file_and_line (file, line,
warning_with_file_and_line (file, line,
"previous declaration of `%s'",
"previous declaration of `%s'",
decl_as_string (t, 0));
decl_as_string (t, 0));
...
@@ -3176,8 +3185,11 @@ push_overloaded_decl (decl, forgettable)
...
@@ -3176,8 +3185,11 @@ push_overloaded_decl (decl, forgettable)
{
{
if
(
decl
==
tmp
||
duplicate_decls
(
decl
,
tmp
))
if
(
decl
==
tmp
||
duplicate_decls
(
decl
,
tmp
))
return
tmp
;
return
tmp
;
if
(
compparms
(
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)),
/* Avoid doing things about built-ins, since duplicate_decls
TYPE_ARG_TYPES
(
TREE_TYPE
(
tmp
)),
2
))
will have given warnings/errors for them. */
if
(
!
DECL_BUILT_IN
(
tmp
)
&&
!
DECL_BUILT_IN_NONANSI
(
tmp
)
&&
compparms
(
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
tmp
)),
2
))
{
{
cp_error
(
"new declaration `%#D'"
,
decl
);
cp_error
(
"new declaration `%#D'"
,
decl
);
cp_error_at
(
"ambiguates old declaration `%#D'"
,
tmp
);
cp_error_at
(
"ambiguates old declaration `%#D'"
,
tmp
);
...
@@ -3762,7 +3774,8 @@ lookup_nested_type (type, context)
...
@@ -3762,7 +3774,8 @@ lookup_nested_type (type, context)
}
}
break
;
break
;
case
FUNCTION_DECL
:
case
FUNCTION_DECL
:
return
TYPE_IDENTIFIER
(
type
)
?
lookup_name
(
TYPE_IDENTIFIER
(
type
),
1
)
:
NULL_TREE
;
return
TYPE_IDENTIFIER
(
type
)
?
lookup_name
(
TYPE_IDENTIFIER
(
type
),
1
)
:
NULL_TREE
;
break
;
break
;
default
:
default
:
my_friendly_abort
(
12
);
my_friendly_abort
(
12
);
...
@@ -3778,6 +3791,7 @@ lookup_nested_type (type, context)
...
@@ -3778,6 +3791,7 @@ lookup_nested_type (type, context)
definitions if there are many, or return 0 if it is undefined.
definitions if there are many, or return 0 if it is undefined.
If PREFER_TYPE is > 0, we prefer TYPE_DECLs.
If PREFER_TYPE is > 0, we prefer TYPE_DECLs.
If PREFER_TYPE is -2, we're being called from yylex(). (UGLY)
Otherwise we prefer non-TYPE_DECLs. */
Otherwise we prefer non-TYPE_DECLs. */
tree
tree
...
@@ -3786,7 +3800,43 @@ lookup_name (name, prefer_type)
...
@@ -3786,7 +3800,43 @@ lookup_name (name, prefer_type)
int
prefer_type
;
int
prefer_type
;
{
{
register
tree
val
;
register
tree
val
;
int
yylex
=
0
;
if
(
prefer_type
==
-
2
)
{
extern
int
looking_for_typename
;
yylex
=
1
;
prefer_type
=
looking_for_typename
;
if
(
got_scope
!=
NULL_TREE
)
{
if
(
got_scope
==
void_type_node
)
val
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
else
if
(
TREE_CODE
(
got_scope
)
==
TEMPLATE_TYPE_PARM
/* TFIXME -- don't do this for UPTs in new model. */
||
TREE_CODE
(
got_scope
)
==
UNINSTANTIATED_P_TYPE
)
{
if
(
prefer_type
>
0
)
val
=
create_nested_upt
(
got_scope
,
name
);
else
val
=
NULL_TREE
;
}
else
if
(
!
IS_AGGR_TYPE
(
got_scope
))
/* Someone else will give an error about this if needed. */
val
=
NULL_TREE
;
else
if
(
got_scope
==
current_class_type
)
val
=
IDENTIFIER_CLASS_VALUE
(
name
);
else
if
(
TYPE_BEING_DEFINED
(
got_scope
))
val
=
lookup_nested_tag
(
got_scope
,
name
);
else
val
=
lookup_field
(
got_scope
,
name
,
0
,
0
);
got_scope
=
NULL_TREE
;
goto
done
;
}
}
if
(
current_binding_level
!=
global_binding_level
if
(
current_binding_level
!=
global_binding_level
&&
IDENTIFIER_LOCAL_VALUE
(
name
))
&&
IDENTIFIER_LOCAL_VALUE
(
name
))
val
=
IDENTIFIER_LOCAL_VALUE
(
name
);
val
=
IDENTIFIER_LOCAL_VALUE
(
name
);
...
@@ -3802,7 +3852,7 @@ lookup_name (name, prefer_type)
...
@@ -3802,7 +3852,7 @@ lookup_name (name, prefer_type)
/* Try to find values from base classes
/* Try to find values from base classes
if we are presently defining a type.
if we are presently defining a type.
We are presently only interested in TYPE_DECLs. */
We are presently only interested in TYPE_DECLs. */
val
=
lookup_field
(
current_class_type
,
name
,
0
,
prefer_type
<
0
);
val
=
lookup_field
(
current_class_type
,
name
,
0
,
1
);
if
(
val
==
error_mark_node
)
if
(
val
==
error_mark_node
)
return
val
;
return
val
;
if
(
val
&&
TREE_CODE
(
val
)
!=
TYPE_DECL
)
if
(
val
&&
TREE_CODE
(
val
)
!=
TYPE_DECL
)
...
@@ -3813,7 +3863,7 @@ lookup_name (name, prefer_type)
...
@@ -3813,7 +3863,7 @@ lookup_name (name, prefer_type)
the nested name at the point where we haven't even, for example,
the nested name at the point where we haven't even, for example,
created the COMPONENT_REF or anything like that. */
created the COMPONENT_REF or anything like that. */
if
(
val
==
NULL_TREE
)
if
(
val
==
NULL_TREE
)
val
=
lookup_nested_field
(
name
,
prefer_type
!=
-
2
);
val
=
lookup_nested_field
(
name
,
!
yylex
);
if
(
val
==
NULL_TREE
)
if
(
val
==
NULL_TREE
)
val
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
val
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
...
@@ -3821,21 +3871,19 @@ lookup_name (name, prefer_type)
...
@@ -3821,21 +3871,19 @@ lookup_name (name, prefer_type)
else
else
val
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
val
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
done
:
if
(
val
)
if
(
val
)
{
{
extern
int
looking_for_typename
;
/* Arbitrate between finding a TYPE_DECL and finding
/* Arbitrate between finding a TYPE_DECL and finding
other kinds of _DECLs. */
other kinds of _DECLs. */
if
(
TREE_CODE
(
val
)
==
TYPE_DECL
||
looking_for_typenam
e
<
0
)
if
(
TREE_CODE
(
val
)
==
TYPE_DECL
||
prefer_typ
e
<
0
)
return
val
;
return
val
;
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
{
{
register
tree
val_as_type
=
TYPE_NAME
(
IDENTIFIER_TYPE_VALUE
(
name
));
register
tree
val_as_type
=
TYPE_NAME
(
IDENTIFIER_TYPE_VALUE
(
name
));
if
(
val
==
val_as_type
||
prefer_type
>
0
if
(
val
==
val_as_type
||
prefer_type
>
0
)
||
looking_for_typename
>
0
)
return
val_as_type
;
return
val_as_type
;
return
val
;
return
val
;
...
@@ -4088,7 +4136,8 @@ init_decl_processing ()
...
@@ -4088,7 +4136,8 @@ init_decl_processing ()
error_mark_list
=
build_tree_list
(
error_mark_node
,
error_mark_node
);
error_mark_list
=
build_tree_list
(
error_mark_node
,
error_mark_node
);
TREE_TYPE
(
error_mark_list
)
=
error_mark_node
;
TREE_TYPE
(
error_mark_list
)
=
error_mark_node
;
pushlevel
(
0
);
/* make the binding_level structure for global names. */
/* Make the binding_level structure for global names. */
pushlevel
(
0
);
global_binding_level
=
current_binding_level
;
global_binding_level
=
current_binding_level
;
this_identifier
=
get_identifier
(
THIS_NAME
);
this_identifier
=
get_identifier
(
THIS_NAME
);
...
@@ -4229,7 +4278,8 @@ init_decl_processing ()
...
@@ -4229,7 +4278,8 @@ init_decl_processing ()
TREE_TYPE
(
void_zero_node
)
=
void_type_node
;
TREE_TYPE
(
void_zero_node
)
=
void_type_node
;
string_type_node
=
build_pointer_type
(
char_type_node
);
string_type_node
=
build_pointer_type
(
char_type_node
);
const_string_type_node
=
build_pointer_type
(
build_type_variant
(
char_type_node
,
1
,
0
));
const_string_type_node
=
build_pointer_type
(
build_type_variant
(
char_type_node
,
1
,
0
));
record_builtin_type
(
RID_MAX
,
NULL_PTR
,
string_type_node
);
record_builtin_type
(
RID_MAX
,
NULL_PTR
,
string_type_node
);
/* Make a type to be the domain of a few array types
/* Make a type to be the domain of a few array types
...
@@ -4257,7 +4307,8 @@ init_decl_processing ()
...
@@ -4257,7 +4307,8 @@ init_decl_processing ()
build_pointer_type
(
default_function_type
);
build_pointer_type
(
default_function_type
);
ptr_type_node
=
build_pointer_type
(
void_type_node
);
ptr_type_node
=
build_pointer_type
(
void_type_node
);
const_ptr_type_node
=
build_pointer_type
(
build_type_variant
(
void_type_node
,
1
,
0
));
const_ptr_type_node
=
build_pointer_type
(
build_type_variant
(
void_type_node
,
1
,
0
));
record_builtin_type
(
RID_MAX
,
NULL_PTR
,
ptr_type_node
);
record_builtin_type
(
RID_MAX
,
NULL_PTR
,
ptr_type_node
);
endlink
=
void_list_node
;
endlink
=
void_list_node
;
int_endlink
=
tree_cons
(
NULL_TREE
,
integer_type_node
,
endlink
);
int_endlink
=
tree_cons
(
NULL_TREE
,
integer_type_node
,
endlink
);
...
@@ -4269,14 +4320,16 @@ init_decl_processing ()
...
@@ -4269,14 +4320,16 @@ init_decl_processing ()
double_ftype_double_double
double_ftype_double_double
=
build_function_type
(
double_type_node
,
=
build_function_type
(
double_type_node
,
tree_cons
(
NULL_TREE
,
double_type_node
,
double_endlink
));
tree_cons
(
NULL_TREE
,
double_type_node
,
double_endlink
));
int_ftype_int
int_ftype_int
=
build_function_type
(
integer_type_node
,
int_endlink
);
=
build_function_type
(
integer_type_node
,
int_endlink
);
long_ftype_long
long_ftype_long
=
build_function_type
(
long_integer_type_node
,
=
build_function_type
(
long_integer_type_node
,
tree_cons
(
NULL_TREE
,
long_integer_type_node
,
endlink
));
tree_cons
(
NULL_TREE
,
long_integer_type_node
,
endlink
));
void_ftype_ptr_ptr_int
void_ftype_ptr_ptr_int
=
build_function_type
(
void_type_node
,
=
build_function_type
(
void_type_node
,
...
@@ -4466,7 +4519,8 @@ init_decl_processing ()
...
@@ -4466,7 +4519,8 @@ init_decl_processing ()
builtin_function
(
"memcmp"
,
int_ftype_cptr_cptr_sizet
,
BUILT_IN_MEMCMP
,
builtin_function
(
"memcmp"
,
int_ftype_cptr_cptr_sizet
,
BUILT_IN_MEMCMP
,
NULL_PTR
);
NULL_PTR
);
builtin_function
(
"strcmp"
,
int_ftype_string_string
,
BUILT_IN_STRCMP
,
NULL_PTR
);
builtin_function
(
"strcmp"
,
int_ftype_string_string
,
BUILT_IN_STRCMP
,
NULL_PTR
);
builtin_function
(
"strcpy"
,
string_ftype_ptr_ptr
,
BUILT_IN_STRCPY
,
NULL_PTR
);
builtin_function
(
"strcpy"
,
string_ftype_ptr_ptr
,
BUILT_IN_STRCPY
,
NULL_PTR
);
#if 0
#if 0
/* Not yet. */
/* Not yet. */
builtin_function ("strncpy", strncpy_ftype, BUILT_IN_STRNCPY, NULL_PTR);
builtin_function ("strncpy", strncpy_ftype, BUILT_IN_STRNCPY, NULL_PTR);
...
@@ -4481,13 +4535,19 @@ init_decl_processing ()
...
@@ -4481,13 +4535,19 @@ init_decl_processing ()
or build_function_call. */
or build_function_call. */
builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, 0);
builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, 0);
builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, 0);
builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, 0);
builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR, 0);
builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR,
0);
builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, 0);
builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, 0);
builtin_function ("__builtin_fmod", double_ftype_double_double, BUILT_IN_FMOD, 0);
builtin_function ("__builtin_fmod", double_ftype_double_double,
builtin_function ("__builtin_frem", double_ftype_double_double, BUILT_IN_FREM, 0);
BUILT_IN_FMOD, 0);
builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, BUILT_IN_MEMSET, 0);
builtin_function ("__builtin_frem", double_ftype_double_double,
builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP, 0);
BUILT_IN_FREM, 0);
builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN, 0);
builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, BUILT_IN_MEMSET,
0);
builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP,
0);
builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN,
0);
#endif
#endif
/* C++ extensions */
/* C++ extensions */
...
@@ -4507,7 +4567,7 @@ init_decl_processing ()
...
@@ -4507,7 +4567,7 @@ init_decl_processing ()
TYPE_MODE
(
unknown_type_node
)
=
TYPE_MODE
(
void_type_node
);
TYPE_MODE
(
unknown_type_node
)
=
TYPE_MODE
(
void_type_node
);
/* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */
/* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */
TREE_TYPE
(
unknown_type_node
)
=
unknown_type_node
;
TREE_TYPE
(
unknown_type_node
)
=
unknown_type_node
;
/* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same result.
*/
/* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same result. */
TYPE_POINTER_TO
(
unknown_type_node
)
=
unknown_type_node
;
TYPE_POINTER_TO
(
unknown_type_node
)
=
unknown_type_node
;
TYPE_REFERENCE_TO
(
unknown_type_node
)
=
unknown_type_node
;
TYPE_REFERENCE_TO
(
unknown_type_node
)
=
unknown_type_node
;
...
@@ -4544,9 +4604,12 @@ init_decl_processing ()
...
@@ -4544,9 +4604,12 @@ init_decl_processing ()
fields names so that the debugger can use them. */
fields names so that the debugger can use them. */
memptr_type
=
make_lang_type
(
RECORD_TYPE
);
memptr_type
=
make_lang_type
(
RECORD_TYPE
);
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
delta_identifier
,
delta_type_node
);
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
delta_identifier
,
fields
[
1
]
=
build_lang_field_decl
(
FIELD_DECL
,
index_identifier
,
delta_type_node
);
delta_type_node
);
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
pfn_identifier
,
ptr_type_node
);
fields
[
1
]
=
build_lang_field_decl
(
FIELD_DECL
,
index_identifier
,
delta_type_node
);
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
pfn_identifier
,
ptr_type_node
);
finish_builtin_type
(
memptr_type
,
VTBL_PTR_TYPE
,
fields
,
2
,
finish_builtin_type
(
memptr_type
,
VTBL_PTR_TYPE
,
fields
,
2
,
double_type_node
);
double_type_node
);
...
@@ -4588,9 +4651,15 @@ init_decl_processing ()
...
@@ -4588,9 +4651,15 @@ init_decl_processing ()
if
(
flag_handle_signatures
)
if
(
flag_handle_signatures
)
{
{
sigtable_entry_type
=
make_lang_type
(
RECORD_TYPE
);
sigtable_entry_type
=
make_lang_type
(
RECORD_TYPE
);
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
SIGTABLE_CODE_NAME
),
short_integer_type_node
);
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
fields
[
1
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
SIGTABLE_OFFSET_NAME
),
short_integer_type_node
);
get_identifier
(
SIGTABLE_CODE_NAME
),
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
SIGTABLE_PFN_NAME
),
ptr_type_node
);
short_integer_type_node
);
fields
[
1
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
SIGTABLE_OFFSET_NAME
),
short_integer_type_node
);
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
SIGTABLE_PFN_NAME
),
ptr_type_node
);
finish_builtin_type
(
sigtable_entry_type
,
SIGTABLE_PTR_TYPE
,
fields
,
2
,
finish_builtin_type
(
sigtable_entry_type
,
SIGTABLE_PTR_TYPE
,
fields
,
2
,
double_type_node
);
double_type_node
);
sigtable_entry_type
=
build_type_variant
(
sigtable_entry_type
,
1
,
0
);
sigtable_entry_type
=
build_type_variant
(
sigtable_entry_type
,
1
,
0
);
...
@@ -4620,9 +4689,12 @@ init_decl_processing ()
...
@@ -4620,9 +4689,12 @@ init_decl_processing ()
__t_desc_type_node
=
make_lang_type
(
RECORD_TYPE
);
__t_desc_type_node
=
make_lang_type
(
RECORD_TYPE
);
__i_desc_type_node
=
make_lang_type
(
RECORD_TYPE
);
__i_desc_type_node
=
make_lang_type
(
RECORD_TYPE
);
__m_desc_type_node
=
make_lang_type
(
RECORD_TYPE
);
__m_desc_type_node
=
make_lang_type
(
RECORD_TYPE
);
__t_desc_array_type
=
build_array_type
(
TYPE_POINTER_TO
(
__t_desc_type_node
),
NULL_TREE
);
__t_desc_array_type
=
__i_desc_array_type
=
build_array_type
(
TYPE_POINTER_TO
(
__i_desc_type_node
),
NULL_TREE
);
build_array_type
(
TYPE_POINTER_TO
(
__t_desc_type_node
),
NULL_TREE
);
__m_desc_array_type
=
build_array_type
(
TYPE_POINTER_TO
(
__m_desc_type_node
),
NULL_TREE
);
__i_desc_array_type
=
build_array_type
(
TYPE_POINTER_TO
(
__i_desc_type_node
),
NULL_TREE
);
__m_desc_array_type
=
build_array_type
(
TYPE_POINTER_TO
(
__m_desc_type_node
),
NULL_TREE
);
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"name"
),
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"name"
),
string_type_node
);
string_type_node
);
...
@@ -4630,7 +4702,8 @@ init_decl_processing ()
...
@@ -4630,7 +4702,8 @@ init_decl_processing ()
unsigned_type_node
);
unsigned_type_node
);
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"bits"
),
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"bits"
),
unsigned_type_node
);
unsigned_type_node
);
fields
[
3
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"points_to"
),
fields
[
3
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"points_to"
),
TYPE_POINTER_TO
(
__t_desc_type_node
));
TYPE_POINTER_TO
(
__t_desc_type_node
));
fields
[
4
]
=
build_lang_field_decl
(
FIELD_DECL
,
fields
[
4
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"ivars_count"
),
get_identifier
(
"ivars_count"
),
...
@@ -4666,7 +4739,8 @@ init_decl_processing ()
...
@@ -4666,7 +4739,8 @@ init_decl_processing ()
integer_type_node
);
integer_type_node
);
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"type"
),
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"type"
),
TYPE_POINTER_TO
(
__t_desc_type_node
));
TYPE_POINTER_TO
(
__t_desc_type_node
));
finish_builtin_type
(
__i_desc_type_node
,
"__i_desc"
,
fields
,
2
,
integer_type_node
);
finish_builtin_type
(
__i_desc_type_node
,
"__i_desc"
,
fields
,
2
,
integer_type_node
);
/* method descriptors look like this:
/* method descriptors look like this:
...
@@ -4699,7 +4773,8 @@ init_decl_processing ()
...
@@ -4699,7 +4773,8 @@ init_decl_processing ()
short_integer_type_node
);
short_integer_type_node
);
fields
[
7
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"parm_types"
),
fields
[
7
]
=
build_lang_field_decl
(
FIELD_DECL
,
get_identifier
(
"parm_types"
),
build_pointer_type
(
build_array_type
(
TYPE_POINTER_TO
(
__t_desc_type_node
),
NULL_TREE
)));
build_pointer_type
(
build_array_type
(
TYPE_POINTER_TO
(
__t_desc_type_node
),
NULL_TREE
)));
finish_builtin_type
(
__m_desc_type_node
,
"__m_desc"
,
fields
,
7
,
integer_type_node
);
finish_builtin_type
(
__m_desc_type_node
,
"__m_desc"
,
fields
,
7
,
integer_type_node
);
}
}
/* Now, C++. */
/* Now, C++. */
...
@@ -4720,11 +4795,21 @@ init_decl_processing ()
...
@@ -4720,11 +4795,21 @@ init_decl_processing ()
tree_cons
(
NULL_TREE
,
sizetype
,
tree_cons
(
NULL_TREE
,
sizetype
,
void_list_node
)),
void_list_node
)),
NOT_BUILT_IN
);
NOT_BUILT_IN
);
auto_function
(
ansi_opname
[(
int
)
VEC_NEW_EXPR
],
build_function_type
(
ptr_type_node
,
tree_cons
(
NULL_TREE
,
sizetype
,
void_list_node
)),
NOT_BUILT_IN
);
auto_function
(
ansi_opname
[(
int
)
DELETE_EXPR
],
auto_function
(
ansi_opname
[(
int
)
DELETE_EXPR
],
build_function_type
(
void_type_node
,
build_function_type
(
void_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
void_list_node
)),
void_list_node
)),
NOT_BUILT_IN
);
NOT_BUILT_IN
);
auto_function
(
ansi_opname
[(
int
)
VEC_DELETE_EXPR
],
build_function_type
(
void_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
void_list_node
)),
NOT_BUILT_IN
);
abort_fndecl
abort_fndecl
=
define_function
(
"abort"
,
=
define_function
(
"abort"
,
...
@@ -4889,7 +4974,8 @@ shadow_tag (declspecs)
...
@@ -4889,7 +4974,8 @@ shadow_tag (declspecs)
function members. */
function members. */
if
(
TYPE_FIELDS
(
t
))
if
(
TYPE_FIELDS
(
t
))
{
{
tree
decl
=
grokdeclarator
(
NULL_TREE
,
declspecs
,
NORMAL
,
0
,
NULL_TREE
);
tree
decl
=
grokdeclarator
(
NULL_TREE
,
declspecs
,
NORMAL
,
0
,
NULL_TREE
);
finish_anon_union
(
decl
);
finish_anon_union
(
decl
);
}
}
else
else
...
@@ -4982,7 +5068,8 @@ start_decl (declarator, declspecs, initialized, raises)
...
@@ -4982,7 +5068,8 @@ start_decl (declarator, declspecs, initialized, raises)
/* This should only be done once on the top most decl. */
/* This should only be done once on the top most decl. */
if
(
have_extern_spec
&&
!
used_extern_spec
)
if
(
have_extern_spec
&&
!
used_extern_spec
)
{
{
declspecs
=
decl_tree_cons
(
NULL_TREE
,
get_identifier
(
"extern"
),
declspecs
);
declspecs
=
decl_tree_cons
(
NULL_TREE
,
get_identifier
(
"extern"
),
declspecs
);
used_extern_spec
=
1
;
used_extern_spec
=
1
;
}
}
...
@@ -5057,9 +5144,11 @@ start_decl (declarator, declspecs, initialized, raises)
...
@@ -5057,9 +5144,11 @@ start_decl (declarator, declspecs, initialized, raises)
DECL_ARGUMENTS
(
decl
)
=
args
;
DECL_ARGUMENTS
(
decl
)
=
args
;
}
}
d
=
build_lang_decl
(
TEMPLATE_DECL
,
DECL_NAME
(
decl
),
TREE_TYPE
(
decl
));
d
=
build_lang_decl
(
TEMPLATE_DECL
,
DECL_NAME
(
decl
),
TREE_TYPE
(
decl
));
if
(
interface_unknown
&&
flag_external_templates
&&
!
DECL_IN_SYSTEM_HEADER
(
decl
))
if
(
interface_unknown
&&
flag_external_templates
&&
!
DECL_IN_SYSTEM_HEADER
(
decl
))
warn_if_unknown_interface
();
warn_if_unknown_interface
();
TREE_PUBLIC
(
d
)
=
TREE_PUBLIC
(
decl
)
=
flag_external_templates
&&
!
interface_unknown
;
TREE_PUBLIC
(
d
)
=
TREE_PUBLIC
(
decl
)
=
flag_external_templates
&&
!
interface_unknown
;
TREE_STATIC
(
d
)
=
TREE_STATIC
(
decl
);
TREE_STATIC
(
d
)
=
TREE_STATIC
(
decl
);
DECL_EXTERNAL
(
d
)
=
(
DECL_EXTERNAL
(
decl
)
DECL_EXTERNAL
(
d
)
=
(
DECL_EXTERNAL
(
decl
)
&&
!
(
context
&&
!
DECL_THIS_EXTERN
(
decl
)));
&&
!
(
context
&&
!
DECL_THIS_EXTERN
(
decl
)));
...
@@ -5251,7 +5340,8 @@ start_decl (declarator, declspecs, initialized, raises)
...
@@ -5251,7 +5340,8 @@ start_decl (declarator, declspecs, initialized, raises)
use temporary storage. Do this even if we will ignore the value. */
use temporary storage. Do this even if we will ignore the value. */
if
(
current_binding_level
==
global_binding_level
&&
debug_temp_inits
)
if
(
current_binding_level
==
global_binding_level
&&
debug_temp_inits
)
{
{
if
(
TYPE_NEEDS_CONSTRUCTING
(
type
)
||
TREE_CODE
(
type
)
==
REFERENCE_TYPE
)
if
(
TYPE_NEEDS_CONSTRUCTING
(
type
)
||
TREE_CODE
(
type
)
==
REFERENCE_TYPE
)
/* In this case, the initializer must lay down in permanent
/* In this case, the initializer must lay down in permanent
storage, since it will be saved until `finish_file' is run. */
storage, since it will be saved until `finish_file' is run. */
;
;
...
@@ -5463,7 +5553,8 @@ grok_reference_init (decl, type, init, cleanupp)
...
@@ -5463,7 +5553,8 @@ grok_reference_init (decl, type, init, cleanupp)
TREE_OPERAND
(
TREE_OPERAND
(
tmp
,
0
),
2
)
=
error_mark_node
;
TREE_OPERAND
(
TREE_OPERAND
(
tmp
,
0
),
2
)
=
error_mark_node
;
}
}
if
(
IS_AGGR_TYPE
(
TREE_TYPE
(
this_ptr_type
)))
if
(
IS_AGGR_TYPE
(
TREE_TYPE
(
this_ptr_type
)))
DECL_INITIAL
(
decl
)
=
convert_pointer_to
(
TREE_TYPE
(
this_ptr_type
),
tmp
);
DECL_INITIAL
(
decl
)
=
convert_pointer_to
(
TREE_TYPE
(
this_ptr_type
),
tmp
);
else
else
DECL_INITIAL
(
decl
)
=
convert
(
this_ptr_type
,
tmp
);
DECL_INITIAL
(
decl
)
=
convert
(
this_ptr_type
,
tmp
);
...
@@ -5481,7 +5572,8 @@ grok_reference_init (decl, type, init, cleanupp)
...
@@ -5481,7 +5572,8 @@ grok_reference_init (decl, type, init, cleanupp)
if
(
TREE_CODE
(
actual_init
)
==
ADDR_EXPR
if
(
TREE_CODE
(
actual_init
)
==
ADDR_EXPR
&&
TREE_CODE
(
TREE_OPERAND
(
actual_init
,
0
))
==
TARGET_EXPR
)
&&
TREE_CODE
(
TREE_OPERAND
(
actual_init
,
0
))
==
TARGET_EXPR
)
actual_init
=
save_expr
(
actual_init
);
actual_init
=
save_expr
(
actual_init
);
DECL_INITIAL
(
decl
)
=
convert_pointer_to
(
TREE_TYPE
(
this_ptr_type
),
actual_init
);
DECL_INITIAL
(
decl
)
=
convert_pointer_to
(
TREE_TYPE
(
this_ptr_type
),
actual_init
);
DECL_INITIAL
(
decl
)
=
save_expr
(
DECL_INITIAL
(
decl
));
DECL_INITIAL
(
decl
)
=
save_expr
(
DECL_INITIAL
(
decl
));
TREE_TYPE
(
DECL_INITIAL
(
decl
))
=
type
;
TREE_TYPE
(
DECL_INITIAL
(
decl
))
=
type
;
}
}
...
@@ -5689,7 +5781,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
...
@@ -5689,7 +5781,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
{
{
if
(
TYPE_NEEDS_CONSTRUCTING
(
type
))
if
(
TYPE_NEEDS_CONSTRUCTING
(
type
))
{
{
cp_error
(
"`%D' must be initialized by constructor, not by `{...}'"
,
decl
);
cp_error
(
"`%D' must be initialized by constructor, not by `{...}'"
,
decl
);
init
=
error_mark_node
;
init
=
error_mark_node
;
}
}
else
else
...
@@ -5780,7 +5873,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
...
@@ -5780,7 +5873,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
if
(
CLASSTYPE_READONLY_FIELDS_NEED_INIT
(
ctype
))
if
(
CLASSTYPE_READONLY_FIELDS_NEED_INIT
(
ctype
))
cp_error
(
"structure `%D' with uninitialized const members"
,
decl
);
cp_error
(
"structure `%D' with uninitialized const members"
,
decl
);
if
(
CLASSTYPE_REF_FIELDS_NEED_INIT
(
ctype
))
if
(
CLASSTYPE_REF_FIELDS_NEED_INIT
(
ctype
))
cp_error
(
"structure `%D' with uninitialized reference members"
,
decl
);
cp_error
(
"structure `%D' with uninitialized reference members"
,
decl
);
}
}
if
(
TREE_CODE
(
decl
)
==
VAR_DECL
if
(
TREE_CODE
(
decl
)
==
VAR_DECL
...
@@ -6002,9 +6096,6 @@ finish_decl (decl, init, asmspec_tree, need_pop)
...
@@ -6002,9 +6096,6 @@ finish_decl (decl, init, asmspec_tree, need_pop)
}
}
else
if
(
toplev
)
else
if
(
toplev
)
{
{
/* Keep GCC from complaining that this variable
is defined but never used. */
TREE_USED
(
decl
)
=
1
;
/* If this is a static const, change its apparent linkage
/* If this is a static const, change its apparent linkage
if it belongs to a #pragma interface. */
if it belongs to a #pragma interface. */
if
(
TREE_STATIC
(
decl
)
&&
!
interface_unknown
)
if
(
TREE_STATIC
(
decl
)
&&
!
interface_unknown
)
...
@@ -6092,7 +6183,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
...
@@ -6092,7 +6183,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
: & TYPE_ARG_TYPES (type);
: & TYPE_ARG_TYPES (type);
*argp = NULL_TREE;
*argp = NULL_TREE;
fnname = build_decl_overload (original_name, TYPE_ARG_TYPES (type), 0);
fnname = build_decl_overload (original_name,
TYPE_ARG_TYPES (type), 0);
*argp = parmtypes;
*argp = parmtypes;
fndecl = build_decl (FUNCTION_DECL, fnname, type);
fndecl = build_decl (FUNCTION_DECL, fnname, type);
DECL_EXTERNAL (fndecl) = DECL_EXTERNAL (decl);
DECL_EXTERNAL (fndecl) = DECL_EXTERNAL (decl);
...
@@ -6169,7 +6261,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
...
@@ -6169,7 +6261,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
if
(
init
||
TYPE_NEEDS_CONSTRUCTING
(
type
))
if
(
init
||
TYPE_NEEDS_CONSTRUCTING
(
type
))
{
{
emit_line_note
(
DECL_SOURCE_FILE
(
decl
),
DECL_SOURCE_LINE
(
decl
));
emit_line_note
(
DECL_SOURCE_FILE
(
decl
),
DECL_SOURCE_LINE
(
decl
));
expand_aggr_init
(
decl
,
init
,
0
);
expand_aggr_init
(
decl
,
init
,
0
);
}
}
...
@@ -6182,7 +6275,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
...
@@ -6182,7 +6275,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
if
(
cleanup
)
if
(
cleanup
)
{
{
if
(
!
expand_decl_cleanup
(
decl
,
cleanup
))
if
(
!
expand_decl_cleanup
(
decl
,
cleanup
))
cp_error
(
"parser lost in parsing declaration of `%D'"
,
decl
);
cp_error
(
"parser lost in parsing declaration of `%D'"
,
decl
);
}
}
}
}
}
}
...
@@ -6380,7 +6474,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
...
@@ -6380,7 +6474,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
if
(
inlinep
)
if
(
inlinep
)
cp_error
(
"`%D' declared as an `inline' %s"
,
object
,
type
);
cp_error
(
"`%D' declared as an `inline' %s"
,
object
,
type
);
if
(
quals
)
if
(
quals
)
cp_error
(
"`const' and `volatile' function specifiers on `%D' invalid in %s declaration"
,
object
,
type
);
cp_error
(
"`const' and `volatile' function specifiers on `%D' invalid in %s declaration"
,
object
,
type
);
if
(
friendp
)
if
(
friendp
)
cp_error_at
(
"invalid friend declaration"
,
object
);
cp_error_at
(
"invalid friend declaration"
,
object
);
if
(
raises
)
if
(
raises
)
...
@@ -6399,7 +6494,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
...
@@ -6399,7 +6494,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
CHECK is 1 if we must find this method in CTYPE, 0 if we should
CHECK is 1 if we must find this method in CTYPE, 0 if we should
not look, and -1 if we should not call `grokclassfn' at all. */
not look, and -1 if we should not call `grokclassfn' at all. */
static
tree
static
tree
grokfndecl
(
ctype
,
type
,
declarator
,
virtualp
,
flags
,
quals
,
raises
,
check
,
publicp
)
grokfndecl
(
ctype
,
type
,
declarator
,
virtualp
,
flags
,
quals
,
raises
,
check
,
publicp
)
tree
ctype
,
type
;
tree
ctype
,
type
;
tree
declarator
;
tree
declarator
;
int
virtualp
;
int
virtualp
;
...
@@ -6530,7 +6626,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, raises, check, publ
...
@@ -6530,7 +6626,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, raises, check, publ
for
(
i
=
0
;
i
<
n_baselinks
;
i
++
)
for
(
i
=
0
;
i
<
n_baselinks
;
i
++
)
{
{
tree
base_binfo
=
TREE_VEC_ELT
(
binfos
,
i
);
tree
base_binfo
=
TREE_VEC_ELT
(
binfos
,
i
);
if
(
TYPE_VIRTUAL_P
(
BINFO_TYPE
(
base_binfo
))
||
flag_all_virtual
==
1
)
if
(
TYPE_VIRTUAL_P
(
BINFO_TYPE
(
base_binfo
))
||
flag_all_virtual
==
1
)
{
{
tmp
=
get_first_matching_virtual
(
base_binfo
,
decl
,
tmp
=
get_first_matching_virtual
(
base_binfo
,
decl
,
flags
==
DTOR_FLAG
);
flags
==
DTOR_FLAG
);
...
@@ -6547,8 +6644,10 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, raises, check, publ
...
@@ -6547,8 +6644,10 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, raises, check, publ
path to its virtual baseclass. */
path to its virtual baseclass. */
if
(
staticp
)
if
(
staticp
)
{
{
cp_error
(
"method `%D' may not be declared static"
,
decl
);
cp_error
(
"method `%D' may not be declared static"
,
cp_error_at
(
"(since `%D' declared virtual in base class.)"
,
tmp
);
decl
);
cp_error_at
(
"(since `%D' declared virtual in base class.)"
,
tmp
);
break
;
break
;
}
}
virtualp
=
1
;
virtualp
=
1
;
...
@@ -6716,7 +6815,8 @@ build_ptrmemfunc_type (type)
...
@@ -6716,7 +6815,8 @@ build_ptrmemfunc_type (type)
u
=
make_lang_type
(
UNION_TYPE
);
u
=
make_lang_type
(
UNION_TYPE
);
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
pfn_identifier
,
type
);
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
pfn_identifier
,
type
);
fields
[
1
]
=
build_lang_field_decl
(
FIELD_DECL
,
delta2_identifier
,
delta_type_node
);
fields
[
1
]
=
build_lang_field_decl
(
FIELD_DECL
,
delta2_identifier
,
delta_type_node
);
finish_builtin_type
(
u
,
"__ptrmemfunc_type"
,
fields
,
1
,
ptr_type_node
);
finish_builtin_type
(
u
,
"__ptrmemfunc_type"
,
fields
,
1
,
ptr_type_node
);
TYPE_NAME
(
u
)
=
NULL_TREE
;
TYPE_NAME
(
u
)
=
NULL_TREE
;
...
@@ -6725,8 +6825,10 @@ build_ptrmemfunc_type (type)
...
@@ -6725,8 +6825,10 @@ build_ptrmemfunc_type (type)
/* Let the front-end know this is a pointer to member function. */
/* Let the front-end know this is a pointer to member function. */
TYPE_PTRMEMFUNC_FLAG
(
t
)
=
1
;
TYPE_PTRMEMFUNC_FLAG
(
t
)
=
1
;
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
delta_identifier
,
delta_type_node
);
fields
[
0
]
=
build_lang_field_decl
(
FIELD_DECL
,
delta_identifier
,
fields
[
1
]
=
build_lang_field_decl
(
FIELD_DECL
,
index_identifier
,
delta_type_node
);
delta_type_node
);
fields
[
1
]
=
build_lang_field_decl
(
FIELD_DECL
,
index_identifier
,
delta_type_node
);
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
pfn_or_delta2_identifier
,
u
);
fields
[
2
]
=
build_lang_field_decl
(
FIELD_DECL
,
pfn_or_delta2_identifier
,
u
);
finish_builtin_type
(
t
,
"__ptrmemfunc_type"
,
fields
,
2
,
ptr_type_node
);
finish_builtin_type
(
t
,
"__ptrmemfunc_type"
,
fields
,
2
,
ptr_type_node
);
...
@@ -6839,7 +6941,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -6839,7 +6941,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
tree
ctype
=
current_class_type
;
tree
ctype
=
current_class_type
;
tree
ctor_return_type
=
NULL_TREE
;
tree
ctor_return_type
=
NULL_TREE
;
enum
overload_flags
flags
=
NO_SPECIAL
;
enum
overload_flags
flags
=
NO_SPECIAL
;
int
seen_scope_ref
=
0
;
tree
quals
=
NULL_TREE
;
tree
quals
=
NULL_TREE
;
RIDBIT_RESET_ALL
(
specbits
);
RIDBIT_RESET_ALL
(
specbits
);
...
@@ -6957,7 +7058,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -6957,7 +7058,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
dname
=
decl
;
dname
=
decl
;
decl
=
NULL_TREE
;
decl
=
NULL_TREE
;
if
(
IDENTIFIER_TYPENAME_P
(
dname
))
/* This may just be a variable starting with __op. */
if
(
IDENTIFIER_TYPENAME_P
(
dname
)
&&
TREE_TYPE
(
dname
))
{
{
my_friendly_assert
(
flags
==
NO_SPECIAL
,
154
);
my_friendly_assert
(
flags
==
NO_SPECIAL
,
154
);
flags
=
TYPENAME_FLAG
;
flags
=
TYPENAME_FLAG
;
...
@@ -6987,11 +7089,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -6987,11 +7089,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
/* C++ extension */
/* C++ extension */
case
SCOPE_REF
:
case
SCOPE_REF
:
/*
if (seen_scope_ref == 1)
error ("multiple `::' terms in declarator invalid");
*/
seen_scope_ref
+=
1
;
{
{
/* Perform error checking, and convert class names to types.
/* Perform error checking, and convert class names to types.
We may call grokdeclarator multiple times for the same
We may call grokdeclarator multiple times for the same
...
@@ -7239,14 +7336,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7239,14 +7336,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
}
else
else
{
{
if
(
funcdef_flag
&&
warn_return_type
if
(
funcdef_flag
)
&&
return_type
==
return_normal
{
&&
!
(
RIDBIT_SETP
(
RID_SIGNED
,
specbits
)
if
(
warn_return_type
||
RIDBIT_SETP
(
RID_UNSIGNED
,
specbits
)
&&
return_type
==
return_normal
||
RIDBIT_SETP
(
RID_LONG
,
specbits
)
&&
!
(
RIDBIT_SETP
(
RID_SIGNED
,
specbits
)
||
RIDBIT_SETP
(
RID_SHORT
,
specbits
)))
||
RIDBIT_SETP
(
RID_UNSIGNED
,
specbits
)
warn_about_return_type
=
1
;
||
RIDBIT_SETP
(
RID_LONG
,
specbits
)
/* Save warning until we know what is really going on. */
||
RIDBIT_SETP
(
RID_SHORT
,
specbits
)))
/* Save warning until we know what is really going on. */
warn_about_return_type
=
1
;
}
else
if
(
class_binding_level
&&
declarator
&&
TREE_CODE
(
declarator
)
==
SCOPE_REF
)
/* OK -- access declaration */
;
else
if
(
declspecs
==
NULL_TREE
&&
(
innermost_code
!=
CALL_EXPR
||
pedantic
))
cp_pedwarn
(
"ANSI C++ forbids declaration `%D' with no type or storage class"
,
dname
);
type
=
integer_type_node
;
type
=
integer_type_node
;
}
}
}
}
...
@@ -7486,7 +7593,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7486,7 +7593,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
}
if
(
volatilep
)
if
(
volatilep
)
{
{
error
(
"`volatile' specified for signature member function `%s'"
,
name
);
error
(
"`volatile' specified for signature member function `%s'"
,
name
);
volatilep
=
0
;
volatilep
=
0
;
}
}
if
(
inlinep
)
if
(
inlinep
)
...
@@ -7502,7 +7610,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7502,7 +7610,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
}
if
(
virtualp
)
if
(
virtualp
)
{
{
error
(
"`virtual' specified for signature member function `%s'"
,
name
);
error
(
"`virtual' specified for signature member function `%s'"
,
name
);
/* Later, we'll make signature member functions virtual. */
/* Later, we'll make signature member functions virtual. */
virtualp
=
0
;
virtualp
=
0
;
}
}
...
@@ -7816,7 +7925,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7816,7 +7925,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
else
else
{
{
if
(
pedantic
)
if
(
pedantic
)
cp_pedwarn
(
"ANSI C++ forbids variable-size array `%D'"
,
dname
);
cp_pedwarn
(
"ANSI C++ forbids variable-size array `%D'"
,
dname
);
dont_grok_size
:
dont_grok_size
:
itype
=
itype
=
build_binary_op
(
MINUS_EXPR
,
size
,
integer_one_node
,
1
);
build_binary_op
(
MINUS_EXPR
,
size
,
integer_one_node
,
1
);
...
@@ -8177,11 +8287,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8177,11 +8287,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
/* don't fall out into global scope. Hides real bug? --eichin */
;
/* don't fall out into global scope. Hides real bug? --eichin */
;
else
if
(
TREE_COMPLEXITY
(
declarator
)
==
current_class_depth
)
else
if
(
TREE_COMPLEXITY
(
declarator
)
==
current_class_depth
)
{
{
/* I'm not really sure what pushclass calls this popclass
/* This pop_nested_class corresponds to the
corresponds to. One is in build_push_scope and that has
push_nested_class used to push into class scope for
been changed to a push_nested_class call, that's why I
parsing the argument list of a function decl, in
try to use pop_nested_class here instead.
qualified_id. */
-niklas@appli.se */
pop_nested_class
(
1
);
pop_nested_class
(
1
);
TREE_COMPLEXITY
(
declarator
)
=
current_class_depth
;
TREE_COMPLEXITY
(
declarator
)
=
current_class_depth
;
}
}
...
@@ -8631,7 +8740,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8631,7 +8740,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
}
if
(
declarator
==
ansi_opname
[(
int
)
NEW_EXPR
]
if
(
declarator
==
ansi_opname
[(
int
)
NEW_EXPR
]
||
declarator
==
ansi_opname
[(
int
)
DELETE_EXPR
])
||
declarator
==
ansi_opname
[(
int
)
VEC_NEW_EXPR
]
||
declarator
==
ansi_opname
[(
int
)
DELETE_EXPR
]
||
declarator
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])
{
{
if
(
virtualp
)
if
(
virtualp
)
{
{
...
@@ -9328,7 +9439,8 @@ grok_ctor_properties (ctype, decl)
...
@@ -9328,7 +9439,8 @@ grok_ctor_properties (ctype, decl)
}
}
/* An operator with this name can be either unary or binary. */
/* An operator with this name can be either unary or binary. */
int
ambi_op_p
(
name
)
static
int
ambi_op_p
(
name
)
tree
name
;
tree
name
;
{
{
return
(
name
==
ansi_opname
[(
int
)
INDIRECT_REF
]
return
(
name
==
ansi_opname
[(
int
)
INDIRECT_REF
]
...
@@ -9340,7 +9452,8 @@ int ambi_op_p (name)
...
@@ -9340,7 +9452,8 @@ int ambi_op_p (name)
}
}
/* An operator with this name can only be unary. */
/* An operator with this name can only be unary. */
int
unary_op_p
(
name
)
static
int
unary_op_p
(
name
)
tree
name
;
tree
name
;
{
{
return
(
name
==
ansi_opname
[(
int
)
TRUTH_NOT_EXPR
]
return
(
name
==
ansi_opname
[(
int
)
TRUTH_NOT_EXPR
]
...
@@ -9358,44 +9471,39 @@ grok_op_properties (decl, virtualp, friendp)
...
@@ -9358,44 +9471,39 @@ grok_op_properties (decl, virtualp, friendp)
tree
argtypes
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
));
tree
argtypes
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
));
int
methodp
=
(
TREE_CODE
(
TREE_TYPE
(
decl
))
==
METHOD_TYPE
);
int
methodp
=
(
TREE_CODE
(
TREE_TYPE
(
decl
))
==
METHOD_TYPE
);
tree
name
=
DECL_NAME
(
decl
);
tree
name
=
DECL_NAME
(
decl
);
tree
t
;
if
(
!
friendp
)
if
(
current_class_type
==
NULL_TREE
)
for
(
t
=
current_class_type
;
t
;
t
=
TYPE_NEXT_VARIANT
(
t
))
friendp
=
1
;
{
if
(
name
==
ansi_opname
[(
int
)
MODIFY_EXPR
])
TYPE_HAS_ASSIGNMENT
(
t
)
=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
CALL_EXPR
])
TYPE_OVERLOADS_CALL_EXPR
(
t
)
=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
ARRAY_REF
])
TYPE_OVERLOADS_ARRAY_REF
(
t
)
=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
COMPONENT_REF
]
||
name
==
ansi_opname
[(
int
)
MEMBER_REF
])
TYPE_OVERLOADS_ARROW
(
t
)
=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
NEW_EXPR
])
{
if
(
TREE_CHAIN
(
argtypes
)
==
void_list_node
)
TREE_GETS_NEW
(
t
)
=
1
;
else
TREE_GETS_PLACED_NEW
(
t
)
=
1
;
}
else
if
(
name
==
ansi_opname
[(
int
)
DELETE_EXPR
])
TREE_GETS_DELETE
(
t
)
=
1
;
#if 0
else if (name == ansi_opname[(int) VEC_NEW_EXPR])
TREE_GETS_NEW (t) = 1;
else if (name == ansi_opname[(int) VEC_DELETE_EXPR])
TREE_GETS_DELETE (t) = 1;
#endif
}
if
(
name
==
ansi_opname
[(
int
)
NEW_EXPR
])
if
(
!
friendp
)
{
if
(
name
==
ansi_opname
[(
int
)
MODIFY_EXPR
])
TYPE_HAS_ASSIGNMENT
(
current_class_type
)
=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
CALL_EXPR
])
TYPE_OVERLOADS_CALL_EXPR
(
current_class_type
)
=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
ARRAY_REF
])
TYPE_OVERLOADS_ARRAY_REF
(
current_class_type
)
=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
COMPONENT_REF
]
||
name
==
ansi_opname
[(
int
)
MEMBER_REF
])
TYPE_OVERLOADS_ARROW
(
current_class_type
)
=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
NEW_EXPR
])
TYPE_GETS_NEW
(
current_class_type
)
|=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
DELETE_EXPR
])
TYPE_GETS_DELETE
(
current_class_type
)
|=
1
;
else
if
(
name
==
ansi_opname
[(
int
)
VEC_NEW_EXPR
])
TYPE_GETS_NEW
(
current_class_type
)
|=
2
;
else
if
(
name
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])
TYPE_GETS_DELETE
(
current_class_type
)
|=
2
;
}
if
(
name
==
ansi_opname
[(
int
)
NEW_EXPR
]
||
name
==
ansi_opname
[(
int
)
VEC_NEW_EXPR
])
{
{
#if 0
/* When the compiler encounters the definition of A::operator new, it
/* When the compiler encounters the definition of A::operator new, it
doesn't look at the class declaration to find out if it's static. */
doesn't look at the class declaration to find out if it's static. */
my_friendly_assert (!methodp, 355);
if
(
methodp
)
#endif
revert_static_member_fn
(
&
TREE_TYPE
(
decl
),
&
decl
,
&
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)));
/* Take care of function decl if we had syntax errors. */
/* Take care of function decl if we had syntax errors. */
if
(
argtypes
==
NULL_TREE
)
if
(
argtypes
==
NULL_TREE
)
...
@@ -9404,18 +9512,14 @@ grok_op_properties (decl, virtualp, friendp)
...
@@ -9404,18 +9512,14 @@ grok_op_properties (decl, virtualp, friendp)
hash_tree_chain
(
integer_type_node
,
hash_tree_chain
(
integer_type_node
,
void_list_node
));
void_list_node
));
else
else
decl
=
coerce_new_type
(
TREE_TYPE
(
decl
));
TREE_TYPE
(
decl
)
=
coerce_new_type
(
TREE_TYPE
(
decl
));
}
}
#if 0
else
if
(
name
==
ansi_opname
[(
int
)
DELETE_EXPR
]
else if (name == ansi_opname[(int) VEC_NEW_EXPR])
||
name
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])
{
}
#endif
else
if
(
name
==
ansi_opname
[(
int
)
DELETE_EXPR
])
{
{
#if 0
if
(
methodp
)
my_friendly_assert (!methodp, 355);
revert_static_member_fn
(
&
TREE_TYPE
(
decl
),
&
decl
,
#endif
&
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)));
if
(
argtypes
==
NULL_TREE
)
if
(
argtypes
==
NULL_TREE
)
TREE_TYPE
(
decl
)
=
TREE_TYPE
(
decl
)
=
...
@@ -9423,13 +9527,15 @@ grok_op_properties (decl, virtualp, friendp)
...
@@ -9423,13 +9527,15 @@ grok_op_properties (decl, virtualp, friendp)
hash_tree_chain
(
ptr_type_node
,
hash_tree_chain
(
ptr_type_node
,
void_list_node
));
void_list_node
));
else
else
decl
=
coerce_delete_type
(
TREE_TYPE
(
decl
));
{
}
TREE_TYPE
(
decl
)
=
coerce_delete_type
(
TREE_TYPE
(
decl
));
#if 0
else if (name == ansi_opname[(int) VEC_DELETE_EXPR])
if
(
!
friendp
&&
name
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
]
{
&&
(
TREE_CHAIN
(
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)))
!=
void_list_node
))
TYPE_VEC_DELETE_TAKES_SIZE
(
current_class_type
)
=
1
;
}
}
}
#endif
else
else
{
{
/* An operator function must either be a non-static member function
/* An operator function must either be a non-static member function
...
@@ -9484,8 +9590,9 @@ grok_op_properties (decl, virtualp, friendp)
...
@@ -9484,8 +9590,9 @@ grok_op_properties (decl, virtualp, friendp)
parmtype
=
TREE_VALUE
(
TREE_CHAIN
(
argtypes
));
parmtype
=
TREE_VALUE
(
TREE_CHAIN
(
argtypes
));
if
(
TREE_CODE
(
parmtype
)
==
REFERENCE_TYPE
if
(
TREE_CODE
(
parmtype
)
==
REFERENCE_TYPE
&&
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
parmtype
))
&&
(
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
parmtype
))
==
current_class_type
)
==
current_class_type
)
&&
!
friendp
)
{
{
TYPE_HAS_ASSIGN_REF
(
current_class_type
)
=
1
;
TYPE_HAS_ASSIGN_REF
(
current_class_type
)
=
1
;
if
(
TYPE_READONLY
(
TREE_TYPE
(
parmtype
)))
if
(
TYPE_READONLY
(
TREE_TYPE
(
parmtype
)))
...
@@ -9957,9 +10064,8 @@ if (CLASSTYPE_N_BASECLASSES (basetype) == NULL_TREE
...
@@ -9957,9 +10064,8 @@ if (CLASSTYPE_N_BASECLASSES (basetype) == NULL_TREE
}
}
TYPE_OVERLOADS_METHOD_CALL_EXPR
(
ref
)
|=
TYPE_OVERLOADS_METHOD_CALL_EXPR
(
basetype
);
TYPE_OVERLOADS_METHOD_CALL_EXPR
(
ref
)
|=
TYPE_OVERLOADS_METHOD_CALL_EXPR
(
basetype
);
TREE_GETS_NEW
(
ref
)
|=
TREE_GETS_NEW
(
basetype
);
TYPE_GETS_NEW
(
ref
)
|=
TYPE_GETS_NEW
(
basetype
);
TREE_GETS_PLACED_NEW
(
ref
)
|=
TREE_GETS_PLACED_NEW
(
basetype
);
TYPE_GETS_DELETE
(
ref
)
|=
TYPE_GETS_DELETE
(
basetype
);
TREE_GETS_DELETE
(
ref
)
|=
TREE_GETS_DELETE
(
basetype
);
CLASSTYPE_LOCAL_TYPEDECLS
(
ref
)
|=
CLASSTYPE_LOCAL_TYPEDECLS
(
basetype
);
CLASSTYPE_LOCAL_TYPEDECLS
(
ref
)
|=
CLASSTYPE_LOCAL_TYPEDECLS
(
basetype
);
i
+=
1
;
i
+=
1
;
}
}
...
@@ -10439,7 +10545,8 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
...
@@ -10439,7 +10545,8 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
/* If this doesn't return integer_type, complain. */
/* If this doesn't return integer_type, complain. */
if
(
TREE_TYPE
(
TREE_TYPE
(
decl1
))
!=
integer_type_node
)
if
(
TREE_TYPE
(
TREE_TYPE
(
decl1
))
!=
integer_type_node
)
{
{
warning
(
"return type for `main' changed to integer type"
);
if
(
pedantic
||
warn_return_type
)
warning
(
"return type for `main' changed to integer type"
);
TREE_TYPE
(
decl1
)
=
fntype
=
default_function_type
;
TREE_TYPE
(
decl1
)
=
fntype
=
default_function_type
;
}
}
warn_about_return_type
=
0
;
warn_about_return_type
=
0
;
...
@@ -11040,7 +11147,7 @@ finish_function (lineno, call_poplevel)
...
@@ -11040,7 +11147,7 @@ finish_function (lineno, call_poplevel)
/* These are two cases where we cannot delegate deletion. */
/* These are two cases where we cannot delegate deletion. */
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
current_class_type
)
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
current_class_type
)
||
T
REE_GETS
_DELETE
(
current_class_type
))
||
T
YPE_GETS_REG
_DELETE
(
current_class_type
))
exprstmt
=
build_delete
(
current_class_type
,
C_C_D
,
integer_zero_node
,
exprstmt
=
build_delete
(
current_class_type
,
C_C_D
,
integer_zero_node
,
LOOKUP_NONVIRTUAL
|
LOOKUP_DESTRUCTOR
,
0
);
LOOKUP_NONVIRTUAL
|
LOOKUP_DESTRUCTOR
,
0
);
else
else
...
@@ -11096,7 +11203,7 @@ finish_function (lineno, call_poplevel)
...
@@ -11096,7 +11203,7 @@ finish_function (lineno, call_poplevel)
virtual_size
=
c_sizeof
(
current_class_type
);
virtual_size
=
c_sizeof
(
current_class_type
);
/* At the end, call delete if that's what's requested. */
/* At the end, call delete if that's what's requested. */
if
(
T
REE_GETS
_DELETE
(
current_class_type
))
if
(
T
YPE_GETS_REG
_DELETE
(
current_class_type
))
/* This NOP_EXPR means we are in a static call context. */
/* This NOP_EXPR means we are in a static call context. */
exprstmt
=
exprstmt
=
build_method_call
build_method_call
...
@@ -11216,7 +11323,7 @@ finish_function (lineno, call_poplevel)
...
@@ -11216,7 +11323,7 @@ finish_function (lineno, call_poplevel)
expand_decl_init
(
allocated_this
);
expand_decl_init
(
allocated_this
);
/* How we cleanup `this' if an exception was raised before
/* How we cleanup `this' if an exception was raised before
we are ready to bail out. */
we are ready to bail out. */
cleanup
=
T
REE_GETS
_DELETE
(
current_class_type
)
cleanup
=
T
YPE_GETS_REG
_DELETE
(
current_class_type
)
?
build_opfncall
(
DELETE_EXPR
,
LOOKUP_NORMAL
,
allocated_this
,
virtual_size
,
NULL_TREE
)
?
build_opfncall
(
DELETE_EXPR
,
LOOKUP_NORMAL
,
allocated_this
,
virtual_size
,
NULL_TREE
)
/* The size of allocated_this is wrong, and hence the
/* The size of allocated_this is wrong, and hence the
second argument to operator delete will be wrong. */
second argument to operator delete will be wrong. */
...
...
gcc/cp/decl2.c
View file @
a28e3c7f
...
@@ -1071,6 +1071,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
...
@@ -1071,6 +1071,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
return
error_mark_node
;
return
error_mark_node
;
}
}
#if 0
/* If the type has no destructor, then we should build a regular
/* If the type has no destructor, then we should build a regular
delete, instead of a vector delete. Otherwise, we would end
delete, instead of a vector delete. Otherwise, we would end
up passing a bogus offset into __builtin_delete, which is
up passing a bogus offset into __builtin_delete, which is
...
@@ -1082,15 +1083,15 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
...
@@ -1082,15 +1083,15 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
doing_vec = 0;
doing_vec = 0;
use_global_delete = 1;
use_global_delete = 1;
}
}
#endif
if
(
doing_vec
)
if
(
doing_vec
)
return
build_vec_delete
(
t
,
maxindex
,
elt_size
,
NULL_TREE
,
return
build_vec_delete
(
t
,
maxindex
,
elt_size
,
integer_one_node
,
integer_
one_node
,
integer_two_nod
e
);
integer_
two_node
,
use_global_delet
e
);
else
else
return
build_delete
(
type
,
t
,
integer_three_node
,
return
build_delete
(
type
,
t
,
integer_three_node
,
LOOKUP_NORMAL
|
LOOKUP_HAS_IN_CHARGE
,
LOOKUP_NORMAL
|
LOOKUP_HAS_IN_CHARGE
,
use_global_delete
use_global_delete
);
||
TYPE_HAS_DESTRUCTOR
(
TREE_TYPE
(
type
)));
}
}
/* Sanity check: report error if this function FUNCTION is not
/* Sanity check: report error if this function FUNCTION is not
...
@@ -1456,6 +1457,7 @@ grokbitfield (declarator, declspecs, width)
...
@@ -1456,6 +1457,7 @@ grokbitfield (declarator, declspecs, width)
return
value
;
return
value
;
}
}
#if 0
/* Like GROKFIELD, except that the declarator has been
/* Like GROKFIELD, except that the declarator has been
buried in DECLSPECS. Find the declarator, and
buried in DECLSPECS. Find the declarator, and
return something that looks like it came from
return something that looks like it came from
...
@@ -1634,6 +1636,7 @@ groktypefield (declspecs, parmlist)
...
@@ -1634,6 +1636,7 @@ groktypefield (declspecs, parmlist)
DECL_IN_AGGR_P (decl) = 1;
DECL_IN_AGGR_P (decl) = 1;
return decl;
return decl;
}
}
#endif
tree
tree
grokoptypename
(
declspecs
,
declarator
)
grokoptypename
(
declspecs
,
declarator
)
...
@@ -2278,7 +2281,7 @@ coerce_delete_type (type)
...
@@ -2278,7 +2281,7 @@ coerce_delete_type (type)
else
if
(
e3
|=
e2
)
else
if
(
e3
|=
e2
)
{
{
if
(
arg_types
==
NULL_TREE
)
if
(
arg_types
==
NULL_TREE
)
arg_types
=
void_list_node
;
arg_types
=
tree_cons
(
NULL_TREE
,
ptr_type_node
,
void_list_node
)
;
else
else
arg_types
=
tree_cons
(
NULL_TREE
,
ptr_type_node
,
TREE_CHAIN
(
arg_types
));
arg_types
=
tree_cons
(
NULL_TREE
,
ptr_type_node
,
TREE_CHAIN
(
arg_types
));
}
}
...
@@ -2853,7 +2856,11 @@ reparse_decl_as_expr1 (decl)
...
@@ -2853,7 +2856,11 @@ reparse_decl_as_expr1 (decl)
case
BIT_NOT_EXPR
:
case
BIT_NOT_EXPR
:
return
build_x_unary_op
(
BIT_NOT_EXPR
,
return
build_x_unary_op
(
BIT_NOT_EXPR
,
reparse_decl_as_expr1
(
TREE_OPERAND
(
decl
,
0
)));
reparse_decl_as_expr1
(
TREE_OPERAND
(
decl
,
0
)));
case
SCOPE_REF
:
return
build_offset_ref
(
TREE_OPERAND
(
decl
,
0
),
TREE_OPERAND
(
decl
,
1
));
case
ARRAY_REF
:
return
grok_array_decl
(
reparse_decl_as_expr1
(
TREE_OPERAND
(
decl
,
0
)),
TREE_OPERAND
(
decl
,
1
));
default
:
default
:
my_friendly_abort
(
5
);
my_friendly_abort
(
5
);
return
NULL_TREE
;
return
NULL_TREE
;
...
@@ -2901,6 +2908,9 @@ finish_decl_parsing (decl)
...
@@ -2901,6 +2908,9 @@ finish_decl_parsing (decl)
push_nested_class
(
TREE_OPERAND
(
decl
,
0
),
3
);
push_nested_class
(
TREE_OPERAND
(
decl
,
0
),
3
);
TREE_COMPLEXITY
(
decl
)
=
current_class_depth
;
TREE_COMPLEXITY
(
decl
)
=
current_class_depth
;
return
decl
;
return
decl
;
case
ARRAY_REF
:
TREE_OPERAND
(
decl
,
0
)
=
finish_decl_parsing
(
TREE_OPERAND
(
decl
,
0
));
return
decl
;
default
:
default
:
my_friendly_abort
(
5
);
my_friendly_abort
(
5
);
return
NULL_TREE
;
return
NULL_TREE
;
...
...
gcc/cp/gxxint.texi
View file @
a28e3c7f
...
@@ -1059,17 +1059,18 @@ It is ambiguous whether @code{class T} should be parsed as the
...
@@ -1059,17 +1059,18 @@ It is ambiguous whether @code{class T} should be parsed as the
declaration
of
a
template
type
parameter
named
@code
{
T
}
or
an
unnamed
declaration
of
a
template
type
parameter
named
@code
{
T
}
or
an
unnamed
constant
parameter
of
type
@code
{
class
T
}.
Section
14
.
6
,
paragraph
3
of
constant
parameter
of
type
@code
{
class
T
}.
Section
14
.
6
,
paragraph
3
of
the
January
'
94
working
paper
states
that
the
first
interpretation
is
the
January
'
94
working
paper
states
that
the
first
interpretation
is
the
correct
one
.
This
ambiguity
results
in
four
reduce
/
reduce
conflicts
.
the
correct
one
.
This
ambiguity
results
in
two
reduce
/
reduce
conflicts
.
2
)
Between
@code
{
primary
}
and
@code
{
type
name
}
for
code
like
@samp
{
int
()}
2
)
Between
@code
{
primary
}
and
@code
{
type
_id
}
for
code
like
@samp
{
int
()}
in
places
where
both
can
be
accepted
,
such
as
the
argument
to
in
places
where
both
can
be
accepted
,
such
as
the
argument
to
@code
{
sizeof
}.
Section
8
.
1
of
the
pre
-
San
Diego
working
paper
specifies
@code
{
sizeof
}.
Section
8
.
1
of
the
pre
-
San
Diego
working
paper
specifies
that
these
ambiguous
constructs
will
be
interpreted
as
@code
{
typename
}
s
.
that
these
ambiguous
constructs
will
be
interpreted
as
@code
{
typename
}
s
.
This
ambiguity
results
in
six
reduce
/
reduce
conflicts
.
This
ambiguity
results
in
six
reduce
/
reduce
conflicts
between
@samp
{
absdcl
}
and
@samp
{
functional_cast
}.
3
)
Between
@code
{
primary
}
/
@code
{
functional_cast
}
and
3
)
Between
@code
{
functional_cast
}
and
@code
{
expr_or_declarator
}
/
@code
{
complex_direct_notype_declarator
},
for
@code
{
complex_direct_notype_declarator
},
for
various
token
strings
.
various
token
strings
.
This
situation
occurs
in
code
looking
like
This
situation
occurs
in
code
looking
like
@example
@example
int
(
*
a
);
int
(
*
a
);
...
@@ -1078,11 +1079,23 @@ int (*a);
...
@@ -1078,11 +1079,23 @@ int (*a);
This
code
is
ambiguous
;
it
could
be
a
declaration
of
the
variable
This
code
is
ambiguous
;
it
could
be
a
declaration
of
the
variable
@samp
{
a
}
as
a
pointer
to
@samp
{
int
},
or
it
could
be
a
functional
cast
of
@samp
{
a
}
as
a
pointer
to
@samp
{
int
},
or
it
could
be
a
functional
cast
of
@samp
{
*
a
}
to
@samp
{
int
}.
Section
6
.
8
specifies
that
the
former
@samp
{
*
a
}
to
@samp
{
int
}.
Section
6
.
8
specifies
that
the
former
interpretation
is
correct
.
This
ambiguity
results
in
12
reduce
/
reduce
interpretation
is
correct
.
This
ambiguity
results
in
7
reduce
/
reduce
conflicts
.
Ack
.
conflicts
.
Another
aspect
of
this
ambiguity
is
code
like
'
int
(
x
[
2
]);
'
,
which
is
resolved
at
the
'['
and
accounts
for
6
reduce
/
reduce
conflicts
4
)
Between
@code
{
after_type_declarator
}
and
@code
{
parm
},
for
the
token
between
@samp
{
direct_notype_declarator
}
and
@code
{
TYPENAME
}.
This
occurs
in
(
as
one
example
)
code
like
@samp
{
primary
}
/
@samp
{
overqualified_id
}.
Finally
,
there
are
4
r
/
r
conflicts
between
@samp
{
expr_or_declarator
}
and
@samp
{
primary
}
over
code
like
'
int
(
a
);
'
,
which
could
probably
be
resolved
but
would
also
probably
be
more
trouble
than
it
'
s
worth
.
In
all
,
this
situation
accounts
for
17
conflicts
.
Ack
!
The
second
case
above
is
responsible
for
the
failure
to
parse
'
LinppFile
ppfile
(
String
(
argv
[
1
]),
&
outs
,
argc
,
argv
)
;'
(
from
Rogue
Wave
Math
.
h
++
)
as
an
object
declaration
,
and
must
be
fixed
so
that
it
does
not
resolve
until
later
.
4
)
Indirectly
between
@code{
after_type_declarator
}
and
@code{
parm
}
,
for
type
names
.
This
occurs
in
(
as
one
example
)
code
like
@example
@example
typedef
int
foo
,
bar
;
typedef
int
foo
,
bar
;
...
@@ -1093,11 +1106,12 @@ class A @{
...
@@ -1093,11 +1106,12 @@ class A @{
What
is
@code{
bar
}
inside
the
class
definition
?
We
currently
interpret
What
is
@code{
bar
}
inside
the
class
definition
?
We
currently
interpret
it
as
a
@code{
parm
}
,
as
does
Cfront
,
but
IBM
xlC
interprets
it
as
an
it
as
a
@code{
parm
}
,
as
does
Cfront
,
but
IBM
xlC
interprets
it
as
an
@code{
after_type_declarator
}
.
I
suspect
that
xlC
is
correct
,
in
light
@code{
after_type_declarator
}
.
I
believe
that
xlC
is
correct
,
in
light
of
7
.
1
p2
,
which
says
"The longest sequence of @i{decl-specifiers} that
of
7
.
1
p2
,
which
says
"The longest sequence of @i{decl-specifiers} that
could possibly be a type name is taken as the @i{decl-specifier-seq} of
could possibly be a type name is taken as the @i{decl-specifier-seq} of
a @i{declaration}."
However
,
it
seems
clear
that
this
rule
must
be
a @i{declaration}."
However
,
it
seems
clear
that
this
rule
must
be
violated
in
the
case
of
constructors
,
so
...
violated
in
the
case
of
constructors
.
This
ambiguity
accounts
for
8
conflicts
.
Unlike
the
others
,
this
ambiguity
is
not
recognized
by
the
Working
Paper
.
Unlike
the
others
,
this
ambiguity
is
not
recognized
by
the
Working
Paper
.
...
...
gcc/cp/init.c
View file @
a28e3c7f
...
@@ -52,12 +52,11 @@ static void expand_recursive_init_1 ();
...
@@ -52,12 +52,11 @@ static void expand_recursive_init_1 ();
static
void
expand_recursive_init
();
static
void
expand_recursive_init
();
static
void
expand_virtual_init
PROTO
((
tree
,
tree
,
tree
));
static
void
expand_virtual_init
PROTO
((
tree
,
tree
,
tree
));
tree
expand_vec_init
();
tree
expand_vec_init
();
tree
build_vec_delete
();
static
void
add_friend
(),
add_friends
();
static
void
add_friend
(),
add_friends
();
/* Cache _builtin_new and _builtin_delete exprs. */
/* Cache _builtin_new and _builtin_delete exprs. */
static
tree
BIN
,
BID
;
static
tree
BIN
,
BID
,
BIVN
,
BIVD
;
/* Cache the identifier nodes for the two magic field of a new cookie. */
/* Cache the identifier nodes for the two magic field of a new cookie. */
static
tree
nc_nelts_field_id
;
static
tree
nc_nelts_field_id
;
...
@@ -81,6 +80,10 @@ void init_init_processing ()
...
@@ -81,6 +80,10 @@ void init_init_processing ()
TREE_USED
(
TREE_OPERAND
(
BIN
,
0
))
=
0
;
TREE_USED
(
TREE_OPERAND
(
BIN
,
0
))
=
0
;
BID
=
default_conversion
(
get_first_fn
(
IDENTIFIER_GLOBAL_VALUE
(
ansi_opname
[(
int
)
DELETE_EXPR
])));
BID
=
default_conversion
(
get_first_fn
(
IDENTIFIER_GLOBAL_VALUE
(
ansi_opname
[(
int
)
DELETE_EXPR
])));
TREE_USED
(
TREE_OPERAND
(
BID
,
0
))
=
0
;
TREE_USED
(
TREE_OPERAND
(
BID
,
0
))
=
0
;
BIVN
=
default_conversion
(
get_first_fn
(
IDENTIFIER_GLOBAL_VALUE
(
ansi_opname
[(
int
)
VEC_NEW_EXPR
])));
TREE_USED
(
TREE_OPERAND
(
BIVN
,
0
))
=
0
;
BIVD
=
default_conversion
(
get_first_fn
(
IDENTIFIER_GLOBAL_VALUE
(
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])));
TREE_USED
(
TREE_OPERAND
(
BIVD
,
0
))
=
0
;
minus_one
=
build_int_2
(
-
1
,
-
1
);
minus_one
=
build_int_2
(
-
1
,
-
1
);
/* Define the structure that holds header information for
/* Define the structure that holds header information for
...
@@ -1801,12 +1804,10 @@ is_aggr_typedef (name, or_else)
...
@@ -1801,12 +1804,10 @@ is_aggr_typedef (name, or_else)
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
type
=
IDENTIFIER_TYPE_VALUE
(
name
);
type
=
IDENTIFIER_TYPE_VALUE
(
name
);
else
if
(
IDENTIFIER_HAS_CLASS_TYPE_VALUE
(
name
))
type
=
IDENTIFIER_CLASS_TYPE_VALUE
(
name
);
else
else
{
{
if
(
or_else
)
if
(
or_else
)
cp_error
(
"`%T'
fails to be
an aggregate typedef"
,
name
);
cp_error
(
"`%T'
is not
an aggregate typedef"
,
name
);
return
0
;
return
0
;
}
}
...
@@ -1814,7 +1815,7 @@ is_aggr_typedef (name, or_else)
...
@@ -1814,7 +1815,7 @@ is_aggr_typedef (name, or_else)
&&
TREE_CODE
(
type
)
!=
TEMPLATE_TYPE_PARM
)
&&
TREE_CODE
(
type
)
!=
TEMPLATE_TYPE_PARM
)
{
{
if
(
or_else
)
if
(
or_else
)
cp_error
(
"
type `%T' is of non-
aggregate type"
,
type
);
cp_error
(
"
`%T' is not an
aggregate type"
,
type
);
return
0
;
return
0
;
}
}
return
1
;
return
1
;
...
@@ -1833,8 +1834,6 @@ get_aggr_from_typedef (name, or_else)
...
@@ -1833,8 +1834,6 @@ get_aggr_from_typedef (name, or_else)
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
type
=
IDENTIFIER_TYPE_VALUE
(
name
);
type
=
IDENTIFIER_TYPE_VALUE
(
name
);
else
if
(
IDENTIFIER_HAS_CLASS_TYPE_VALUE
(
name
))
type
=
IDENTIFIER_CLASS_TYPE_VALUE
(
name
);
else
else
{
{
if
(
or_else
)
if
(
or_else
)
...
@@ -1861,8 +1860,6 @@ get_type_value (name)
...
@@ -1861,8 +1860,6 @@ get_type_value (name)
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
return
IDENTIFIER_TYPE_VALUE
(
name
);
return
IDENTIFIER_TYPE_VALUE
(
name
);
else
if
(
IDENTIFIER_CLASS_VALUE
(
name
))
return
IDENTIFIER_CLASS_TYPE_VALUE
(
name
);
else
else
return
NULL_TREE
;
return
NULL_TREE
;
}
}
...
@@ -2808,13 +2805,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
...
@@ -2808,13 +2805,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
TREE_PUBLIC
(
decl
)
=
1
;
TREE_PUBLIC
(
decl
)
=
1
;
add_friend
(
current_class_type
,
decl
);
add_friend
(
current_class_type
,
decl
);
DECL_FRIEND_P
(
decl
)
=
1
;
DECL_FRIEND_P
(
decl
)
=
1
;
if
(
IDENTIFIER_POINTER
(
declarator
)[
0
]
==
'_'
)
{
if
(
!
strcmp
(
IDENTIFIER_POINTER
(
declarator
)
+
10
,
"new"
))
TREE_GETS_NEW
(
current_class_type
)
=
0
;
else
if
(
!
strcmp
(
IDENTIFIER_POINTER
(
declarator
)
+
10
,
"delete"
))
TREE_GETS_DELETE
(
current_class_type
)
=
0
;
}
decl
=
void_type_node
;
decl
=
void_type_node
;
}
}
/* A global friend.
/* A global friend.
...
@@ -2980,6 +2970,7 @@ build_new (placement, decl, init, use_global_new)
...
@@ -2980,6 +2970,7 @@ build_new (placement, decl, init, use_global_new)
tree
type
,
true_type
,
size
,
rval
;
tree
type
,
true_type
,
size
,
rval
;
tree
nelts
;
tree
nelts
;
int
has_array
=
0
;
int
has_array
=
0
;
enum
tree_code
code
=
NEW_EXPR
;
tree
pending_sizes
=
NULL_TREE
;
tree
pending_sizes
=
NULL_TREE
;
...
@@ -3155,27 +3146,28 @@ build_new (placement, decl, init, use_global_new)
...
@@ -3155,27 +3146,28 @@ build_new (placement, decl, init, use_global_new)
/* Get a little extra space to store a couple of things before the new'ed
/* Get a little extra space to store a couple of things before the new'ed
array. */
array. */
if
(
has_array
&&
TYPE_
NEEDS_DESTRUCTOR
(
true_type
))
if
(
has_array
&&
TYPE_
VEC_NEW_USES_COOKIE
(
true_type
))
{
{
tree
extra
=
BI_header_size
;
tree
extra
=
BI_header_size
;
size
=
size_binop
(
PLUS_EXPR
,
size
,
extra
);
size
=
size_binop
(
PLUS_EXPR
,
size
,
extra
);
}
}
if
(
has_array
)
code
=
VEC_NEW_EXPR
;
/* Allocate the object. */
/* Allocate the object. */
if
(
TYPE_LANG_SPECIFIC
(
true_type
)
if
(
!
use_global_new
&&
TYPE_LANG_SPECIFIC
(
true_type
)
&&
(
TREE_GETS_NEW
(
true_type
)
||
TREE_GETS_PLACED_NEW
(
true_type
))
&&
(
TYPE_GETS_NEW
(
true_type
)
&
(
1
<<
has_array
)))
&&
!
use_global_new
rval
=
build_opfncall
(
code
,
LOOKUP_NORMAL
,
&&
!
has_array
)
rval
=
build_opfncall
(
NEW_EXPR
,
LOOKUP_NORMAL
,
TYPE_POINTER_TO
(
true_type
),
size
,
placement
);
TYPE_POINTER_TO
(
true_type
),
size
,
placement
);
else
if
(
placement
)
else
if
(
placement
)
{
{
rval
=
build_opfncall
(
NEW_EXPR
,
LOOKUP_GLOBAL
|
LOOKUP_COMPLAIN
,
rval
=
build_opfncall
(
code
,
LOOKUP_GLOBAL
|
LOOKUP_COMPLAIN
,
ptr_type_node
,
size
,
placement
);
ptr_type_node
,
size
,
placement
);
rval
=
convert
(
TYPE_POINTER_TO
(
true_type
),
rval
);
rval
=
convert
(
TYPE_POINTER_TO
(
true_type
),
rval
);
}
}
else
if
(
flag_this_is_variable
>
0
else
if
(
!
has_array
&&
flag_this_is_variable
>
0
&&
TYPE_HAS_CONSTRUCTOR
(
true_type
)
&&
init
!=
void_type_node
)
&&
TYPE_HAS_CONSTRUCTOR
(
true_type
)
&&
init
!=
void_type_node
)
{
{
if
(
init
==
NULL_TREE
||
TREE_CODE
(
init
)
==
TREE_LIST
)
if
(
init
==
NULL_TREE
||
TREE_CODE
(
init
)
==
TREE_LIST
)
...
@@ -3189,7 +3181,8 @@ build_new (placement, decl, init, use_global_new)
...
@@ -3189,7 +3181,8 @@ build_new (placement, decl, init, use_global_new)
else
else
{
{
rval
=
build_builtin_call
(
build_pointer_type
(
true_type
),
rval
=
build_builtin_call
(
build_pointer_type
(
true_type
),
BIN
,
build_tree_list
(
NULL_TREE
,
size
));
has_array
?
BIVN
:
BIN
,
build_tree_list
(
NULL_TREE
,
size
));
#if 0
#if 0
/* See comment above as to why this is disabled. */
/* See comment above as to why this is disabled. */
if (alignment)
if (alignment)
...
@@ -3202,14 +3195,13 @@ build_new (placement, decl, init, use_global_new)
...
@@ -3202,14 +3195,13 @@ build_new (placement, decl, init, use_global_new)
}
}
#endif
#endif
TREE_CALLS_NEW
(
rval
)
=
1
;
TREE_CALLS_NEW
(
rval
)
=
1
;
TREE_SIDE_EFFECTS
(
rval
)
=
1
;
}
}
/* if rval is NULL_TREE I don't have to allocate it, but are we totally
/* if rval is NULL_TREE I don't have to allocate it, but are we totally
sure we have some extra bytes in that case for the BI_header_size
sure we have some extra bytes in that case for the BI_header_size
cookies? And how does that interact with the code below? (mrs) */
cookies? And how does that interact with the code below? (mrs) */
/* Finish up some magic for new'ed arrays */
/* Finish up some magic for new'ed arrays */
if
(
has_array
&&
TYPE_
NEEDS_DESTRUCTOR
(
true_type
)
&&
rval
!=
NULL_TREE
)
if
(
has_array
&&
TYPE_
VEC_NEW_USES_COOKIE
(
true_type
)
&&
rval
!=
NULL_TREE
)
{
{
tree
extra
=
BI_header_size
;
tree
extra
=
BI_header_size
;
tree
cookie
,
exp1
;
tree
cookie
,
exp1
;
...
@@ -3594,20 +3586,21 @@ expand_vec_init (decl, base, maxindex, init, from_array)
...
@@ -3594,20 +3586,21 @@ expand_vec_init (decl, base, maxindex, init, from_array)
This does not call any destructors. */
This does not call any destructors. */
tree
tree
build_x_delete
(
type
,
addr
,
use_global
_delete
,
virtual_size
)
build_x_delete
(
type
,
addr
,
which
_delete
,
virtual_size
)
tree
type
,
addr
;
tree
type
,
addr
;
int
use_global
_delete
;
int
which
_delete
;
tree
virtual_size
;
tree
virtual_size
;
{
{
int
use_global_delete
=
which_delete
&
1
;
int
use_vec_delete
=
!!
(
which_delete
&
2
);
tree
rval
;
tree
rval
;
enum
tree_code
code
=
use_vec_delete
?
VEC_DELETE_EXPR
:
DELETE_EXPR
;
if
(
!
use_global_delete
if
(
!
use_global_delete
&&
TYPE_LANG_SPECIFIC
(
TREE_TYPE
(
type
))
&&
TYPE_LANG_SPECIFIC
(
TREE_TYPE
(
type
))
&&
(
TYPE_GETS_DELETE
(
TREE_TYPE
(
type
))
&
(
1
<<
use_vec_delete
)))
&&
TREE_GETS_DELETE
(
TREE_TYPE
(
type
)))
rval
=
build_opfncall
(
code
,
LOOKUP_NORMAL
,
addr
,
virtual_size
,
NULL_TREE
);
rval
=
build_opfncall
(
DELETE_EXPR
,
LOOKUP_NORMAL
,
addr
,
virtual_size
,
NULL_TREE
);
else
else
rval
=
build_builtin_call
(
void_type_node
,
BID
,
rval
=
build_builtin_call
(
void_type_node
,
use_vec_delete
?
BIVD
:
BID
,
build_tree_list
(
NULL_TREE
,
addr
));
build_tree_list
(
NULL_TREE
,
addr
));
return
rval
;
return
rval
;
}
}
...
@@ -3674,7 +3667,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
...
@@ -3674,7 +3667,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
addr
=
save_expr
(
addr
);
addr
=
save_expr
(
addr
);
return
build_vec_delete
(
addr
,
array_type_nelts
(
type
),
return
build_vec_delete
(
addr
,
array_type_nelts
(
type
),
c_sizeof_nowarn
(
TREE_TYPE
(
type
)),
c_sizeof_nowarn
(
TREE_TYPE
(
type
)),
NULL_TREE
,
auto_delete
,
integer_two_node
);
auto_delete
,
integer_two_node
,
use_global_delete
);
}
}
else
else
{
{
...
@@ -3707,10 +3701,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
...
@@ -3707,10 +3701,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
/* Pass the size of the object down to the operator delete() in
/* Pass the size of the object down to the operator delete() in
addition to the ADDR. */
addition to the ADDR. */
if
(
T
REE_GETS
_DELETE
(
type
)
&&
!
use_global_delete
)
if
(
T
YPE_GETS_REG
_DELETE
(
type
)
&&
!
use_global_delete
)
{
{
/* This is probably wrong. It should be the size of the virtual
object being deleted. */
tree
virtual_size
=
c_sizeof_nowarn
(
type
);
tree
virtual_size
=
c_sizeof_nowarn
(
type
);
return
build_opfncall
(
DELETE_EXPR
,
LOOKUP_NORMAL
,
addr
,
return
build_opfncall
(
DELETE_EXPR
,
LOOKUP_NORMAL
,
addr
,
virtual_size
,
NULL_TREE
);
virtual_size
,
NULL_TREE
);
...
@@ -3837,7 +3829,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
...
@@ -3837,7 +3829,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
operator delete, call the parent parent destructor (if any),
operator delete, call the parent parent destructor (if any),
but let this node do the deleting. Otherwise, it is ok
but let this node do the deleting. Otherwise, it is ok
to let the parent destructor do the deleting. */
to let the parent destructor do the deleting. */
if
(
T
REE_GETS
_DELETE
(
type
)
&&
!
use_global_delete
)
if
(
T
YPE_GETS_REG
_DELETE
(
type
)
&&
!
use_global_delete
)
{
{
parent_auto_delete
=
integer_zero_node
;
parent_auto_delete
=
integer_zero_node
;
if
(
auto_delete
==
integer_zero_node
)
if
(
auto_delete
==
integer_zero_node
)
...
@@ -3970,8 +3962,6 @@ build_vbase_delete (type, decl)
...
@@ -3970,8 +3962,6 @@ build_vbase_delete (type, decl)
MAXINDEX is the number of elements to be deleted.
MAXINDEX is the number of elements to be deleted.
ELT_SIZE is the nominal size of each element in the vector.
ELT_SIZE is the nominal size of each element in the vector.
BASE is the expression that should yield the store to be deleted.
BASE is the expression that should yield the store to be deleted.
DTOR_DUMMY is a placeholder for a destructor. The library function
__builtin_vec_delete has a pointer to function in this position.
This function expands (or synthesizes) these calls itself.
This function expands (or synthesizes) these calls itself.
AUTO_DELETE_VEC says whether the container (vector) should be deallocated.
AUTO_DELETE_VEC says whether the container (vector) should be deallocated.
AUTO_DELETE say whether each item in the container should be deallocated.
AUTO_DELETE say whether each item in the container should be deallocated.
...
@@ -3985,10 +3975,11 @@ build_vbase_delete (type, decl)
...
@@ -3985,10 +3975,11 @@ build_vbase_delete (type, decl)
confirm the size, and trap if the numbers differ; not clear that it'd
confirm the size, and trap if the numbers differ; not clear that it'd
be worth bothering.) */
be worth bothering.) */
tree
tree
build_vec_delete
(
base
,
maxindex
,
elt_size
,
dtor_dummy
,
auto_delete_vec
,
auto_delete
)
build_vec_delete
(
base
,
maxindex
,
elt_size
,
auto_delete_vec
,
auto_delete
,
use_global_delete
)
tree
base
,
maxindex
,
elt_size
;
tree
base
,
maxindex
,
elt_size
;
tree
dtor_dummy
;
tree
auto_delete_vec
,
auto_delete
;
tree
auto_delete_vec
,
auto_delete
;
int
use_global_delete
;
{
{
tree
ptype
=
TREE_TYPE
(
base
);
tree
ptype
=
TREE_TYPE
(
base
);
tree
type
;
tree
type
;
...
@@ -4081,7 +4072,8 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
...
@@ -4081,7 +4072,8 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
/* This is the real size */
/* This is the real size */
virtual_size
=
size_binop
(
PLUS_EXPR
,
virtual_size
,
BI_header_size
);
virtual_size
=
size_binop
(
PLUS_EXPR
,
virtual_size
,
BI_header_size
);
body
=
build_tree_list
(
NULL_TREE
,
body
=
build_tree_list
(
NULL_TREE
,
build_x_delete
(
ptr_type_node
,
base_tbd
,
1
,
build_x_delete
(
ptype
,
base_tbd
,
2
|
use_global_delete
,
virtual_size
));
virtual_size
));
body
=
build
(
COND_EXPR
,
void_type_node
,
body
=
build
(
COND_EXPR
,
void_type_node
,
build
(
BIT_AND_EXPR
,
integer_type_node
,
build
(
BIT_AND_EXPR
,
integer_type_node
,
...
@@ -4124,7 +4116,7 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
...
@@ -4124,7 +4116,7 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
/* The below is short by BI_header_size */
/* The below is short by BI_header_size */
virtual_size
=
fold
(
size_binop
(
MULT_EXPR
,
size_exp
,
maxindex
));
virtual_size
=
fold
(
size_binop
(
MULT_EXPR
,
size_exp
,
maxindex
));
if
(
loop
==
integer_zero_node
)
if
(
!
TYPE_VEC_NEW_USES_COOKIE
(
type
)
)
/* no header */
/* no header */
base_tbd
=
base
;
base_tbd
=
base
;
else
else
...
@@ -4137,7 +4129,8 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
...
@@ -4137,7 +4129,8 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
/* True size with header. */
/* True size with header. */
virtual_size
=
size_binop
(
PLUS_EXPR
,
virtual_size
,
BI_header_size
);
virtual_size
=
size_binop
(
PLUS_EXPR
,
virtual_size
,
BI_header_size
);
}
}
deallocate_expr
=
build_x_delete
(
ptr_type_node
,
base_tbd
,
1
,
deallocate_expr
=
build_x_delete
(
ptype
,
base_tbd
,
2
|
use_global_delete
,
virtual_size
);
virtual_size
);
if
(
auto_delete_vec
!=
integer_one_node
)
if
(
auto_delete_vec
!=
integer_one_node
)
deallocate_expr
=
build
(
COND_EXPR
,
void_type_node
,
deallocate_expr
=
build
(
COND_EXPR
,
void_type_node
,
...
...
gcc/cp/lex.c
View file @
a28e3c7f
...
@@ -542,6 +542,10 @@ init_lex ()
...
@@ -542,6 +542,10 @@ init_lex ()
IDENTIFIER_OPNAME_P
(
ansi_opname
[(
int
)
NEW_EXPR
])
=
1
;
IDENTIFIER_OPNAME_P
(
ansi_opname
[(
int
)
NEW_EXPR
])
=
1
;
ansi_opname
[(
int
)
DELETE_EXPR
]
=
get_identifier
(
"__dl"
);
ansi_opname
[(
int
)
DELETE_EXPR
]
=
get_identifier
(
"__dl"
);
IDENTIFIER_OPNAME_P
(
ansi_opname
[(
int
)
DELETE_EXPR
])
=
1
;
IDENTIFIER_OPNAME_P
(
ansi_opname
[(
int
)
DELETE_EXPR
])
=
1
;
ansi_opname
[(
int
)
VEC_NEW_EXPR
]
=
get_identifier
(
"__vn"
);
IDENTIFIER_OPNAME_P
(
ansi_opname
[(
int
)
VEC_NEW_EXPR
])
=
1
;
ansi_opname
[(
int
)
VEC_DELETE_EXPR
]
=
get_identifier
(
"__vd"
);
IDENTIFIER_OPNAME_P
(
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])
=
1
;
ansi_opname
[(
int
)
TYPE_EXPR
]
=
get_identifier
(
"__op"
);
ansi_opname
[(
int
)
TYPE_EXPR
]
=
get_identifier
(
"__op"
);
IDENTIFIER_OPNAME_P
(
ansi_opname
[(
int
)
TYPE_EXPR
])
=
1
;
IDENTIFIER_OPNAME_P
(
ansi_opname
[(
int
)
TYPE_EXPR
])
=
1
;
...
@@ -681,6 +685,8 @@ init_lex ()
...
@@ -681,6 +685,8 @@ init_lex ()
opname_tab
[(
int
)
MODIFY_EXPR
]
=
"="
;
opname_tab
[(
int
)
MODIFY_EXPR
]
=
"="
;
opname_tab
[(
int
)
NEW_EXPR
]
=
"new"
;
opname_tab
[(
int
)
NEW_EXPR
]
=
"new"
;
opname_tab
[(
int
)
DELETE_EXPR
]
=
"delete"
;
opname_tab
[(
int
)
DELETE_EXPR
]
=
"delete"
;
opname_tab
[(
int
)
VEC_NEW_EXPR
]
=
"new []"
;
opname_tab
[(
int
)
VEC_DELETE_EXPR
]
=
"delete []"
;
opname_tab
[(
int
)
COND_EXPR
]
=
"... ? ... : ..."
;
opname_tab
[(
int
)
COND_EXPR
]
=
"... ? ... : ..."
;
opname_tab
[(
int
)
CALL_EXPR
]
=
"()"
;
opname_tab
[(
int
)
CALL_EXPR
]
=
"()"
;
opname_tab
[(
int
)
PLUS_EXPR
]
=
"+"
;
opname_tab
[(
int
)
PLUS_EXPR
]
=
"+"
;
...
@@ -841,10 +847,7 @@ yyprint (file, yychar, yylval)
...
@@ -841,10 +847,7 @@ yyprint (file, yychar, yylval)
case
IDENTIFIER_DEFN
:
case
IDENTIFIER_DEFN
:
case
TYPENAME_DEFN
:
case
TYPENAME_DEFN
:
case
PTYPENAME_DEFN
:
case
PTYPENAME_DEFN
:
case
TYPENAME_COLON
:
case
TYPENAME_ELLIPSIS
:
case
TYPENAME_ELLIPSIS
:
case
SCOPED_TYPENAME
:
case
SCOPED_NAME
:
case
SCSPEC
:
case
SCSPEC
:
case
PRE_PARSED_CLASS_DECL
:
case
PRE_PARSED_CLASS_DECL
:
t
=
yylval
.
ttype
;
t
=
yylval
.
ttype
;
...
@@ -2324,14 +2327,15 @@ check_newline ()
...
@@ -2324,14 +2327,15 @@ check_newline ()
register
int
c
;
register
int
c
;
register
int
token
;
register
int
token
;
lineno
++
;
/* Read first nonwhite char on the line. Do this before incrementing the
line number, in case we're at the end of saved text. */
/* Read first nonwhite char on the line. */
do
do
c
=
getch
();
c
=
getch
();
while
(
c
==
' '
||
c
==
'\t'
);
while
(
c
==
' '
||
c
==
'\t'
);
lineno
++
;
if
(
c
!=
'#'
)
if
(
c
!=
'#'
)
{
{
/* If not #, return it so caller will use it. */
/* If not #, return it so caller will use it. */
...
@@ -3080,12 +3084,13 @@ readescape (ignore_ptr)
...
@@ -3080,12 +3084,13 @@ readescape (ignore_ptr)
return
c
;
return
c
;
}
}
/* Value is 1 if we should try to make the next identifier look like a
/* Value is 1 (or 2) if we should try to make the next identifier look like
typename (when it may be a local variable or a class variable).
a typename (when it may be a local variable or a class variable).
Value is 0 if we treat this name in a default fashion.
Value is 0 if we treat this name in a default fashion. */
Value is -1 if we must not see a type name. */
int
looking_for_typename
=
0
;
int
looking_for_typename
=
0
;
#if 0
/* NO LONGER USED: Value is -1 if we must not see a type name. */
void
void
dont_see_typename ()
dont_see_typename ()
{
{
...
@@ -3096,6 +3101,7 @@ dont_see_typename ()
...
@@ -3096,6 +3101,7 @@ dont_see_typename ()
lastiddecl = 0;
lastiddecl = 0;
}
}
}
}
#endif
#ifdef __GNUC__
#ifdef __GNUC__
extern
__inline
int
identifier_type
();
extern
__inline
int
identifier_type
();
...
@@ -3119,7 +3125,7 @@ see_typename ()
...
@@ -3119,7 +3125,7 @@ see_typename ()
looking_for_typename
=
0
;
looking_for_typename
=
0
;
if
(
yychar
==
IDENTIFIER
)
if
(
yychar
==
IDENTIFIER
)
{
{
lastiddecl
=
lookup_name
(
yylval
.
ttype
,
-
1
);
lastiddecl
=
lookup_name
(
yylval
.
ttype
,
-
2
);
if
(
lastiddecl
==
0
)
if
(
lastiddecl
==
0
)
{
{
if
(
flag_labels_ok
)
if
(
flag_labels_ok
)
...
@@ -3540,7 +3546,6 @@ real_yylex ()
...
@@ -3540,7 +3546,6 @@ real_yylex ()
}
}
if
(
value
==
NEW
&&
!
global_bindings_p
())
if
(
value
==
NEW
&&
!
global_bindings_p
())
{
{
looking_for_typename
=
1
;
value
=
NEW
;
value
=
NEW
;
goto
done
;
goto
done
;
}
}
...
...
gcc/cp/lex.h
View file @
a28e3c7f
...
@@ -114,6 +114,9 @@ extern char *token_buffer; /* Pointer to token buffer. */
...
@@ -114,6 +114,9 @@ extern char *token_buffer; /* Pointer to token buffer. */
/* Back-door communication channel to the lexer. */
/* Back-door communication channel to the lexer. */
extern
int
looking_for_typename
;
extern
int
looking_for_typename
;
/* Tell the lexer where to look for names. */
extern
tree
got_scope
;
/* Pending language change.
/* Pending language change.
Positive is push count, negative is pop count. */
Positive is push count, negative is pop count. */
extern
int
pending_lang_change
;
extern
int
pending_lang_change
;
...
...
gcc/cp/method.c
View file @
a28e3c7f
...
@@ -840,27 +840,22 @@ build_decl_overload (dname, parms, for_method)
...
@@ -840,27 +840,22 @@ build_decl_overload (dname, parms, for_method)
{
{
char
*
name
=
IDENTIFIER_POINTER
(
dname
);
char
*
name
=
IDENTIFIER_POINTER
(
dname
);
if
(
dname
==
ansi_opname
[(
int
)
NEW_EXPR
]
/* member operators new and delete look like methods at this point. */
&&
parms
!=
NULL_TREE
if
(
!
for_method
&&
parms
!=
NULL_TREE
&&
TREE_CODE
(
parms
)
==
TREE_LIST
)
&&
TREE_CODE
(
parms
)
==
TREE_LIST
{
&&
TREE_VALUE
(
parms
)
==
sizetype
if
(
TREE_VALUE
(
parms
)
==
sizetype
&&
TREE_CHAIN
(
parms
)
==
void_list_node
)
&&
TREE_CHAIN
(
parms
)
==
void_list_node
)
return
get_identifier
(
"__builtin_new"
);
{
else
if
(
dname
==
ansi_opname
[(
int
)
DELETE_EXPR
]
if
(
dname
==
ansi_opname
[(
int
)
NEW_EXPR
])
&&
parms
!=
NULL_TREE
return
get_identifier
(
"__builtin_new"
);
&&
TREE_CODE
(
parms
)
==
TREE_LIST
else
if
(
dname
==
ansi_opname
[(
int
)
VEC_NEW_EXPR
])
&&
TREE_VALUE
(
parms
)
==
ptr_type_node
return
get_identifier
(
"__builtin_vec_new"
);
&&
TREE_CHAIN
(
parms
)
==
void_list_node
)
}
return
get_identifier
(
"__builtin_delete"
);
else
if
(
dname
==
ansi_opname
[(
int
)
DELETE_EXPR
])
else
if
(
dname
==
ansi_opname
[(
int
)
DELETE_EXPR
]
return
get_identifier
(
"__builtin_delete"
);
&&
parms
!=
NULL_TREE
else
if
(
dname
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])
&&
TREE_CODE
(
parms
)
==
TREE_LIST
return
get_identifier
(
"__builtin_vec_delete"
);
&&
TREE_VALUE
(
parms
)
==
ptr_type_node
}
&&
TREE_CHAIN
(
parms
)
!=
NULL_TREE
&&
TREE_CODE
(
TREE_CHAIN
(
parms
))
==
TREE_LIST
&&
TREE_VALUE
(
TREE_CHAIN
(
parms
))
==
sizetype
&&
TREE_CHAIN
(
TREE_CHAIN
(
parms
))
==
void_list_node
)
return
get_identifier
(
"__builtin_delete"
);
OB_INIT
();
OB_INIT
();
if
(
for_method
!=
2
)
if
(
for_method
!=
2
)
...
@@ -1112,19 +1107,19 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
...
@@ -1112,19 +1107,19 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
try_second
=
0
;
try_second
=
0
;
break
;
break
;
case
VEC_NEW_EXPR
:
case
NEW_EXPR
:
case
NEW_EXPR
:
{
{
fnname
=
ansi_opname
[(
int
)
NEW_EXPR
];
tree
args
=
tree_cons
(
NULL_TREE
,
xarg2
,
arg3
);
fnname
=
ansi_opname
[(
int
)
code
];
if
(
flags
&
LOOKUP_GLOBAL
)
if
(
flags
&
LOOKUP_GLOBAL
)
return
build_overload_call
(
fnname
,
tree_cons
(
NULL_TREE
,
xarg2
,
arg3
),
return
build_overload_call
(
fnname
,
args
,
flags
&
LOOKUP_COMPLAIN
,
flags
&
LOOKUP_COMPLAIN
,
(
struct
candidate
*
)
0
);
(
struct
candidate
*
)
0
);
rval
=
build_method_call
rval
=
build_method_call
(
build_indirect_ref
(
build1
(
NOP_EXPR
,
xarg1
,
error_mark_node
),
(
build_indirect_ref
(
build1
(
NOP_EXPR
,
xarg1
,
error_mark_node
),
"new"
),
"new"
),
fnname
,
tree_cons
(
NULL_TREE
,
xarg2
,
arg3
),
fnname
,
args
,
NULL_TREE
,
flags
);
NULL_TREE
,
flags
);
if
(
rval
==
error_mark_node
)
if
(
rval
==
error_mark_node
)
/* User might declare fancy operator new, but invoke it
/* User might declare fancy operator new, but invoke it
like standard one. */
like standard one. */
...
@@ -1136,13 +1131,13 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
...
@@ -1136,13 +1131,13 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
}
}
break
;
break
;
case
VEC_DELETE_EXPR
:
case
DELETE_EXPR
:
case
DELETE_EXPR
:
{
{
fnname
=
ansi_opname
[(
int
)
DELETE_EXPR
];
fnname
=
ansi_opname
[(
int
)
code
];
if
(
flags
&
LOOKUP_GLOBAL
)
if
(
flags
&
LOOKUP_GLOBAL
)
return
build_overload_call
(
fnname
,
return
build_overload_call
(
fnname
,
tree_cons
(
NULL_TREE
,
xarg1
,
build_tree_list
(
NULL_TREE
,
xarg1
),
build_tree_list
(
NULL_TREE
,
xarg2
)),
flags
&
LOOKUP_COMPLAIN
,
flags
&
LOOKUP_COMPLAIN
,
(
struct
candidate
*
)
0
);
(
struct
candidate
*
)
0
);
...
@@ -1151,7 +1146,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
...
@@ -1151,7 +1146,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
error_mark_node
),
error_mark_node
),
NULL_PTR
),
NULL_PTR
),
fnname
,
tree_cons
(
NULL_TREE
,
xarg1
,
fnname
,
tree_cons
(
NULL_TREE
,
xarg1
,
build_tree_list
(
NULL_TREE
,
xarg2
)),
build_tree_list
(
NULL_TREE
,
xarg2
)),
NULL_TREE
,
flags
);
NULL_TREE
,
flags
);
/* This happens when the user mis-declares `operator delete'.
/* This happens when the user mis-declares `operator delete'.
Should now be impossible. */
Should now be impossible. */
...
...
gcc/cp/parse.y
View file @
a28e3c7f
...
@@ -66,12 +66,16 @@ extern int errno;
...
@@ -66,12 +66,16 @@ extern int errno;
#endif
#endif
extern int end_of_file;
extern int end_of_file;
extern int current_class_depth;
void yyerror ();
void yyerror ();
/* Like YYERROR but do call yyerror. */
/* Like YYERROR but do call yyerror. */
#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
#define OP0(NODE) (TREE_OPERAND (NODE, 0))
#define OP1(NODE) (TREE_OPERAND (NODE, 1))
/* Contains the statement keyword (if/while/do) to include in an
/* Contains the statement keyword (if/while/do) to include in an
error message if the user supplies an empty conditional expression. */
error message if the user supplies an empty conditional expression. */
static char *cond_stmt_keyword;
static char *cond_stmt_keyword;
...
@@ -112,12 +116,6 @@ empty_parms ()
...
@@ -112,12 +116,6 @@ empty_parms ()
but they can also serve as typespecs in declarations. */
but they can also serve as typespecs in declarations. */
%token TYPENAME
%token TYPENAME
/* Qualified identifiers that end in a TYPENAME. */
%token SCOPED_TYPENAME
/* Qualified identifiers that end in a IDENTIFIER. */
%token SCOPED_NAME
/* Reserved words that specify storage class.
/* Reserved words that specify storage class.
yylval contains an IDENTIFIER_NODE which indicates which one. */
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token SCSPEC
%token SCSPEC
...
@@ -156,11 +154,6 @@ empty_parms ()
...
@@ -156,11 +154,6 @@ empty_parms ()
%token TYPEID DYNAMIC_CAST
%token TYPEID DYNAMIC_CAST
%token <itype> SCOPE
%token <itype> SCOPE
/* Special token created by the lexer to separate TYPENAME
from an ABSDCL. This allows us to parse `foo (*pf)()'. */
%token START_DECLARATOR
/* Define the operator tokens and their precedences.
/* Define the operator tokens and their precedences.
The value is an integer because, if used, it is the tree code
The value is an integer because, if used, it is the tree code
to use in the expression made from the operator. */
to use in the expression made from the operator. */
...
@@ -173,7 +166,7 @@ empty_parms ()
...
@@ -173,7 +166,7 @@ empty_parms ()
%nonassoc IF
%nonassoc IF
%nonassoc ELSE
%nonassoc ELSE
%left IDENTIFIER TYPENAME PTYPENAME
TYPENAME_COLON SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS SCOPED_TYPENAME TYPEOF SIGOF START_DECLARATOR
OPERATOR
%left IDENTIFIER TYPENAME PTYPENAME
SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF
OPERATOR
%left '{' ',' ';'
%left '{' ',' ';'
...
@@ -217,30 +210,28 @@ empty_parms ()
...
@@ -217,30 +210,28 @@ empty_parms ()
%type <ttype> compstmt except_stmts ansi_except_stmts implicitly_scoped_stmt
%type <ttype> compstmt except_stmts ansi_except_stmts implicitly_scoped_stmt
%type <ttype> declarator notype_declarator after_type_declarator
%type <ttype> declarator notype_declarator after_type_declarator
%type <ttype> notype_declarator1 after_type_declarator1
%type <ttype> direct_notype_declarator direct_after_type_declarator
%type <ttype> direct_notype_declarator direct_after_type_declarator
%type <ttype> structsp opt.component_decl_list component_decl_list
%type <ttype> structsp opt.component_decl_list component_decl_list
%type <ttype> component_decl components component_declarator
%type <ttype> component_decl components component_declarator
%type <ttype> notype_components notype_component_declarator
%type <ttype> notype_components notype_component_declarator
%type <ttype> after_type_component_declarator after_type_component_declarator0
%type <ttype> after_type_component_declarator after_type_component_declarator0
%type <ttype> notype_component_declarator0
%type <ttype> notype_component_declarator0
component_decl_1
%type <ttype> enumlist enumerator
%type <ttype> enumlist enumerator
%type <ttype> type_id absdcl
absdcl1
type_quals
%type <ttype> type_id absdcl type_quals
%type <ttype> direct_abstract_declarator conversion_declarator
%type <ttype> direct_abstract_declarator conversion_declarator
%type <ttype> new_type_id new_declarator direct_new_declarator
%type <ttype> new_type_id new_declarator direct_new_declarator
%type <ttype> xexpr parmlist parms parm bad_parm
%type <ttype> xexpr parmlist parms parm bad_parm
%type <ttype> identifiers_or_typenames
%type <ttype> identifiers_or_typenames
%type <ttype> fcast_or_absdcl regcast_or_absdcl sub_cast_expr
%type <ttype> fcast_or_absdcl regcast_or_absdcl sub_cast_expr
%type <ttype> expr_or_declarator complex_notype_declarator1
%type <ttype> expr_or_declarator complex_notype_declarator
%type <ttype> notype_unqualified_id
%type <ttype> notype_unqualified_id unqualified_id qualified_id
%type <ttype> overqualified_id notype_qualified_id
%type <ttype> complex_direct_notype_declarator functional_cast
%type <ttype> complex_direct_notype_declarator functional_cast
%type <ttype> named_parm complex_parmlist typed_declspecs1 parms_comma
%type <ttype> named_parm complex_parmlist typed_declspecs1 parms_comma
/* C++ extensions */
/* C++ extensions */
%type <ttype> typename_scope
%token <ttype> TYPENAME_ELLIPSIS PTYPENAME
%token <ttype> TYPENAME_COLON TYPENAME_ELLIPSIS
%token <ttype> PTYPENAME SCOPED_TYPENAME SCOPED_NAME
%token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
%token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
%token <ttype> PRE_PARSED_CLASS_DECL
%token <ttype> PRE_PARSED_CLASS_DECL
%type <ttype> fn.def1 /* Not really! */
%type <ttype> fn.def1 /* Not really! */
...
@@ -251,21 +242,26 @@ empty_parms ()
...
@@ -251,21 +242,26 @@ empty_parms ()
%type <itype> base_class_access_list
%type <itype> base_class_access_list
%type <ttype> base_class maybe_base_class_list base_class.1
%type <ttype> base_class maybe_base_class_list base_class.1
%type <ttype> maybe_raises raise_identifier raise_identifiers ansi_raise_identifier ansi_raise_identifiers
%type <ttype> maybe_raises raise_identifier raise_identifiers ansi_raise_identifier ansi_raise_identifiers
%type <ttype> component_declarator0 id_scope scoped_typename scoped_base_class
%type <ttype> component_declarator0
%type <ttype> forhead.1 identifier_or_opname operator_name
%type <ttype> forhead.1 operator_name
%type <ttype> new delete object aggr
%type <ttype> new object aggr
%type <itype> delete
/* %type <ttype> primary_no_id */
/* %type <ttype> primary_no_id */
%type <ttype> nonmomentary_expr
%type <ttype> nonmomentary_expr
%type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
%type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
%type <itype> .scope try ansi_try
%type <itype> .scope try ansi_try
%type <ttype> template_header template_parm_list template_parm
%type <ttype> template_header template_parm_list template_parm
%type <ttype> template_type template_arg_list template_arg
%type <ttype> template_type template_arg_list template_arg
%type <ttype> template_instantiation template_type_name tmpl.
1 tmpl.
2
%type <ttype> template_instantiation template_type_name tmpl.2
%type <ttype> template_instantiate_once template_instantiate_some
%type <ttype> template_instantiate_once template_instantiate_some
%type <itype> fn_tmpl_end
%type <itype> fn_tmpl_end
/* %type <itype> try_for_typename */
/* %type <itype> try_for_typename */
%type <ttype> condition partially_scoped_stmt xcond paren_cond_or_null
%type <ttype> condition partially_scoped_stmt xcond paren_cond_or_null
%type <strtype> .kindof_pushlevel
%type <strtype> .kindof_pushlevel
%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
%type <ttype> qualified_type_name complete_type_name notype_identifier
%type <ttype> complex_type_name nested_name_specifier_1
%type <itype> nomods_initdecls nomods_initdcl0
/* in order to recognize aggr tags as defining and thus shadowing. */
/* in order to recognize aggr tags as defining and thus shadowing. */
%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
...
@@ -405,15 +401,6 @@ template_parm:
...
@@ -405,15 +401,6 @@ template_parm:
warning ("restricted template type parameters not yet implemented");
warning ("restricted template type parameters not yet implemented");
$$ = build_tree_list ($2, $4);
$$ = build_tree_list ($2, $4);
}
}
| aggr TYPENAME_COLON base_class.1
{
if ($1 == signature_type_node)
sorry ("signature as template type parameter");
else if ($1 != class_type_node)
error ("template type parameter must use keyword `class'");
warning ("restricted template type parameters not yet implemented");
$$ = build_tree_list ($2, $3);
}
| parm
| parm
;
;
...
@@ -528,11 +515,8 @@ fn_tmpl_end: '{' { $$ = '{'; }
...
@@ -528,11 +515,8 @@ fn_tmpl_end: '{' { $$ = '{'; }
;
;
datadef:
datadef:
notype_initdecls ';'
nomods_initdecls ';'
{ if (pedantic)
{}
pedwarn ("ANSI C++ forbids data definition with no type or storage class");
else if (! flag_traditional && ! have_extern_spec)
warning ("data definition has no type or storage class"); }
| declmods notype_initdecls ';'
| declmods notype_initdecls ';'
{}
{}
/* Normal case to make fast: "const i;". */
/* Normal case to make fast: "const i;". */
...
@@ -649,26 +633,6 @@ fn.def1:
...
@@ -649,26 +633,6 @@ fn.def1:
YYERROR1;
YYERROR1;
reinit_parse_for_function ();
reinit_parse_for_function ();
$$ = NULL_TREE; }
$$ = NULL_TREE; }
| TYPENAME '(' parmlist ')' type_quals maybe_raises
{ if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0))
YYERROR1;
reinit_parse_for_function ();
$$ = NULL_TREE; }
| scoped_typename '(' parmlist ')' type_quals maybe_raises
{ if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0))
YYERROR1;
reinit_parse_for_function ();
$$ = NULL_TREE; }
| TYPENAME LEFT_RIGHT type_quals maybe_raises
{ if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0))
YYERROR1;
reinit_parse_for_function ();
$$ = NULL_TREE; }
| scoped_typename LEFT_RIGHT type_quals maybe_raises
{ if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0))
YYERROR1;
reinit_parse_for_function ();
$$ = NULL_TREE; }
| PRE_PARSED_FUNCTION_DECL
| PRE_PARSED_FUNCTION_DECL
{ start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1);
{ start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1);
reinit_parse_for_function (); }
reinit_parse_for_function (); }
...
@@ -679,8 +643,9 @@ fn.def1:
...
@@ -679,8 +643,9 @@ fn.def1:
fn.def2:
fn.def2:
typed_declspecs '(' parmlist ')' type_quals maybe_raises
typed_declspecs '(' parmlist ')' type_quals maybe_raises
{
{
tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5);
$$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
$$ = start_method (TREE_CHAIN ($$), decl, $6);
$$ = start_method (TREE_CHAIN ($1), $$, $6);
rest_of_mdef:
if (! $$)
if (! $$)
YYERROR1;
YYERROR1;
if (yychar == YYEMPTY)
if (yychar == YYEMPTY)
...
@@ -688,52 +653,17 @@ fn.def2:
...
@@ -688,52 +653,17 @@ fn.def2:
reinit_parse_for_method (yychar, $$); }
reinit_parse_for_method (yychar, $$); }
| typed_declspecs LEFT_RIGHT type_quals maybe_raises
| typed_declspecs LEFT_RIGHT type_quals maybe_raises
{
{
tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3);
$$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
$$ = start_method (TREE_CHAIN ($$), decl, $4);
empty_parms (), $3);
if (! $$)
$$ = start_method (TREE_CHAIN ($1), $$, $4);
YYERROR1;
goto rest_of_mdef;
if (yychar == YYEMPTY)
}
yychar = YYLEX;
reinit_parse_for_method (yychar, $$); }
| typed_declspecs declarator maybe_raises
| typed_declspecs declarator maybe_raises
{ $$ = start_method ($$, $2, $3);
{ $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
if (! $$)
YYERROR1;
if (yychar == YYEMPTY)
yychar = YYLEX;
reinit_parse_for_method (yychar, $$); }
| declmods '(' parmlist ')' type_quals maybe_raises
{
tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5);
$$ = start_method (TREE_CHAIN ($$), decl, $6);
if (! $$)
YYERROR1;
if (yychar == YYEMPTY)
yychar = YYLEX;
reinit_parse_for_method (yychar, $$); }
| declmods LEFT_RIGHT type_quals maybe_raises
{
tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3);
$$ = start_method (TREE_CHAIN ($$), decl, $4);
if (! $$)
YYERROR1;
if (yychar == YYEMPTY)
yychar = YYLEX;
reinit_parse_for_method (yychar, $$); }
| declmods notype_declarator maybe_raises
| declmods notype_declarator maybe_raises
{ $$ = start_method ($$, $2, $3);
{ $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
if (! $$)
YYERROR1;
if (yychar == YYEMPTY)
yychar = YYLEX;
reinit_parse_for_method (yychar, $$); }
| notype_declarator maybe_raises
| notype_declarator maybe_raises
{ $$ = start_method (NULL_TREE, $$, $2);
{ $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
if (! $$)
YYERROR1;
if (yychar == YYEMPTY)
yychar = YYLEX;
reinit_parse_for_method (yychar, $$); }
;
;
return_id: RETURN IDENTIFIER
return_id: RETURN IDENTIFIER
...
@@ -811,27 +741,22 @@ member_init: '(' nonnull_exprlist ')'
...
@@ -811,27 +741,22 @@ member_init: '(' nonnull_exprlist ')'
pedwarn ("anachronistic old style base class initializer");
pedwarn ("anachronistic old style base class initializer");
expand_member_init (C_C_D, NULL_TREE, void_type_node);
expand_member_init (C_C_D, NULL_TREE, void_type_node);
}
}
| identifier '(' nonnull_exprlist ')'
| notype_identifier '(' nonnull_exprlist ')'
{
expand_member_init (C_C_D, $<ttype>$, $3);
}
| identifier LEFT_RIGHT
{ expand_member_init (C_C_D, $<ttype>$, void_type_node); }
| template_type_name '(' nonnull_exprlist ')'
{ expand_member_init (C_C_D, $<ttype>$, $3); }
{ expand_member_init (C_C_D, $<ttype>$, $3); }
|
template_type_name
LEFT_RIGHT
|
notype_identifier
LEFT_RIGHT
{ expand_member_init (C_C_D, $<ttype>$, void_type_node); }
{ expand_member_init (C_C_D, $<ttype>$, void_type_node); }
|
scoped_type
name '(' nonnull_exprlist ')'
|
complete_type_
name '(' nonnull_exprlist ')'
{ expand_member_init (C_C_D, $<ttype>$, $3); }
{ expand_member_init (C_C_D, $<ttype>$, $3); }
|
scoped_type
name LEFT_RIGHT
|
complete_type_
name LEFT_RIGHT
{ expand_member_init (C_C_D, $<ttype>$, void_type_node); }
{ expand_member_init (C_C_D, $<ttype>$, void_type_node); }
| id_scope identifier '(' nonnull_exprlist ')'
/* GNU extension */
| notype_qualified_id '(' nonnull_exprlist ')'
{
{
do_member_init (
$<ttype>$, $2, $4
);
do_member_init (
OP0 ($1), OP1 ($1), $3
);
}
}
|
id_scope identifier
LEFT_RIGHT
|
notype_qualified_id
LEFT_RIGHT
{
{
do_member_init (
$<ttype>$, $2
, void_type_node);
do_member_init (
OP0 ($1), OP1 ($1)
, void_type_node);
}
}
;
;
...
@@ -841,23 +766,17 @@ identifier:
...
@@ -841,23 +766,17 @@ identifier:
| PTYPENAME
| PTYPENAME
;
;
notype_identifier:
IDENTIFIER
| PTYPENAME %prec EMPTY
;
identifier_defn:
identifier_defn:
IDENTIFIER_DEFN
IDENTIFIER_DEFN
| TYPENAME_DEFN
| TYPENAME_DEFN
| PTYPENAME_DEFN
| PTYPENAME_DEFN
;
;
identifier_or_opname:
IDENTIFIER
| TYPENAME
| PTYPENAME
/* | '~' TYPENAME
{ $$ = build_parse_node (BIT_NOT_EXPR, $2); }*/
/* get rid of the next line, replace it with the above */
| '~' identifier { $$ = build_parse_node (BIT_NOT_EXPR,$2);}
| operator_name
;
explicit_instantiation:
explicit_instantiation:
TEMPLATE aggr template_type
TEMPLATE aggr template_type
| TEMPLATE typed_declspecs declarator
| TEMPLATE typed_declspecs declarator
...
@@ -865,32 +784,8 @@ explicit_instantiation:
...
@@ -865,32 +784,8 @@ explicit_instantiation:
;
;
template_type:
template_type:
template_type_name tmpl.1 template_instantiation
template_type_name tmpl.2 template_instantiation
{
{ if ($3) $$ = $3; }
extern tree template_type_seen_before_scope;
if ($3)
$$ = $3;
else if ($$ != error_mark_node)
$$ = IDENTIFIER_TYPE_VALUE ($$);
/* This is a kludge: In order to detect nested types inside
* template classes, we have to tell the lexer that it should
* try to replace a following SCOPE token with the correct
* SCOPED_TYPENAME for the nested type. This SCOPED_TYPENAME
* token will be handled in the rule "scoped_typename".
* - niklas@appli.se */
if (yychar == SCOPE)
{
/* We set template_type_seen_before_scope to be
an error_mark_node so we can avoid meaningless
and unhelpful syntax errors later. */
if ($$ != error_mark_node)
template_type_seen_before_scope = TYPE_IDENTIFIER ($$);
else
template_type_seen_before_scope = error_mark_node;
yychar = YYLEX;
}
}
;
;
template_type_name:
template_type_name:
...
@@ -900,16 +795,7 @@ template_type_name:
...
@@ -900,16 +795,7 @@ template_type_name:
{ $$ = lookup_template_class ($$, $3, NULL_TREE); }
{ $$ = lookup_template_class ($$, $3, NULL_TREE); }
;
;
tmpl.1:
tmpl.2: %prec EMPTY
/* Expansion of template may be required, unless we're followed by
a class definition. */
'{' { yyungetc ('{', 1); $$ = 0; }
| ':' { yyungetc (':', 1); $$ = 0; }
| /* empty */ %prec EMPTY
{ $$ = instantiate_class_template ($<ttype>0, 1); }
;
tmpl.2:
/* Always do expansion if it hasn't been done already. */
/* Always do expansion if it hasn't been done already. */
{ $$ = instantiate_class_template ($<ttype>0, 1); }
{ $$ = instantiate_class_template ($<ttype>0, 1); }
;
;
...
@@ -961,7 +847,7 @@ template_instantiate_once:
...
@@ -961,7 +847,7 @@ template_instantiate_once:
}
}
left_curly opt.component_decl_list '}'
left_curly opt.component_decl_list '}'
{
{
$$
= finish_struct ($<ttype>3, $5, 0);
tree t
= finish_struct ($<ttype>3, $5, 0);
pop_obstacks ();
pop_obstacks ();
end_template_instantiation ($1);
end_template_instantiation ($1);
...
@@ -971,7 +857,7 @@ template_instantiate_once:
...
@@ -971,7 +857,7 @@ template_instantiate_once:
pop_tinst_level();
pop_tinst_level();
CLASSTYPE_GOT_SEMICOLON (
$$
) = 1;
CLASSTYPE_GOT_SEMICOLON (
t
) = 1;
}
}
;
;
...
@@ -1229,20 +1115,15 @@ unary_expr:
...
@@ -1229,20 +1115,15 @@ unary_expr:
| .scope new '(' nonnull_exprlist ')' '(' type_id ')'
| .scope new '(' nonnull_exprlist ')' '(' type_id ')'
{ $$ = build_new ($4, groktypename ($7), NULL_TREE,
{ $$ = build_new ($4, groktypename ($7), NULL_TREE,
$$ != NULL_TREE); }
$$ != NULL_TREE); }
/* Unswallow a ':' which is probably meant for ?: expression. */
| .scope new TYPENAME_COLON
{ yyungetc (':', 1); $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); }
| .scope new '(' nonnull_exprlist ')' TYPENAME_COLON
{ yyungetc (':', 1); $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); }
| delete cast_expr %prec UNARY
| delete cast_expr %prec UNARY
{ $$ = delete_sanity ($2, NULL_TREE, 0, $
$ != NULL_TREE
); }
{ $$ = delete_sanity ($2, NULL_TREE, 0, $
1
); }
| delete '[' ']' cast_expr %prec UNARY
| delete '[' ']' cast_expr %prec UNARY
{ $$ = delete_sanity ($4, NULL_TREE, 1, $
$ != NULL_TREE
);
{ $$ = delete_sanity ($4, NULL_TREE, 1, $
1
);
if (yychar == YYEMPTY)
if (yychar == YYEMPTY)
yychar = YYLEX; }
yychar = YYLEX; }
| delete '[' expr ']' cast_expr %prec UNARY
| delete '[' expr ']' cast_expr %prec UNARY
{ $$ = delete_sanity ($5, $3, 2, $
$ != NULL_TREE
);
{ $$ = delete_sanity ($5, $3, 2, $
1
);
if (yychar == YYEMPTY)
if (yychar == YYEMPTY)
yychar = YYLEX; }
yychar = YYLEX; }
;
;
...
@@ -1368,33 +1249,33 @@ expr_no_commas:
...
@@ -1368,33 +1249,33 @@ expr_no_commas:
;
;
notype_unqualified_id:
notype_unqualified_id:
'~' see_typename TYPENAME
'~' see_typename identifier
{
{ $$ = build_parse_node (BIT_NOT_EXPR, $3); }
destructor_name:
$$ = build_parse_node (BIT_NOT_EXPR, $3);
}
| '~' see_typename IDENTIFIER
{ goto destructor_name; }
| '~' see_typename PTYPENAME
{ goto destructor_name; }
| operator_name
| operator_name
| IDENTIFIER
| IDENTIFIER
| PTYPENAME %prec EMPTY
| PTYPENAME %prec EMPTY
;
;
unqualified_id:
notype_unqualified_id
| TYPENAME
;
expr_or_declarator:
expr_or_declarator:
'*' expr_or_declarator %prec UNARY
notype_unqualified_id
| notype_qualified_id
| '*' expr_or_declarator %prec UNARY
{ $$ = build_parse_node (INDIRECT_REF, $2); }
{ $$ = build_parse_node (INDIRECT_REF, $2); }
| '&' expr_or_declarator %prec UNARY
| '&' expr_or_declarator %prec UNARY
{ $$ = build_parse_node (ADDR_EXPR, $2); }
{ $$ = build_parse_node (ADDR_EXPR, $2); }
| notype_unqualified_id
{ see_typename (); }
;
;
direct_notype_declarator:
direct_notype_declarator:
complex_direct_notype_declarator
complex_direct_notype_declarator
| notype_unqualified_id
| notype_unqualified_id
{ see_typename (); }
| notype_qualified_id
{ push_nested_class (TREE_TYPE (OP0 ($$)), 3);
TREE_COMPLEXITY ($$) = current_class_depth; }
;
;
primary:
primary:
...
@@ -1474,10 +1355,6 @@ primary:
...
@@ -1474,10 +1355,6 @@ primary:
}
}
| primary '[' expr ']'
| primary '[' expr ']'
{ $$ = grok_array_decl ($$, $3); }
{ $$ = grok_array_decl ($$, $3); }
| object identifier_or_opname %prec UNARY
{ $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
| object id_scope identifier_or_opname %prec UNARY
{ $$ = build_object_ref ($$, $2, $3); }
| primary PLUSPLUS
| primary PLUSPLUS
{ /* If we get an OFFSET_REF, turn it into what it really
{ /* If we get an OFFSET_REF, turn it into what it really
means (e.g., a COMPONENT_REF). This way if we've got,
means (e.g., a COMPONENT_REF). This way if we've got,
...
@@ -1569,7 +1446,7 @@ primary:
...
@@ -1569,7 +1446,7 @@ primary:
| TYPEID '(' type_id ')'
| TYPEID '(' type_id ')'
{ tree type = groktypename ($3);
{ tree type = groktypename ($3);
$$ = get_typeid (type); }
$$ = get_typeid (type); }
|
SCOPE
IDENTIFIER
|
global_scope
IDENTIFIER
{
{
do_scoped_id:
do_scoped_id:
$$ = IDENTIFIER_GLOBAL_VALUE ($2);
$$ = IDENTIFIER_GLOBAL_VALUE ($2);
...
@@ -1608,19 +1485,24 @@ primary:
...
@@ -1608,19 +1485,24 @@ primary:
}
}
}
}
|
SCOPE
operator_name
|
global_scope
operator_name
{
{
got_scope = NULL_TREE;
if (TREE_CODE ($2) == IDENTIFIER_NODE)
if (TREE_CODE ($2) == IDENTIFIER_NODE)
goto do_scoped_id;
goto do_scoped_id;
$$ = $2;
$$ = $2;
}
}
| id_scope identifier_or_opname %prec HYPERUNARY
| overqualified_id %prec HYPERUNARY
{ $$ = build_offset_ref ($$, $2); }
{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
| id_scope identifier_or_opname '(' nonnull_exprlist ')'
| overqualified_id '(' nonnull_exprlist ')'
{ $$ = build_member_call ($$, $2, $4); }
{ $$ = build_member_call (OP0 ($$), OP1 ($$), $3); }
| id_scope identifier_or_opname LEFT_RIGHT
| overqualified_id LEFT_RIGHT
{ $$ = build_member_call ($$, $2, NULL_TREE); }
{ $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }
| object identifier_or_opname '(' nonnull_exprlist ')'
| object unqualified_id %prec UNARY
{ $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
| object qualified_id %prec UNARY
{ $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
| object unqualified_id '(' nonnull_exprlist ')'
{
{
#if 0
#if 0
/* This is a future direction of this code, but because
/* This is a future direction of this code, but because
...
@@ -1635,7 +1517,7 @@ primary:
...
@@ -1635,7 +1517,7 @@ primary:
(LOOKUP_NORMAL|LOOKUP_AGGR));
(LOOKUP_NORMAL|LOOKUP_AGGR));
#endif
#endif
}
}
| object
identifier_or_opname
LEFT_RIGHT
| object
unqualified_id
LEFT_RIGHT
{
{
#if 0
#if 0
/* This is a future direction of this code, but because
/* This is a future direction of this code, but because
...
@@ -1650,27 +1532,27 @@ primary:
...
@@ -1650,27 +1532,27 @@ primary:
(LOOKUP_NORMAL|LOOKUP_AGGR));
(LOOKUP_NORMAL|LOOKUP_AGGR));
#endif
#endif
}
}
| object
id_scope identifier_or_opname
'(' nonnull_exprlist ')'
| object
qualified_id
'(' nonnull_exprlist ')'
{
{
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (
$2
)))
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (
OP0 ($2)
)))
{
{
warning ("signature name in scope resolution ignored");
warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$,
$3, $5
, NULL_TREE,
$$ = build_method_call ($$,
OP1 ($2), $4
, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR));
(LOOKUP_NORMAL|LOOKUP_AGGR));
}
}
else
else
$$ = build_scoped_method_call ($$,
$2, $3, $5
);
$$ = build_scoped_method_call ($$,
OP0 ($2), OP1 ($2), $4
);
}
}
| object
id_scope identifier_or_opname
LEFT_RIGHT
| object
qualified_id
LEFT_RIGHT
{
{
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (
$2
)))
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (
OP0 ($2)
)))
{
{
warning ("signature name in scope resolution ignored");
warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$,
$3
, NULL_TREE, NULL_TREE,
$$ = build_method_call ($$,
OP1 ($2)
, NULL_TREE, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR));
(LOOKUP_NORMAL|LOOKUP_AGGR));
}
}
else
else
$$ = build_scoped_method_call ($$,
$2, $3
, NULL_TREE);
$$ = build_scoped_method_call ($$,
OP0 ($2), OP1 ($2)
, NULL_TREE);
}
}
/* p->int::~int() is valid -- 12.4 */
/* p->int::~int() is valid -- 12.4 */
| object '~' TYPESPEC LEFT_RIGHT
| object '~' TYPESPEC LEFT_RIGHT
...
@@ -1741,17 +1623,14 @@ new: NEW
...
@@ -1741,17 +1623,14 @@ new: NEW
.scope:
.scope:
/* empty */
/* empty */
{ $$ = 0; }
{ $$ = 0; }
|
SCOPE
|
global_scope
{ $$ = 1; }
{
got_scope = NULL_TREE;
$$ = 1; }
;
;
delete: DELETE
delete: DELETE
{ $$ = NULL_TREE; }
{ $$ = 0; }
| SCOPE delete
| global_scope delete
{ if ($2)
{ got_scope = NULL_TREE; $$ = 1; }
error ("extra `::' before `delete' ignored");
$$ = error_mark_node;
}
;
;
/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
...
@@ -1782,18 +1661,16 @@ object: primary '.'
...
@@ -1782,18 +1661,16 @@ object: primary '.'
;
;
decl:
decl:
typed_declspecs initdecls ';'
/* Normal case: make this fast. */
{
typespec declarator ';'
resume_momentary ($2);
{ tree d = get_decl_list ($1);
note_list_got_semicolon ($1);
int yes = suspend_momentary ();
}
d = start_decl ($2, d, 0, NULL_TREE);
| typespec initdecls ';'
finish_decl (d, NULL_TREE, NULL_TREE, 0);
{
resume_momentary (yes);
resume_momentary ($2);
if (IS_AGGR_TYPE_CODE (TREE_CODE ($1)))
if (IS_AGGR_TYPE_CODE (TREE_CODE ($1)))
note_got_semicolon ($1);
note_got_semicolon ($1);
}
}
/* Normal case: make this fast. */
| typed_declspecs declarator ';'
| typed_declspecs declarator ';'
{ tree d = $1;
{ tree d = $1;
int yes = suspend_momentary ();
int yes = suspend_momentary ();
...
@@ -1802,29 +1679,23 @@ decl:
...
@@ -1802,29 +1679,23 @@ decl:
resume_momentary (yes);
resume_momentary (yes);
note_list_got_semicolon ($1);
note_list_got_semicolon ($1);
}
}
| typespec declarator ';'
| typespec initdecls ';'
{ tree d = get_decl_list ($1);
{
int yes = suspend_momentary ();
resume_momentary ($2);
d = start_decl ($2, d, 0, NULL_TREE);
finish_decl (d, NULL_TREE, NULL_TREE, 0);
resume_momentary (yes);
if (IS_AGGR_TYPE_CODE (TREE_CODE ($1)))
if (IS_AGGR_TYPE_CODE (TREE_CODE ($1)))
note_got_semicolon ($1);
note_got_semicolon ($1);
}
}
| declmods notype_initdecls ';'
| typed_declspecs initdecls ';'
{ resume_momentary ((int) $<itype>2); }
{
/* Normal case: make this fast. */
resume_momentary ($2);
| declmods notype_declarator ';'
note_list_got_semicolon ($1);
{ tree d;
int yes = suspend_momentary ();
d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE);
finish_decl (d, NULL_TREE, NULL_TREE, 0);
resume_momentary (yes);
}
}
| declmods notype_initdecls ';'
{ resume_momentary ($2); }
| typed_declspecs ';'
| typed_declspecs ';'
{
{
shadow_tag ($
<ttype>$
);
shadow_tag ($
1
);
note_list_got_semicolon ($
<ttype>$
);
note_list_got_semicolon ($
1
);
}
}
| declmods ';'
| declmods ';'
{ warning ("empty declaration"); }
{ warning ("empty declaration"); }
...
@@ -1950,22 +1821,7 @@ reserved_typespecquals:
...
@@ -1950,22 +1821,7 @@ reserved_typespecquals:
typespec: structsp
typespec: structsp
| TYPESPEC %prec EMPTY
| TYPESPEC %prec EMPTY
| TYPENAME %prec EMPTY
| complete_type_name
| scoped_typename %prec EMPTY
| SCOPE TYPENAME %prec EMPTY
{ $$ = IDENTIFIER_GLOBAL_VALUE ($2);
if (!$$)
{
error ("undeclared variable `%s' (first use here)",
IDENTIFIER_POINTER ($2));
$$ = error_mark_node;
IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node;
}
else
{
$$ = TREE_TYPE($$);
}
}
| TYPEOF '(' expr ')'
| TYPEOF '(' expr ')'
{ $$ = TREE_TYPE ($3);
{ $$ = TREE_TYPE ($3);
if (pedantic)
if (pedantic)
...
@@ -2002,7 +1858,6 @@ typespec: structsp
...
@@ -2002,7 +1858,6 @@ typespec: structsp
$$ = error_mark_node;
$$ = error_mark_node;
}
}
}
}
| template_type %prec EMPTY
;
;
/* A typespec that is a reserved word, or a type qualifier. */
/* A typespec that is a reserved word, or a type qualifier. */
...
@@ -2022,6 +1877,11 @@ notype_initdecls:
...
@@ -2022,6 +1877,11 @@ notype_initdecls:
| notype_initdecls ',' initdcl
| notype_initdecls ',' initdcl
;
;
nomods_initdecls:
nomods_initdcl0
| nomods_initdecls ',' initdcl
;
maybeasm:
maybeasm:
/* empty */
/* empty */
{ $$ = NULL_TREE; }
{ $$ = NULL_TREE; }
...
@@ -2098,6 +1958,25 @@ notype_initdcl0:
...
@@ -2098,6 +1958,25 @@ notype_initdcl0:
finish_decl (d, NULL_TREE, $3, 0); }
finish_decl (d, NULL_TREE, $3, 0); }
;
;
nomods_initdcl0:
notype_declarator maybe_raises maybeasm maybe_attribute '='
{ current_declspecs = NULL_TREE;
$<itype>5 = suspend_momentary ();
$<ttype>$ = start_decl ($1, current_declspecs, 1, $2);
cplus_decl_attributes ($<ttype>$, $4); }
init
/* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_decl ($<ttype>6, $7, $3, 0);
$$ = $<itype>5; }
| notype_declarator maybe_raises maybeasm maybe_attribute
{ tree d;
current_declspecs = NULL_TREE;
$$ = suspend_momentary ();
d = start_decl ($1, current_declspecs, 0, $2);
cplus_decl_attributes (d, $4);
finish_decl (d, NULL_TREE, $3, 0); }
;
/* the * rules are dummies to accept the Apollo extended syntax
/* the * rules are dummies to accept the Apollo extended syntax
so that the header files compile. */
so that the header files compile. */
maybe_attribute:
maybe_attribute:
...
@@ -2223,6 +2102,8 @@ structsp:
...
@@ -2223,6 +2102,8 @@ structsp:
check_for_missing_semicolon ($$); }
check_for_missing_semicolon ($$); }
| ENUM identifier
| ENUM identifier
{ $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); }
{ $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); }
| ENUM complex_type_name
{ $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); }
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
| class_head left_curly opt.component_decl_list '}'
| class_head left_curly opt.component_decl_list '}'
...
@@ -2319,11 +2200,11 @@ aggr: AGGR
...
@@ -2319,11 +2200,11 @@ aggr: AGGR
named_class_head_sans_basetype:
named_class_head_sans_basetype:
aggr identifier
aggr identifier
{ aggr1: current_aggr = $$; $$ = $2; }
| aggr template_type_name %prec EMPTY
{ current_aggr = $$; $$ = $2; }
{ current_aggr = $$; $$ = $2; }
| aggr TYPENAME_COLON
| aggr complex_type_name
{ yyungetc (':', 1); goto aggr1; }
{ current_aggr = $$; $$ = $2; }
| aggr template_type %prec EMPTY
{ current_aggr = $$; $$ = $2; }
| aggr template_type_name '{'
| aggr template_type_name '{'
{ yyungetc ('{', 1);
{ yyungetc ('{', 1);
aggr2:
aggr2:
...
@@ -2415,10 +2296,6 @@ base_class:
...
@@ -2415,10 +2296,6 @@ base_class:
else
else
$$ = build_tree_list ((tree)access_default, $$);
$$ = build_tree_list ((tree)access_default, $$);
}
}
| scoped_base_class
{
goto do_base_class1;
}
| base_class_access_list base_class.1
| base_class_access_list base_class.1
{
{
tree type;
tree type;
...
@@ -2448,36 +2325,10 @@ base_class:
...
@@ -2448,36 +2325,10 @@ base_class:
else
else
$$ = build_tree_list ((tree) $$, $2);
$$ = build_tree_list ((tree) $$, $2);
}
}
| base_class_access_list scoped_base_class
{
goto do_base_class2;
}
;
;
scoped_base_class:
base_class.1 SCOPED_TYPENAME
{
/* Kludge!!! See rule "template_type" and the code
* dealing with "template_type_seen_before_scope" in
* yylex(). */
$$ = $2;
}
;
base_class.1:
base_class.1:
template_type_name tmpl.2 template_instantiation
complete_type_name
{
extern tree template_type_seen_before_scope;
tree id = $3 ? TYPE_IDENTIFIER ($3) : $1;
/* Check the rule template_type to get this... */
if (yychar == YYEMPTY)
yychar = YYLEX;
if (yychar == SCOPE) {
template_type_seen_before_scope = id;
yychar = YYLEX;
}
}
| identifier
| SIGOF '(' expr ')'
| SIGOF '(' expr ')'
{
{
if (current_aggr == signature_type_node)
if (current_aggr == signature_type_node)
...
@@ -2585,9 +2436,11 @@ left_curly: '{'
...
@@ -2585,9 +2436,11 @@ left_curly: '{'
}
}
pushclass ($<ttype>0, 0);
pushclass ($<ttype>0, 0);
TYPE_BEING_DEFINED ($<ttype>0) = 1;
TYPE_BEING_DEFINED ($<ttype>0) = 1;
#if 0
t = TYPE_IDENTIFIER ($<ttype>0);
t = TYPE_IDENTIFIER ($<ttype>0);
if (t && IDENTIFIER_TEMPLATE (t))
if (t && IDENTIFIER_TEMPLATE (t))
overload_template_name (t, 1);
overload_template_name (t, 1);
#endif
}
}
;
;
...
@@ -2642,81 +2495,58 @@ component_decl_list:
...
@@ -2642,81 +2495,58 @@ component_decl_list:
;
;
component_decl:
component_decl:
/* Do not add a "typed_declspecs declarator ';'" rule here for
component_decl_1 ';'
| component_decl_1 '}'
{ error ("missing ';' before right brace");
yyungetc ('}', 0); }
/* C++: handle constructors, destructors and inline functions */
/* note that INLINE is like a TYPESPEC */
| fn.def2 ':' /* base_init compstmt */
{ $$ = finish_method ($$); }
| fn.def2 '{' /* nodecls compstmt */
{ $$ = finish_method ($$); }
;
component_decl_1:
/* Do not add a "typed_declspecs declarator" rule here for
speed; we need to call grok_x_components for enums, so the
speed; we need to call grok_x_components for enums, so the
speedup would be insignificant. */
speedup would be insignificant. */
typed_declspecs components
';'
typed_declspecs components
{
{
$$ = grok_x_components ($$, $2);
$$ = grok_x_components ($$, $2);
end_exception_decls ();
end_exception_decls ();
}
}
/* These rules introduce a reduce/reduce conflict; in
| declmods notype_components
typedef int foo, bar;
class A {
foo (bar);
};
should "A::foo" be declared as a function or data member?
In other words, is "bar" an after_type_declarator or a parmlist? */
| typed_declspecs '(' parmlist ')' ';'
{ $$ = groktypefield ($$, $3); }
| typed_declspecs '(' parmlist ')' '}'
{ error ("missing ';' before right brace");
yyungetc ('}', 0);
$$ = groktypefield ($$, $3); }
| typed_declspecs LEFT_RIGHT ';'
{ $$ = groktypefield ($$, empty_parms ()); }
| typed_declspecs LEFT_RIGHT '}'
{ error ("missing ';' before right brace");
yyungetc ('}', 0);
$$ = groktypefield ($$, empty_parms ()); }
| declmods notype_components ';'
{
{
$$ = grok_x_components ($$, $2);
$$ = grok_x_components ($$, $2);
end_exception_decls ();
end_exception_decls ();
}
}
/* Normal case: make this fast. */
| notype_declarator maybe_raises maybeasm maybe_attribute
| declmods notype_declarator ';'
{ $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, $3);
{ $$ = grokfield ($<ttype>2, $<ttype>$,
cplus_decl_attributes ($$, $4); }
NULL_TREE, NULL_TREE, NULL_TREE); }
| ':' expr_no_commas
| declmods notype_components '}'
{ error ("missing ';' before right brace");
yyungetc ('}', 0);
$$ = grok_x_components ($$, $2);
end_exception_decls ();
}
| declmods '(' parmlist ')' ';'
{ $$ = groktypefield ($$, $3); }
| declmods '(' parmlist ')' '}'
{ error ("missing ';' before right brace");
yyungetc ('}', 0);
$$ = groktypefield ($$, $3); }
| declmods LEFT_RIGHT ';'
{ $$ = groktypefield ($$, empty_parms ()); }
| declmods LEFT_RIGHT '}'
{ error ("missing ';' before right brace");
yyungetc ('}', 0);
$$ = groktypefield ($$, empty_parms ()); }
| ':' expr_no_commas ';'
{ $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
{ $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
| ':' expr_no_commas '}'
{ error ("missing ';' before right brace");
yyungetc ('}', 0);
$$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
| error
| error
{ $$ = NULL_TREE; }
{ $$ = NULL_TREE; }
/* C++: handle constructors, destructors and inline functions */
/* These rules introduce a reduce/reduce conflict; in
/* note that INLINE is like a TYPESPEC */
typedef int foo, bar;
| fn.def2 ':' /* base_init compstmt */
class A {
{ $$ = finish_method ($$); }
foo (bar);
| fn.def2 '{' /* nodecls compstmt */
};
{ $$ = finish_method ($$); }
should "A::foo" be declared as a function or "A::bar" as a data
| notype_declarator maybe_raises ';'
member? In other words, is "bar" an after_type_declarator or a
{ $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); }
parmlist? */
| notype_declarator maybe_raises '}'
| typed_declspecs '(' parmlist ')' type_quals
{ error ("missing ';' before right brace");
{ $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
yyungetc ('}', 0);
$3, $5);
$$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); }
$$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE,
NULL_TREE); }
| typed_declspecs LEFT_RIGHT type_quals
{ $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
empty_parms (), $3);
$$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE,
NULL_TREE); }
;
;
/* The case of exactly one component is handled directly by component_decl. */
/* The case of exactly one component is handled directly by component_decl. */
...
@@ -2850,13 +2680,6 @@ new_type_id:
...
@@ -2850,13 +2680,6 @@ new_type_id:
{ $$ = build_decl_list ($$, NULL_TREE); }
{ $$ = build_decl_list ($$, NULL_TREE); }
;
;
/* ANSI abstract-declarator (8.1) */
absdcl:
absdcl1 %prec EMPTY
| START_DECLARATOR absdcl1 %prec EMPTY
{ $$ = $2; }
;
type_quals:
type_quals:
/* empty */ %prec EMPTY
/* empty */ %prec EMPTY
{ $$ = NULL_TREE; }
{ $$ = NULL_TREE; }
...
@@ -2883,32 +2706,31 @@ nonmomentary_expr:
...
@@ -2883,32 +2706,31 @@ nonmomentary_expr:
/* A declarator that is allowed only after an explicit typespec. */
/* A declarator that is allowed only after an explicit typespec. */
/* may all be followed by prec '.' */
/* may all be followed by prec '.' */
after_type_declarator:
after_type_declarator:
after_type_declarator1
'*' nonempty_type_quals after_type_declarator %prec UNARY
| START_DECLARATOR after_type_declarator1
{ $$ = $2; }
;
after_type_declarator1:
'*' nonempty_type_quals after_type_declarator1 %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
{ $$ = make_pointer_declarator ($2, $3); }
| '&' nonempty_type_quals after_type_declarator
1
%prec UNARY
| '&' nonempty_type_quals after_type_declarator %prec UNARY
{ $$ = make_reference_declarator ($2, $3); }
{ $$ = make_reference_declarator ($2, $3); }
| '*' after_type_declarator
1
%prec UNARY
| '*' after_type_declarator %prec UNARY
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
| '&' after_type_declarator
1
%prec UNARY
| '&' after_type_declarator %prec UNARY
{ $$ = make_reference_declarator (NULL_TREE, $2); }
{ $$ = make_reference_declarator (NULL_TREE, $2); }
| id_scope '*' type_quals after_type_declarator1
| ptr_to_mem type_quals after_type_declarator
{ tree arg = make_pointer_declarator ($3, $4);
{ tree arg = make_pointer_declarator ($2, $3);
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $1, arg);
$$ = build_push_scope ($$, arg);
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = arg;
else
$$ = build_parse_node (SCOPE_REF, $$, arg);
}
}
| direct_after_type_declarator
| direct_after_type_declarator
;
;
qualified_type_name:
type_name %prec EMPTY
| nested_type
;
nested_type:
nested_name_specifier type_name %prec EMPTY
{ $$ = $2; }
;
direct_after_type_declarator:
direct_after_type_declarator:
direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
...
@@ -2922,58 +2744,46 @@ direct_after_type_declarator:
...
@@ -2922,58 +2744,46 @@ direct_after_type_declarator:
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
| direct_after_type_declarator '[' ']'
| direct_after_type_declarator '[' ']'
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
| '(' after_type_declarator
1
')'
| '(' after_type_declarator ')'
{ $$ = $2; }
{ $$ = $2; }
| TYPENAME %prec EMPTY
| nested_name_specifier type_name %prec EMPTY
{ push_nested_class (TREE_TYPE ($$), 3);
$$ = build_parse_node (SCOPE_REF, $$, $2);
TREE_COMPLEXITY ($$) = current_class_depth; }
| type_name %prec EMPTY
;
;
/* A declarator allowed whether or not there has been
/* A declarator allowed whether or not there has been
an explicit typespec. These cannot redeclare a typedef-name. */
an explicit typespec. These cannot redeclare a typedef-name. */
notype_declarator:
notype_declarator:
notype_declarator1
'*' nonempty_type_quals notype_declarator %prec UNARY
| START_DECLARATOR notype_declarator1
{ $$ = $2; }
;
notype_declarator1:
'*' nonempty_type_quals notype_declarator1 %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
{ $$ = make_pointer_declarator ($2, $3); }
| '&' nonempty_type_quals notype_declarator
1
%prec UNARY
| '&' nonempty_type_quals notype_declarator %prec UNARY
{ $$ = make_reference_declarator ($2, $3); }
{ $$ = make_reference_declarator ($2, $3); }
| '*' notype_declarator
1
%prec UNARY
| '*' notype_declarator %prec UNARY
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
| '&' notype_declarator
1
%prec UNARY
| '&' notype_declarator %prec UNARY
{ $$ = make_reference_declarator (NULL_TREE, $2); }
{ $$ = make_reference_declarator (NULL_TREE, $2); }
| id_scope '*' type_quals notype_declarator1
| ptr_to_mem type_quals notype_declarator
{ tree arg = make_pointer_declarator ($3, $4);
{ tree arg = make_pointer_declarator ($2, $3);
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $1, arg);
$$ = build_push_scope ($$, arg);
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = arg;
else
$$ = build_parse_node (SCOPE_REF, $$, arg);
}
}
| direct_notype_declarator
| direct_notype_declarator
;
;
complex_notype_declarator
1
:
complex_notype_declarator:
'*' nonempty_type_quals notype_declarator
1
%prec UNARY
'*' nonempty_type_quals notype_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
{ $$ = make_pointer_declarator ($2, $3); }
| '&' nonempty_type_quals notype_declarator
1
%prec UNARY
| '&' nonempty_type_quals notype_declarator %prec UNARY
{ $$ = make_reference_declarator ($2, $3); }
{ $$ = make_reference_declarator ($2, $3); }
| '*' complex_notype_declarator
1
%prec UNARY
| '*' complex_notype_declarator %prec UNARY
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
| '&' complex_notype_declarator
1
%prec UNARY
| '&' complex_notype_declarator %prec UNARY
{ $$ = make_reference_declarator (NULL_TREE, $2); }
{ $$ = make_reference_declarator (NULL_TREE, $2); }
| id_scope '*' type_quals notype_declarator1
| ptr_to_mem type_quals notype_declarator
{ tree arg = make_pointer_declarator ($3, $4);
{ tree arg = make_pointer_declarator ($2, $3);
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $1, arg);
$$ = build_push_scope ($$, arg);
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = arg;
else
$$ = build_parse_node (SCOPE_REF, $$, arg);
}
}
| complex_direct_notype_declarator
| complex_direct_notype_declarator
;
;
...
@@ -2989,40 +2799,30 @@ complex_direct_notype_declarator:
...
@@ -2989,40 +2799,30 @@ complex_direct_notype_declarator:
{ $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
{ $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
| '(' expr_or_declarator ')'
| '(' expr_or_declarator ')'
{ $$ = finish_decl_parsing ($2); }
{ $$ = finish_decl_parsing ($2); }
| '(' complex_notype_declarator
1
')'
| '(' complex_notype_declarator ')'
{ $$ = $2; }
{ $$ = $2; }
| direct_notype_declarator '[' nonmomentary_expr ']'
| direct_notype_declarator '[' nonmomentary_expr ']'
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
| direct_notype_declarator '[' ']'
| direct_notype_declarator '[' ']'
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
;
/* C++ extensions. */
qualified_id:
| id_scope see_typename notype_unqualified_id
nested_name_specifier unqualified_id
{ see_typename ();
{ got_scope = NULL_TREE;
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $$, $2); }
$$ = build_push_scope ($$, $3);
;
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = $3;
else
$$ = build_parse_node (SCOPE_REF, $$, $3);
}
| id_scope see_typename TYPENAME
{ $$ = build_push_scope ($$, $3); }
| SCOPE see_typename direct_notype_declarator
{ $$ = build_parse_node (SCOPE_REF, NULL_TREE, $3); }
| template_type SCOPED_NAME
{ tree t;
extern int current_class_depth;
t = TREE_TYPE(TREE_OPERAND($2, 0));
notype_qualified_id:
if (t != current_class_type &&
nested_name_specifier notype_unqualified_id
TREE_CODE(t) != TEMPLATE_TYPE_PARM)
{ got_scope = NULL_TREE;
{
$$ = build_parse_node (SCOPE_REF, $$, $2); }
push_nested_class(t, 3);
;
TREE_COMPLEXITY ($2) = current_class_depth;
}
overqualified_id:
$$ = $2;
notype_qualified_id
}
| global_scope notype_qualified_id
{ $$ = $2; }
;
;
functional_cast:
functional_cast:
...
@@ -3034,61 +2834,60 @@ functional_cast:
...
@@ -3034,61 +2834,60 @@ functional_cast:
{ $$ = reparse_absdcl_as_expr ($$, $2); }
{ $$ = reparse_absdcl_as_expr ($$, $2); }
;
;
id_scope: typename_scope
type_name:
{ tree t;
TYPENAME
do_id_scope:
| template_type %prec EMPTY
;
t = resolve_scope_to_name (NULL_TREE, $$);
nested_name_specifier:
if (t == NULL_TREE)
nested_name_specifier_1
{
| nested_name_specifier nested_name_specifier_1
cp_error ("`%T' is not a valid scope", $$);
{ $$ = $2; }
$$ = error_mark_node;
;
}
else
/* Why the @#$%^& do type_name and notype_identifier need to be expanded
$$ = t;
inline here?!? (jason) */
}
nested_name_specifier_1:
TYPENAME SCOPE
{ got_scope = TREE_TYPE ($$); }
| template_type SCOPE
{ got_scope = TREE_TYPE ($$); }
/* These break 'const i;'
| IDENTIFIER SCOPE
| IDENTIFIER SCOPE
{ goto do_id_scope; }
| template_type SCOPE /* try_for_typename %prec EMPTY */
{
{
if ($$ == error_mark_node)
failed_scope:
/* leave it alone */;
cp_error ("`%D' is not an aggregate typedef",
else
lastiddecl ? lastiddecl : $$);
{
$$ = error_mark_node;
$$ = resolve_scope_to_name (NULL_TREE, TYPE_IDENTIFIER ($$));
if ($$ == NULL_TREE)
{
error ("undefined explicitly scoped type");
$$ = error_mark_node;
}
}
/* if ($3) popclass (1); */
}
}
| PTYPENAME SCOPE
{ goto failed_scope; } */
;
;
typename_scope:
complete_type_name:
TYPENAME SCOPE;
qualified_type_name
| global_scope qualified_type_name
{ $$ = $2; }
;
scoped_typename: SCOPED_TYPENAME
complex_type_name:
| template_type SCOPED_TYPENAME
nested_type
{
| global_scope qualified_type_name
/* Kludge!!! See rule "template_type" and the code
{ $$ = $2; }
* dealing with "template_type_seen_before_scope" in
;
* yylex(). */
$$ = $2;
ptr_to_mem:
}
nested_name_specifier '*'
/* | template_type SCOPE try_for_typename TYPENAME
{ got_scope = NULL_TREE; }
{
| global_scope nested_name_specifier '*'
if ($$ == error_mark_node)
{ $$ = $2; got_scope = NULL_TREE; }
;
;
else
{
/* All uses of explicit global scope must go through this nonterminal so
$$ = build_parse_node (SCOPE_REF,
that got_scope will be set before yylex is called to get the next token. */
TYPE_IDENTIFIER ($$),
global_scope:
$4);
SCOPE
}
{ got_scope = void_type_node; }
if ($3) popclass (1);
} */
;
;
/* ANSI new-declarator (5.3.4) */
/* ANSI new-declarator (5.3.4) */
...
@@ -3101,23 +2900,13 @@ new_declarator:
...
@@ -3101,23 +2900,13 @@ new_declarator:
{ $$ = make_reference_declarator ($2, $3); }
{ $$ = make_reference_declarator ($2, $3); }
| '&' type_quals %prec EMPTY
| '&' type_quals %prec EMPTY
{ $$ = make_reference_declarator ($2, NULL_TREE); }
{ $$ = make_reference_declarator ($2, NULL_TREE); }
| id_scope '*' type_quals %prec EMPTY
| ptr_to_mem type_quals %prec EMPTY
{ tree arg = make_pointer_declarator ($3, NULL_TREE);
{ tree arg = make_pointer_declarator ($2, NULL_TREE);
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $1, arg);
$$ = build_push_scope ($$, arg);
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = arg;
else
$$ = build_parse_node (SCOPE_REF, $$, arg);
}
}
| id_scope '*' type_quals new_declarator
| ptr_to_mem type_quals new_declarator
{ tree arg = make_pointer_declarator ($3, $4);
{ tree arg = make_pointer_declarator ($2, $3);
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $1, arg);
$$ = build_push_scope ($$, arg);
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = arg;
else
$$ = build_parse_node (SCOPE_REF, $$, arg);
}
}
| direct_new_declarator %prec EMPTY
| direct_new_declarator %prec EMPTY
;
;
...
@@ -3131,48 +2920,36 @@ direct_new_declarator:
...
@@ -3131,48 +2920,36 @@ direct_new_declarator:
;
;
/* ANSI abstract-declarator (8.1) */
/* ANSI abstract-declarator (8.1) */
absdcl
1
:
absdcl:
'*' nonempty_type_quals absdcl
1
'*' nonempty_type_quals absdcl
{ $$ = make_pointer_declarator ($2, $3); }
{ $$ = make_pointer_declarator ($2, $3); }
| '*' absdcl
1
| '*' absdcl
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
| '*' type_quals %prec EMPTY
| '*' type_quals %prec EMPTY
{ $$ = make_pointer_declarator ($2, NULL_TREE); }
{ $$ = make_pointer_declarator ($2, NULL_TREE); }
| '&' nonempty_type_quals absdcl
1
| '&' nonempty_type_quals absdcl
{ $$ = make_reference_declarator ($2, $3); }
{ $$ = make_reference_declarator ($2, $3); }
| '&' absdcl
1
| '&' absdcl
{ $$ = make_reference_declarator (NULL_TREE, $2); }
{ $$ = make_reference_declarator (NULL_TREE, $2); }
| '&' type_quals %prec EMPTY
| '&' type_quals %prec EMPTY
{ $$ = make_reference_declarator ($2, NULL_TREE); }
{ $$ = make_reference_declarator ($2, NULL_TREE); }
| id_scope '*' type_quals %prec EMPTY
| ptr_to_mem type_quals %prec EMPTY
{ tree arg = make_pointer_declarator ($3, NULL_TREE);
{ tree arg = make_pointer_declarator ($2, NULL_TREE);
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $1, arg);
$$ = build_push_scope ($$, arg);
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = arg;
else
$$ = build_parse_node (SCOPE_REF, $$, arg);
}
}
| id_scope '*' type_quals absdcl1
| ptr_to_mem type_quals absdcl
{ tree arg = make_pointer_declarator ($3, $4);
{ tree arg = make_pointer_declarator ($2, $3);
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $1, arg);
$$ = build_push_scope ($$, arg);
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = arg;
else
$$ = build_parse_node (SCOPE_REF, $$, arg);
}
}
| direct_abstract_declarator %prec EMPTY
| direct_abstract_declarator %prec EMPTY
;
;
/* ANSI direct-abstract-declarator (8.1) */
/* ANSI direct-abstract-declarator (8.1) */
direct_abstract_declarator:
direct_abstract_declarator:
'(' absdcl1 ')'
'(' absdcl ')'
{ see_typename ();
{ $$ = $2; }
$$ = $2; }
/* `(typedef)1' is `int'. */
/* `(typedef)1' is `int'. */
| PAREN_STAR_PAREN
| PAREN_STAR_PAREN
{ see_typename (); }
| direct_abstract_declarator '(' parmlist ')' type_quals %prec '.'
| direct_abstract_declarator '(' parmlist ')' type_quals %prec '.'
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
| direct_abstract_declarator LEFT_RIGHT type_quals %prec '.'
| direct_abstract_declarator LEFT_RIGHT type_quals %prec '.'
...
@@ -3813,11 +3590,6 @@ label_colon:
...
@@ -3813,11 +3590,6 @@ label_colon:
}
}
| PTYPENAME ':'
| PTYPENAME ':'
{ goto do_label; }
{ goto do_label; }
| TYPENAME_COLON
{ tree label = define_label (input_filename, lineno, $1);
if (label)
expand_label (label);
}
;
;
try_head: TRY '{' { cplus_expand_start_try (0); } .pushlevel
try_head: TRY '{' { cplus_expand_start_try (0); } .pushlevel
...
@@ -4160,23 +3932,17 @@ named_parm:
...
@@ -4160,23 +3932,17 @@ named_parm:
/* Here we expand typed_declspecs inline to avoid mis-parsing of
/* Here we expand typed_declspecs inline to avoid mis-parsing of
TYPESPEC IDENTIFIER. */
TYPESPEC IDENTIFIER. */
typed_declspecs1 declarator
typed_declspecs1 declarator
{ $$ = build_tree_list ($$, $2);
{ $$ = build_tree_list ($$, $2); }
see_typename (); }
| typed_typespecs declarator
| typed_typespecs declarator
{ $$ = build_tree_list ($$, $2);
{ $$ = build_tree_list ($$, $2); }
see_typename (); }
| typespec declarator
| typespec declarator
{ $$ = build_tree_list (get_decl_list ($$), $2);
{ $$ = build_tree_list (get_decl_list ($$), $2); }
see_typename (); }
| typed_declspecs1 absdcl
| typed_declspecs1 absdcl
{ $$ = build_tree_list ($$, $2);
{ $$ = build_tree_list ($$, $2); }
see_typename (); }
| typed_declspecs1 %prec EMPTY
| typed_declspecs1 %prec EMPTY
{ $$ = build_tree_list ($$, NULL_TREE);
{ $$ = build_tree_list ($$, NULL_TREE); }
see_typename (); }
| declmods notype_declarator
| declmods notype_declarator
{ $$ = build_tree_list ($$, $2);
{ $$ = build_tree_list ($$, $2); }
see_typename (); }
;
;
parm:
parm:
...
@@ -4235,13 +4001,10 @@ raise_identifier:
...
@@ -4235,13 +4001,10 @@ raise_identifier:
{ $$ = build_decl_list (NULL_TREE, $$); }
{ $$ = build_decl_list (NULL_TREE, $$); }
| TYPENAME
| TYPENAME
{ $$ = build_decl_list (NULL_TREE, $$); }
{ $$ = build_decl_list (NULL_TREE, $$); }
| SCOPE IDENTIFIER
| global_scope IDENTIFIER
{ $$ = build_decl_list (void_type_node, $2); }
{ $$ = build_decl_list (NULL_TREE, $2); }
| SCOPE TYPENAME
| global_scope TYPENAME
{ $$ = build_decl_list (void_type_node, $2); }
{ $$ = build_decl_list (NULL_TREE, $2); }
| id_scope IDENTIFIER
{ $$ = build_decl_list ($$, $2); }
| scoped_typename
;
;
ansi_raise_identifier:
ansi_raise_identifier:
...
@@ -4274,87 +4037,87 @@ conversion_declarator:
...
@@ -4274,87 +4037,87 @@ conversion_declarator:
{ $$ = make_pointer_declarator ($2, $3); }
{ $$ = make_pointer_declarator ($2, $3); }
| '&' type_quals conversion_declarator
| '&' type_quals conversion_declarator
{ $$ = make_reference_declarator ($2, $3); }
{ $$ = make_reference_declarator ($2, $3); }
| id_scope '*' type_quals conversion_declarator
| ptr_to_mem type_quals conversion_declarator
{ tree arg = make_pointer_declarator ($3, $4);
{ tree arg = make_pointer_declarator ($2, $3);
if (TREE_CODE ($$) != SCOPE_REF)
$$ = build_parse_node (SCOPE_REF, $1, arg);
$$ = build_push_scope ($$, arg);
else if (TREE_OPERAND ($$, 1) == NULL_TREE)
TREE_OPERAND ($$, 1) = arg;
else
$$ = build_parse_node (SCOPE_REF, $$, arg);
}
}
;
;
operator: OPERATOR
{ got_scope = NULL_TREE; }
;
operator_name:
operator_name:
OPERATOR
'*'
operator
'*'
{ $$ = ansi_opname[MULT_EXPR]; }
{ $$ = ansi_opname[MULT_EXPR]; }
|
OPERATOR
'/'
|
operator
'/'
{ $$ = ansi_opname[TRUNC_DIV_EXPR]; }
{ $$ = ansi_opname[TRUNC_DIV_EXPR]; }
|
OPERATOR
'%'
|
operator
'%'
{ $$ = ansi_opname[TRUNC_MOD_EXPR]; }
{ $$ = ansi_opname[TRUNC_MOD_EXPR]; }
|
OPERATOR
'+'
|
operator
'+'
{ $$ = ansi_opname[PLUS_EXPR]; }
{ $$ = ansi_opname[PLUS_EXPR]; }
|
OPERATOR
'-'
|
operator
'-'
{ $$ = ansi_opname[MINUS_EXPR]; }
{ $$ = ansi_opname[MINUS_EXPR]; }
|
OPERATOR
'&'
|
operator
'&'
{ $$ = ansi_opname[BIT_AND_EXPR]; }
{ $$ = ansi_opname[BIT_AND_EXPR]; }
|
OPERATOR
'|'
|
operator
'|'
{ $$ = ansi_opname[BIT_IOR_EXPR]; }
{ $$ = ansi_opname[BIT_IOR_EXPR]; }
|
OPERATOR
'^'
|
operator
'^'
{ $$ = ansi_opname[BIT_XOR_EXPR]; }
{ $$ = ansi_opname[BIT_XOR_EXPR]; }
|
OPERATOR
'~'
|
operator
'~'
{ $$ = ansi_opname[BIT_NOT_EXPR]; }
{ $$ = ansi_opname[BIT_NOT_EXPR]; }
|
OPERATOR
','
|
operator
','
{ $$ = ansi_opname[COMPOUND_EXPR]; }
{ $$ = ansi_opname[COMPOUND_EXPR]; }
|
OPERATOR
ARITHCOMPARE
|
operator
ARITHCOMPARE
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname[$2]; }
|
OPERATOR
'<'
|
operator
'<'
{ $$ = ansi_opname[LT_EXPR]; }
{ $$ = ansi_opname[LT_EXPR]; }
|
OPERATOR
'>'
|
operator
'>'
{ $$ = ansi_opname[GT_EXPR]; }
{ $$ = ansi_opname[GT_EXPR]; }
|
OPERATOR
EQCOMPARE
|
operator
EQCOMPARE
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname[$2]; }
|
OPERATOR
ASSIGN
|
operator
ASSIGN
{ $$ = ansi_assopname[$2]; }
{ $$ = ansi_assopname[$2]; }
|
OPERATOR
'='
|
operator
'='
{ $$ = ansi_opname [MODIFY_EXPR]; }
{ $$ = ansi_opname [MODIFY_EXPR]; }
|
OPERATOR
LSHIFT
|
operator
LSHIFT
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname[$2]; }
|
OPERATOR
RSHIFT
|
operator
RSHIFT
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname[$2]; }
|
OPERATOR
PLUSPLUS
|
operator
PLUSPLUS
{ $$ = ansi_opname[POSTINCREMENT_EXPR]; }
{ $$ = ansi_opname[POSTINCREMENT_EXPR]; }
|
OPERATOR
MINUSMINUS
|
operator
MINUSMINUS
{ $$ = ansi_opname[PREDECREMENT_EXPR]; }
{ $$ = ansi_opname[PREDECREMENT_EXPR]; }
|
OPERATOR
ANDAND
|
operator
ANDAND
{ $$ = ansi_opname[TRUTH_ANDIF_EXPR]; }
{ $$ = ansi_opname[TRUTH_ANDIF_EXPR]; }
|
OPERATOR
OROR
|
operator
OROR
{ $$ = ansi_opname[TRUTH_ORIF_EXPR]; }
{ $$ = ansi_opname[TRUTH_ORIF_EXPR]; }
|
OPERATOR
'!'
|
operator
'!'
{ $$ = ansi_opname[TRUTH_NOT_EXPR]; }
{ $$ = ansi_opname[TRUTH_NOT_EXPR]; }
|
OPERATOR
'?' ':'
|
operator
'?' ':'
{ $$ = ansi_opname[COND_EXPR]; }
{ $$ = ansi_opname[COND_EXPR]; }
|
OPERATOR
MIN_MAX
|
operator
MIN_MAX
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname[$2]; }
|
OPERATOR
POINTSAT %prec EMPTY
|
operator
POINTSAT %prec EMPTY
{ $$ = ansi_opname[COMPONENT_REF]; }
{ $$ = ansi_opname[COMPONENT_REF]; }
|
OPERATOR
POINTSAT_STAR %prec EMPTY
|
operator
POINTSAT_STAR %prec EMPTY
{ $$ = ansi_opname[MEMBER_REF]; }
{ $$ = ansi_opname[MEMBER_REF]; }
|
OPERATOR
LEFT_RIGHT
|
operator
LEFT_RIGHT
{ $$ = ansi_opname[CALL_EXPR]; }
{ $$ = ansi_opname[CALL_EXPR]; }
|
OPERATOR
'[' ']'
|
operator
'[' ']'
{ $$ = ansi_opname[ARRAY_REF]; }
{ $$ = ansi_opname[ARRAY_REF]; }
|
OPERATOR NEW
|
operator NEW %prec EMPTY
{ $$ = ansi_opname[NEW_EXPR]; }
{ $$ = ansi_opname[NEW_EXPR]; }
|
OPERATOR DELETE
|
operator DELETE %prec EMPTY
{ $$ = ansi_opname[DELETE_EXPR]; }
{ $$ = ansi_opname[DELETE_EXPR]; }
/* | OPERATOR
NEW '[' ']'
| operator
NEW '[' ']'
{ $$ = ansi_opname[VEC_NEW_EXPR]; }
{ $$ = ansi_opname[VEC_NEW_EXPR]; }
| OPERATOR DELETE '[' ']'
| operator DELETE '[' ']'
{ $$ = ansi_opname[VEC_DELETE_EXPR]; } */
{ $$ = ansi_opname[VEC_DELETE_EXPR]; }
| OPERATOR typed_typespecs conversion_declarator
/* Should we be pushing into class scope to parse this? */
| operator typed_typespecs conversion_declarator
{ $$ = grokoptypename ($2, $3); }
{ $$ = grokoptypename ($2, $3); }
|
OPERATOR
error
|
operator
error
{ $$ = ansi_opname[ERROR_MARK]; }
{ $$ = ansi_opname[ERROR_MARK]; }
;
;
...
...
gcc/cp/pt.c
View file @
a28e3c7f
...
@@ -1690,6 +1690,7 @@ instantiate_template (tmpl, targ_ptr)
...
@@ -1690,6 +1690,7 @@ instantiate_template (tmpl, targ_ptr)
return
fndecl
;
return
fndecl
;
}
}
/* classlevel should now never be true. jason 4/12/94 */
void
void
undo_template_name_overload
(
id
,
classlevel
)
undo_template_name_overload
(
id
,
classlevel
)
tree
id
;
tree
id
;
...
@@ -1711,6 +1712,7 @@ undo_template_name_overload (id, classlevel)
...
@@ -1711,6 +1712,7 @@ undo_template_name_overload (id, classlevel)
#endif
#endif
}
}
/* classlevel should now never be true. jason 4/12/94 */
void
void
overload_template_name
(
id
,
classlevel
)
overload_template_name
(
id
,
classlevel
)
tree
id
;
tree
id
;
...
@@ -1731,12 +1733,9 @@ overload_template_name (id, classlevel)
...
@@ -1731,12 +1733,9 @@ overload_template_name (id, classlevel)
#if 1
/* XXX */
#if 1
/* XXX */
/* This was a botch... names of templates do not get their own private
/* This was a botch... names of templates do not get their own private
scopes. Rather, the names of generated template instances should
scopes. Rather, they should go into the binding level already created
just get pushed into whatever scope we happen to be in at the moment.
by push_template_decls. Except that there isn't one of those for
This will typically (but not always) be the global scope. (Maybe
specializations. */
what we really want to do here is a `push_to_toplevel' and then stay
there while we are generating the instance; popping back out to the
current scope when we are done generating the instance.) */
if
(
!
classlevel
)
if
(
!
classlevel
)
{
{
pushlevel
(
1
);
pushlevel
(
1
);
...
@@ -1765,20 +1764,13 @@ overload_template_name (id, classlevel)
...
@@ -1765,20 +1764,13 @@ overload_template_name (id, classlevel)
if
(
classlevel
)
if
(
classlevel
)
pushdecl_class_level
(
decl
);
pushdecl_class_level
(
decl
);
else
else
#if 0 /* not yet, should get fixed properly later */
pushdecl
(
decl
);
pushdecl
(
decl
);
pushlevel (1);
#else
{
pushdecl
(
decl
);
/* @@ Is this necessary now? */
IDENTIFIER_LOCAL_VALUE
(
template
)
=
decl
;
}
#endif
#if 0 /* This seems bogus to me; if it isn't, explain why. (jason) */
/* Fake this for now, just to make dwarfout.c happy. It will have to
/* Fake this for now, just to make dwarfout.c happy. It will have to
be done in a proper way later on. */
be done in a proper way later on. */
DECL_CONTEXT (decl) = t;
DECL_CONTEXT (decl) = t;
#endif
}
}
/* NAME is the IDENTIFIER value of a PRE_PARSED_CLASS_DECL. */
/* NAME is the IDENTIFIER value of a PRE_PARSED_CLASS_DECL. */
...
@@ -2028,6 +2020,22 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
...
@@ -2028,6 +2020,22 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return
0
;
return
0
;
else
if
(
targs
[
idx
])
else
if
(
targs
[
idx
])
{
{
tree
t
=
targs
[
idx
];
if
(
TREE_CODE
(
t
)
==
TREE_CODE
(
arg
))
switch
(
TREE_CODE
(
arg
))
{
case
INTEGER_CST
:
if
(
tree_int_cst_equal
(
t
,
arg
))
return
0
;
break
;
case
REAL_CST
:
if
(
REAL_VALUES_EQUAL
(
TREE_REAL_CST
(
t
),
TREE_REAL_CST
(
arg
)))
return
0
;
break
;
/* STRING_CST values are not valid template const parms. */
default:
;
}
my_friendly_abort
(
87
);
my_friendly_abort
(
87
);
return
1
;
return
1
;
}
}
...
@@ -2306,3 +2314,18 @@ do_function_instantiation (declspecs, declarator)
...
@@ -2306,3 +2314,18 @@ do_function_instantiation (declspecs, declarator)
if
(
!
result
)
if
(
!
result
)
cp_error
(
"no matching template for `%D' found"
,
decl
);
cp_error
(
"no matching template for `%D' found"
,
decl
);
}
}
tree
create_nested_upt
(
scope
,
name
)
tree
scope
,
name
;
{
tree
t
=
make_lang_type
(
UNINSTANTIATED_P_TYPE
);
tree
d
=
build_lang_decl
(
TYPE_DECL
,
name
,
t
);
TYPE_NAME
(
t
)
=
d
;
TYPE_VALUES
(
t
)
=
TYPE_VALUES
(
scope
);
TYPE_CONTEXT
(
t
)
=
scope
;
pushdecl
(
d
);
return
d
;
}
gcc/cp/ptree.c
View file @
a28e3c7f
...
@@ -108,10 +108,14 @@ print_lang_type (file, node, indent)
...
@@ -108,10 +108,14 @@ print_lang_type (file, node, indent)
else
else
fputs
(
" X(X&)"
,
file
);
fputs
(
" X(X&)"
,
file
);
}
}
if
(
TREE_GETS_NEW
(
node
))
if
(
TYPE_GETS_NEW
(
node
)
&
1
)
fputs
(
" gets-new"
,
file
);
fputs
(
" new"
,
file
);
if
(
TREE_GETS_DELETE
(
node
))
if
(
TYPE_GETS_NEW
(
node
)
&
2
)
fputs
(
" gets-delete"
,
file
);
fputs
(
" new[]"
,
file
);
if
(
TYPE_GETS_DELETE
(
node
)
&
1
)
fputs
(
" delete"
,
file
);
if
(
TYPE_GETS_DELETE
(
node
)
&
2
)
fputs
(
" delete[]"
,
file
);
if
(
TYPE_HAS_ASSIGNMENT
(
node
))
if
(
TYPE_HAS_ASSIGNMENT
(
node
))
fputs
(
" has="
,
file
);
fputs
(
" has="
,
file
);
if
(
TYPE_HAS_ASSIGN_REF
(
node
))
if
(
TYPE_HAS_ASSIGN_REF
(
node
))
...
...
gcc/cp/search.c
View file @
a28e3c7f
...
@@ -1079,16 +1079,16 @@ lookup_field (xbasetype, name, protect, want_type)
...
@@ -1079,16 +1079,16 @@ lookup_field (xbasetype, name, protect, want_type)
if
(
TREE_CODE
(
rval
)
==
CONST_DECL
)
if
(
TREE_CODE
(
rval
)
==
CONST_DECL
)
{
{
if
(
this_v
==
access_private
)
if
(
this_v
==
access_private
)
errstr
=
"enum `%
s' is a private value of class `%s
'"
;
errstr
=
"enum `%
D' is a private value of class `%T
'"
;
else
if
(
this_v
==
access_protected
)
else
if
(
this_v
==
access_protected
)
errstr
=
"enum `%
s' is a protected value of class `%s
'"
;
errstr
=
"enum `%
D' is a protected value of class `%T
'"
;
}
}
else
else
{
{
if
(
this_v
==
access_private
)
if
(
this_v
==
access_private
)
errstr
=
"member `%
s' is a private member of class `%s
'"
;
errstr
=
"member `%
D' is a private member of class `%T
'"
;
else
if
(
this_v
==
access_protected
)
else
if
(
this_v
==
access_protected
)
errstr
=
"member `%
s' is a protected member of class `%s
'"
;
errstr
=
"member `%
D' is a protected member of class `%T
'"
;
}
}
}
}
...
@@ -1214,7 +1214,7 @@ lookup_field (xbasetype, name, protect, want_type)
...
@@ -1214,7 +1214,7 @@ lookup_field (xbasetype, name, protect, want_type)
else
else
{
{
/* This is ambiguous. */
/* This is ambiguous. */
errstr
=
"request for member `%
s
' is ambiguous"
;
errstr
=
"request for member `%
D
' is ambiguous"
;
protect
=
2
;
protect
=
2
;
break
;
break
;
}
}
...
@@ -1250,7 +1250,7 @@ lookup_field (xbasetype, name, protect, want_type)
...
@@ -1250,7 +1250,7 @@ lookup_field (xbasetype, name, protect, want_type)
new_v
=
compute_access
(
TREE_VALUE
(
TREE_CHAIN
(
*
tp
)),
rval
);
new_v
=
compute_access
(
TREE_VALUE
(
TREE_CHAIN
(
*
tp
)),
rval
);
if
(
this_v
!=
access_default
&&
new_v
!=
this_v
)
if
(
this_v
!=
access_default
&&
new_v
!=
this_v
)
{
{
errstr
=
"conflicting access to member `%
s
'"
;
errstr
=
"conflicting access to member `%
D
'"
;
this_v
=
access_default
;
this_v
=
access_default
;
}
}
own_access
=
new_v
;
own_access
=
new_v
;
...
@@ -1272,17 +1272,17 @@ lookup_field (xbasetype, name, protect, want_type)
...
@@ -1272,17 +1272,17 @@ lookup_field (xbasetype, name, protect, want_type)
if
(
errstr
==
0
)
if
(
errstr
==
0
)
{
{
if
(
own_access
==
access_private
)
if
(
own_access
==
access_private
)
errstr
=
"member `%
s
' declared private"
;
errstr
=
"member `%
D
' declared private"
;
else
if
(
own_access
==
access_protected
)
else
if
(
own_access
==
access_protected
)
errstr
=
"member `%
s
' declared protected"
;
errstr
=
"member `%
D
' declared protected"
;
else
if
(
this_v
==
access_private
)
else
if
(
this_v
==
access_private
)
errstr
=
TREE_PRIVATE
(
rval
)
errstr
=
TREE_PRIVATE
(
rval
)
?
"member `%
s
' is private"
?
"member `%
D
' is private"
:
"member `%
s
' is from private base class"
;
:
"member `%
D
' is from private base class"
;
else
if
(
this_v
==
access_protected
)
else
if
(
this_v
==
access_protected
)
errstr
=
TREE_PROTECTED
(
rval
)
errstr
=
TREE_PROTECTED
(
rval
)
?
"member `%
s
' is protected"
?
"member `%
D
' is protected"
:
"member `%
s
' is from protected base class"
;
:
"member `%
D
' is from protected base class"
;
}
}
if
(
entry
)
if
(
entry
)
...
@@ -1302,17 +1302,7 @@ lookup_field (xbasetype, name, protect, want_type)
...
@@ -1302,17 +1302,7 @@ lookup_field (xbasetype, name, protect, want_type)
if
(
errstr
&&
protect
)
if
(
errstr
&&
protect
)
{
{
char
*
p
=
IDENTIFIER_POINTER
(
name
),
*
q
=
NULL
;
cp_error
(
errstr
,
name
,
type
);
if
(
IDENTIFIER_OPNAME_P
(
name
))
{
q
=
operator_name_string
(
name
);
p
=
(
char
*
)
xmalloc
(
9
+
strlen
(
q
)
+
1
);
sprintf
(
p
,
"operator %s"
,
q
);
}
error
(
errstr
,
p
,
TYPE_NAME_STRING
(
type
));
if
(
q
)
free
(
p
);
rval
=
error_mark_node
;
rval
=
error_mark_node
;
}
}
return
rval
;
return
rval
;
...
@@ -3031,15 +3021,15 @@ push_class_decls (type)
...
@@ -3031,15 +3021,15 @@ push_class_decls (type)
search_stack
=
push_search_level
(
search_stack
,
&
search_obstack
);
search_stack
=
push_search_level
(
search_stack
,
&
search_obstack
);
id
=
TYPE_IDENTIFIER
(
type
);
id
=
TYPE_IDENTIFIER
(
type
);
#if 0
if (IDENTIFIER_TEMPLATE (id) != 0)
if (IDENTIFIER_TEMPLATE (id) != 0)
{
{
#if 0
tree tmpl = IDENTIFIER_TEMPLATE (id);
tree tmpl = IDENTIFIER_TEMPLATE (id);
push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
TREE_VALUE (tmpl), 1);
TREE_VALUE (tmpl), 1);
#endif
overload_template_name (id, 1);
overload_template_name (id, 1);
}
}
#endif
/* Push class fields into CLASS_VALUE scope, and mark. */
/* Push class fields into CLASS_VALUE scope, and mark. */
dfs_walk
(
TYPE_BINFO
(
type
),
dfs_pushdecls
,
unmarkedp
);
dfs_walk
(
TYPE_BINFO
(
type
),
dfs_pushdecls
,
unmarkedp
);
...
@@ -3227,3 +3217,27 @@ reinit_search_statistics ()
...
@@ -3227,3 +3217,27 @@ reinit_search_statistics ()
n_outer_fields_searched
=
0
;
n_outer_fields_searched
=
0
;
n_contexts_saved
=
0
;
n_contexts_saved
=
0
;
}
}
tree
lookup_nested_tag
(
type
,
name
)
tree
type
,
name
;
{
tree
tags
=
CLASSTYPE_TAGS
(
type
);
for
(;
tags
;
tags
=
TREE_CHAIN
(
tags
))
{
/* The TREE_PURPOSE of an enum tag (which becomes a member of the
enclosing class) is set to the name for the enum type. So, if
name is `bar', and we strike `baz' for `enum bar { baz }', then
this test will be true. */
if
(
TREE_PURPOSE
(
tags
)
==
name
)
break
;
}
if
(
tags
)
return
TYPE_NAME
(
TREE_VALUE
(
tags
));
if
(
TYPE_CONTEXT
(
type
))
return
lookup_nested_tag
(
TYPE_CONTEXT
(
type
),
name
);
return
NULL_TREE
;
}
gcc/cp/spew.c
View file @
a28e3c7f
...
@@ -45,12 +45,6 @@ struct token {
...
@@ -45,12 +45,6 @@ struct token {
};
};
static
int
do_aggr
();
static
int
do_aggr
();
static
struct
token
frob_identifier
();
static
tree
hack_more_ids
();
#if 0
static struct token hack_scope ();
static tree hack_ptype ();
#endif
/* From lex.c: */
/* From lex.c: */
/* the declaration found for the last IDENTIFIER token read in.
/* the declaration found for the last IDENTIFIER token read in.
...
@@ -72,51 +66,10 @@ static unsigned int yylex_ctr = 0;
...
@@ -72,51 +66,10 @@ static unsigned int yylex_ctr = 0;
static
int
debug_yychar
();
static
int
debug_yychar
();
#endif
#endif
#if 0 /* Used by arbitrate_lookup */
static char follows_typename[END_OF_SAVED_INPUT+1];
static char follows_identifier[END_OF_SAVED_INPUT+1];
#endif
/* This is a hack!!! TEMPLATE_TYPE_SEEN_BEFORE_SCOPE consists of the name
* of the last template_type parsed in parse.y if it is followed by a
* scope operator. It will be reset inside the next invocation of yylex().
* This is used for recognizing nested types inside templates.
* - niklas@appli.se */
tree
template_type_seen_before_scope
;
/* Initialize token_obstack. Called once, from init_lex. */
/* Initialize token_obstack. Called once, from init_lex. */
void
void
init_spew
()
init_spew
()
{
{
#if 0 /* Used by arbitrate_lookup */
static char *chars_following_identifier = ".+-|/%^!?:";
short *ps;
static short toks_follow_ids[] =
{ ASSIGN, RANGE, OROR, ANDAND, MIN_MAX, EQCOMPARE,
ARITHCOMPARE, LSHIFT, RSHIFT, UNARY, PLUSPLUS, MINUSMINUS, POINTSAT,
POINTSAT_STAR, DOT_STAR, CONSTANT, STRING, SIZEOF, ENUM, IF,
ELSE, WHILE, DO, FOR, SWITCH, CASE, DEFAULT, BREAK, CONTINUE,
RETURN, GOTO, ASM_KEYWORD, GCC_ASM_KEYWORD, TYPEOF, ALIGNOF, HEADOF,
CLASSOF, SIGOF, ATTRIBUTE, AGGR, VISSPEC, DELETE, RAISE, RERAISE, TRY,
EXCEPT, CATCH, THROW, ANSI_TRY, ANSI_THROW, DYNAMIC_CAST, TYPEID,
EXTERN_LANG_STRING, ALL, END_OF_SAVED_INPUT, -1 };
static short toks_follow_types[] =
{ IDENTIFIER, TYPENAME, SCOPED_TYPENAME, SCOPED_NAME, SCSPEC,
TYPESPEC, TYPE_QUAL,
ELLIPSIS, THIS, OPERATOR, TEMPLATE, SCOPE, START_DECLARATOR,
TYPENAME_COLON, PAREN_STAR_PAREN, TYPENAME_ELLIPSIS, PTYPENAME,
PRE_PARSED_FUNCTION_DECL, PRE_PARSED_CLASS_DECL, -1 };
/* Initialize the arrays saying what tokens are definitely
(or possibly) valid following typenames and identifiers. */
while (*chars_following_identifier)
follows_identifier[*chars_following_identifier++] = 1;
for (ps = toks_follow_ids; *ps != -1; ps++)
follows_identifier[*ps] = 1;
for (ps = toks_follow_types; *ps != -1; ps++)
follows_typename[*ps] = 1;
#endif
gcc_obstack_init
(
&
token_obstack
);
gcc_obstack_init
(
&
token_obstack
);
}
}
...
@@ -181,7 +134,8 @@ consume_token()
...
@@ -181,7 +134,8 @@ consume_token()
: first_token++)
: first_token++)
#endif
#endif
/* Pull in enough tokens from real_yylex that the queue is N long. */
/* Pull in enough tokens from real_yylex that the queue is N long beyond
the current token. */
static
void
static
void
scan_tokens
(
n
)
scan_tokens
(
n
)
...
@@ -278,13 +232,13 @@ probe_obstack (h, obj, nlevels)
...
@@ -278,13 +232,13 @@ probe_obstack (h, obj, nlevels)
}
}
/* from lex.c: */
/* from lex.c: */
/* Value is 1 if we should try to make the next identifier look like a
/* Value is 1 (or 2) if we should try to make the next identifier look like
typename (when it may be a local variable or a class variable).
a typename (when it may be a local variable or a class variable).
Value is 0 if we treat this name in a default fashion.
Value is 0 if we treat this name in a default fashion. */
Value is -1 if we must not see a type name. */
extern
int
looking_for_typename
;
extern
int
looking_for_typename
;
extern
struct
obstack
*
current_obstack
,
*
saveable_obstack
;
extern
struct
obstack
*
current_obstack
,
*
saveable_obstack
;
tree
got_scope
;
int
int
yylex
()
yylex
()
...
@@ -300,36 +254,6 @@ yylex()
...
@@ -300,36 +254,6 @@ yylex()
fprintf
(
stderr
,
"
\t\t
## %d ##"
,
yylex_ctr
);
fprintf
(
stderr
,
"
\t\t
## %d ##"
,
yylex_ctr
);
}
}
#endif
#endif
/* This is a kludge for recognizing nested types in templates */
if
(
template_type_seen_before_scope
)
{
shift_tokens
(
2
);
/* Sync in hack_more_ids (yes, it's ugly) */
nth_token
(
1
)
->
yychar
=
SCOPE
;
yylval
.
ttype
=
hack_more_ids
(
0
,
template_type_seen_before_scope
);
template_type_seen_before_scope
=
0
;
if
(
!
yylval
.
ttype
)
{
/* Sync back again, leaving SCOPE on the token stream, because we
* failed to substitute the original SCOPE token with a
* SCOPED_TYPENAME. See rule "template_type" in parse.y */
consume_token
();
}
else
{
tree
t
=
TREE_TYPE
(
yylval
.
ttype
);
if
(
TREE_CODE
(
yylval
.
ttype
)
==
SCOPE_REF
&&
t
&&
TREE_CODE
(
t
)
==
UNINSTANTIATED_P_TYPE
)
yychar
=
SCOPED_NAME
;
else
yychar
=
SCOPED_TYPENAME
;
#ifdef SPEW_DEBUG
if
(
spew_debug
)
debug_yychar
(
yychar
);
#endif
return
yychar
;
}
}
/* if we've got tokens, send them */
/* if we've got tokens, send them */
if
(
num_tokens
())
if
(
num_tokens
())
...
@@ -370,7 +294,13 @@ yylex()
...
@@ -370,7 +294,13 @@ yylex()
goto
retry
;
goto
retry
;
case
IDENTIFIER
:
case
IDENTIFIER
:
scan_tokens
(
1
);
if
(
nth_token
(
1
)
->
yychar
==
SCOPE
)
/* Don't interfere with the setting from an 'aggr' prefix. */
looking_for_typename
++
;
trrr
=
lookup_name
(
tmp_token
.
yylval
.
ttype
,
-
2
);
trrr
=
lookup_name
(
tmp_token
.
yylval
.
ttype
,
-
2
);
if
(
trrr
)
if
(
trrr
)
{
{
tmp_token
.
yychar
=
identifier_type
(
trrr
);
tmp_token
.
yychar
=
identifier_type
(
trrr
);
...
@@ -378,28 +308,17 @@ yylex()
...
@@ -378,28 +308,17 @@ yylex()
{
{
case
TYPENAME
:
case
TYPENAME
:
lastiddecl
=
identifier_typedecl_value
(
tmp_token
.
yylval
.
ttype
);
lastiddecl
=
identifier_typedecl_value
(
tmp_token
.
yylval
.
ttype
);
if
(
lastiddecl
==
NULL_TREE
)
if
(
lastiddecl
!=
trrr
)
lastiddecl
=
trrr
;
{
lastiddecl
=
trrr
;
tmp_token
.
yylval
.
ttype
=
DECL_NESTED_TYPENAME
(
trrr
);
}
break
;
break
;
case
IDENTIFIER
:
case
IDENTIFIER
:
lastiddecl
=
trrr
;
lastiddecl
=
trrr
;
break
;
break
;
case
PTYPENAME
:
case
PTYPENAME
:
/* This is for cases like
lastiddecl
=
NULL_TREE
;
template<class A> X<A>::operator[] ...
since "X" is (presumably) a PTYPENAME; we might want to
avoid seeing the entire thing as a type name, but X<A>
must be one.
It might not work right if the thing after the ::
can be a typename nested in X<A>, but I don't think the
PT code would be up to dealing with that anyways. --KR */
if
(
looking_for_typename
==
-
1
)
{
scan_tokens
(
2
);
if
(
nth_token
(
1
)
->
yychar
==
'<'
)
looking_for_typename
=
0
;
}
break
;
break
;
default:
default:
my_friendly_abort
(
101
);
my_friendly_abort
(
101
);
...
@@ -410,120 +329,20 @@ yylex()
...
@@ -410,120 +329,20 @@ yylex()
/* and fall through to... */
/* and fall through to... */
case
TYPENAME
:
case
TYPENAME
:
case
PTYPENAME
:
case
PTYPENAME
:
/* if (new_token) add_token (&tmp_token); */
consume_token
();
*
nth_token
(
0
)
=
tmp_token
;
if
(
looking_for_typename
>
0
)
tmp_token
=
frob_identifier
();
looking_for_typename
--
;
if
(
looking_for_typename
<
0
)
{
tmp_token
.
yychar
=
IDENTIFIER
;
lastiddecl
=
0
;
looking_for_typename
=
0
;
}
else
if
(
lastiddecl
&&
TREE_CODE
(
lastiddecl
)
==
TYPE_DECL
)
{
scan_tokens
(
2
);
if
(
nth_token
(
0
)
->
yychar
==
IDENTIFIER
&&
nth_token
(
1
)
->
yychar
!=
SCOPE
)
looking_for_typename
=
-
1
;
else
looking_for_typename
=
0
;
goto
finish_typename_processing
;
}
else
looking_for_typename
=
0
;
break
;
break
;
case
SCSPEC
:
case
SCSPEC
:
/* do_aggr needs to check if the previous token was RID_FRIEND,
/* do_aggr needs to check if the previous token was RID_FRIEND,
so just increment first_token instead of calling consume_token. */
so just increment first_token instead of calling consume_token. */
first_token
++
;
first_token
++
;
goto
finish_typename_processing
;
break
;
case
TYPESPEC
:
case
TYPESPEC
:
consume_token
();
consume_token
();
finish_typename_processing:
#if 0
/* Now see if we should insert a START_DECLARATOR token.
Here are the cases caught:
typespec ( * ID ) ( // ptr to function
typespec ( & ID ) ( // ref to function
typespec ( * ID ) [ // array of pointers
typespec ( & ID ) [ // array of references
This is a terrible kludge. */
scan_tokens (2);
if (nth_token (0)->yychar == '('
&& (nth_token (1)->yychar == '*'
|| nth_token (1)->yychar == '&'))
{
scan_tokens (5);
if (nth_token (3)->yychar == ')'
&& (nth_token (4)->yychar == '('
|| nth_token (4)->yychar == '['
|| nth_token (4)->yychar == LEFT_RIGHT)
&& (nth_token (2)->yychar == IDENTIFIER
|| nth_token (2)->yychar == TYPENAME))
{
shift_tokens (1);
nth_token (0)->yychar = START_DECLARATOR;
}
}
/* Extend to handle:
typespec (ID::* qf)( // ptr to member function
typespec (ID::* qf)[ // array of ptr to member functions
*/
if (nth_token (0)->yychar == '('
&& (nth_token (1)->yychar == IDENTIFIER
|| nth_token (1)->yychar == TYPENAME))
{
scan_tokens (7);
if (nth_token (2)->yychar == SCOPE
&& nth_token (3)->yychar == '*'
&& (nth_token (4)->yychar == IDENTIFIER
|| nth_token (4)->yychar == TYPENAME)
&& nth_token (5)->yychar == ')'
&& (nth_token (6)->yychar == '('
|| nth_token (6)->yychar == '['
|| nth_token (6)->yychar == LEFT_RIGHT))
{
shift_tokens (1);
nth_token (0)->yychar = START_DECLARATOR;
}
}
#endif
break
;
break
;
#if 0
case '(':
/* Handle casts. We are looking for one of:
`( TYPENAME' followed by `)', or
`( TYPENAME *' followed by one of `[,*,&,)', or
`( TYPENAME &' followed by one of `[,*,&,)', or
`( TYPENAME [' followed by `]'. We are punting
generality on scanning casts to array types. */
scan_tokens (4);
if (nth_token (1)->yychar == IDENTIFIER)
{
tree type = identifier_typedecl_value (nth_token (1)->yylval.ttype);
if (type)
switch (nth_token (2)->yychar)
{
default:
break;
}
}
break;
case SCOPE:
/* if (new_token) add_token (&tmp_token); */
*nth_token(0) = tmp_token;
tmp_token = hack_scope ();
break;
#endif
case
AGGR
:
case
AGGR
:
*
nth_token
(
0
)
=
tmp_token
;
*
nth_token
(
0
)
=
tmp_token
;
do_aggr
();
do_aggr
();
...
@@ -533,36 +352,7 @@ yylex()
...
@@ -533,36 +352,7 @@ yylex()
looking_for_typename
=
1
;
looking_for_typename
=
1
;
/* fall through... */
/* fall through... */
default:
default:
#ifdef SPEW_DEBUG
if
(
spew_debug
)
debug_yychar
(
tmp_token
.
yychar
);
#endif
consume_token
();
consume_token
();
yylval
=
tmp_token
.
yylval
;
yychar
=
tmp_token
.
yychar
;
end_of_file
=
tmp_token
.
end_of_file
;
return
tmp_token
.
yychar
;
}
if
(
tmp_token
.
yychar
==
SCOPED_TYPENAME
)
{
#if 0
tree t2 = resolve_scope_to_name (NULL_TREE, tmp_token.yylval.ttype);
if (t2 != NULL_TREE)
{
tmp_token.yylval.ttype = t2;
tmp_token.yychar = TYPENAME;
}
else
{
/* unwind? */
}
}
else
{
/* couldn't get here, as is... */
#endif
tmp_token
.
yychar
=
TYPENAME
;
}
}
yylval
=
tmp_token
.
yylval
;
yylval
=
tmp_token
.
yylval
;
...
@@ -572,7 +362,6 @@ yylex()
...
@@ -572,7 +362,6 @@ yylex()
if
(
spew_debug
)
if
(
spew_debug
)
debug_yychar
(
yychar
);
debug_yychar
(
yychar
);
#endif
#endif
/* consume_token(); */
/* already eaten by frob_identifier?... */
return
yychar
;
return
yychar
;
}
}
...
@@ -618,515 +407,6 @@ do_aggr ()
...
@@ -618,515 +407,6 @@ do_aggr ()
}
}
return
0
;
return
0
;
}
}
static
struct
token
frob_identifier
()
{
/* we could have a type, if it is followed by :: (if so, suck it all up); */
/* we could have a ptypename; */
/* we could have a normal identifier. */
tree
t1
;
struct
token
rt
;
scan_tokens
(
1
);
rt
=
*
nth_token
(
0
);
#if 0
if (nth_token(1)->yychar == '<')
{
t1 = hack_ptype(); /* suck up the whole thing */
if (t1)
{
rt.yylval.ttype = t1;
rt.yychar = TYPENAME;
*nth_token(0) = rt;
}
/* else fall out bottom */
}
#endif
if
(
nth_token
(
1
)
->
yychar
==
SCOPE
)
{
#if 0
t1 = hack_more_ids(0);
if (t1 && TREE_CODE(t1) == SCOPE_REF)
#else
t1
=
hack_more_ids
(
0
,
nth_token
(
0
)
->
yylval
.
ttype
);
if
(
t1
)
#endif
{
rt
.
yylval
.
ttype
=
t1
;
rt
.
yychar
=
SCOPED_TYPENAME
;
return
rt
;
}
else
{
/* deal with types (enums?) in classes... */
struct
token
*
tok
;
tree
ta
,
tb
;
scan_tokens
(
3
);
/* Have to check for a type conversion operator
to a nested type. */
if
(
nth_token
(
2
)
->
yychar
==
OPERATOR
)
tok
=
nth_token
(
3
);
else
tok
=
nth_token
(
2
);
if
(
tok
->
yychar
==
IDENTIFIER
||
tok
->
yychar
==
TYPENAME
)
{
ta
=
build_parse_node
(
SCOPE_REF
,
nth_token
(
0
)
->
yylval
.
ttype
,
tok
->
yylval
.
ttype
);
tb
=
resolve_scope_to_name
(
NULL_TREE
,
ta
);
if
(
tb
!=
NULL_TREE
)
{
if
(
nth_token
(
2
)
->
yychar
==
OPERATOR
)
{
/* Have to keep these tokens around
so we can finish parsing the declaration.
What do we do for
int foo::operator bar::baz ();
where bar is a nested class in foo? */
nth_token
(
3
)
->
yychar
=
TYPENAME
;
nth_token
(
3
)
->
yylval
.
ttype
=
tb
;
}
else
{
consume_token
();
/* base type */
consume_token
();
/* SCOPE */
consume_token
();
/* member type */
rt
.
yychar
=
TYPENAME
;
rt
.
yylval
.
ttype
=
tb
;
rt
.
end_of_file
=
tok
->
end_of_file
;
return
rt
;
}
}
}
/* else fall out bottom */
}
}
consume_token
();
return
rt
;
}
#if 0
/* When this function is called, nth_token(0) is the current
token we are scanning. This means that the next token we'll
scan is nth_token (1). Usually the next token we'll scan
is nth_token (0) (and the current token is in [yylval,yychar]). */
tree
arbitrate_lookup (name, exp_decl, type_decl)
tree name, exp_decl, type_decl;
{
int ch;
tree t;
char *assume;
scan_tokens (3);
ch = nth_token (1)->yychar;
switch (ch)
{
case '(':
case LEFT_RIGHT:
/* If we guessed wrong here, `build_functional_cast' can fix it. */
return type_decl;
case '=':
if (global_bindings_p ())
/* Probably a default parameter. */
return type_decl;
/* Probably not an initialization. */
return exp_decl;
case '[':
/* This needs special help because an expression inside the
brackets means nothing. */
{
int i;
for (i = 0; i < 42; i++)
{
int ith_yychar;
scan_tokens (3+i);
ith_yychar = nth_token (2+i)->yychar;
/* If we hit an undefined identifier, assume
the decl in arbitration is its type specifier. */
if (ith_yychar == IDENTIFIER
&& lookup_name (nth_token (2+i)->yylval.ttype, 0) == 0)
return type_decl;
else if (ith_yychar == ']')
{
/* There are only a few things we expect after a ']'
in a declarator. */
i += 1;
scan_tokens (4+i);
ith_yychar = nth_token (2+i)->yychar;
/* These are inconclusive. */
if (ith_yychar == LEFT_RIGHT
|| ith_yychar == '('
|| ith_yychar == '['
|| ith_yychar == ',')
continue;
/* stmt or decl? We'll probably never know. */
else if (ith_yychar == ';')
goto warn_ambiguous;
if (ith_yychar == '=')
{
if (nth_token (3+i)->yychar == '{')
return type_decl;
continue;
}
/* Whatever it is, it looks like we're processing an expr. */
return exp_decl;
}
}
goto warn_ambiguous;
}
case ',':
case ';':
case '&':
case '<':
case '*':
case ']':
case ')':
case '>':
/* see if the next token looks like it wants to be part
of a declaration list or an expression list. */
{
int i;
/* Some heuristics: if we are inside a function definition,
prefer the local declaration. */
if (! global_bindings_p ())
{
if (IDENTIFIER_LOCAL_VALUE (name) == exp_decl)
return exp_decl;
if (IDENTIFIER_LOCAL_VALUE (name) != type_decl
&& IDENTIFIER_CLASS_VALUE (name) == exp_decl)
return exp_decl;
}
/* If these symbols follow in a list, we know it's a list of
expressions. */
if (follows_identifier[nth_token (2)->yychar])
return exp_decl;
/* If we see a id&, or id&) the we are probably in an argument list. */
if (ch=='&'
&& (nth_token (2)->yychar == ',' || nth_token (2)->yychar == ')'))
return type_decl;
/* Look for the first identifier or other distinguishing token
we find in the next several tokens. */
for (i = 0; i < 42; i++)
{
int ith_yychar;
scan_tokens (3+i);
ith_yychar = nth_token (2+i)->yychar;
if (ith_yychar == IDENTIFIER)
{
tree as_type = lookup_name (nth_token (2+i)->yylval.ttype, 1);
if (as_type && TREE_CODE (as_type) != TYPE_DECL)
return exp_decl;
/* An undeclared identifier or a typename means we're
probably looking at a typename. */
return type_decl;
}
else if (ith_yychar == EMPTY
|| follows_identifier[ith_yychar])
return exp_decl;
else if (follows_typename[ith_yychar])
return type_decl;
/* stmt or decl? We'll probably never know. */
else if (ith_yychar == ';')
goto warn_ambiguous;
}
goto warn_ambiguous;
}
default:
if (follows_identifier[ch])
return exp_decl;
if (follows_typename[ch])
return type_decl;
/* Fall through... */
warn_ambiguous:
if (ch == '[')
{
assume = "expression";
t = exp_decl;
}
else
{
assume = "type";
t = type_decl;
}
warning ("name `%s' could be type or expression; compiler assuming %s",
IDENTIFIER_POINTER (DECL_NAME (t)), assume);
return t;
}
}
#endif
/* now returns decl_node */
#if 0
static tree
hack_ptype()
{
/* when we get here, we know that [0] is a ptype and [1] is '<'.
* now we loop over simple parameters. */
struct token this_param;
int n = 2;
tree tplist = 0;
tree tc;
scan_tokens(n+1);
while((this_param = *nth_token(n)).yychar != '>')
{
/* if it is a type, add it to the list */
tree thistype;
switch(this_param.yychar)
{
case IDENTIFIER:
case TYPENAME:
case TYPESPEC:
break;
default:
return 0;
}
thistype = this_param.yylval.ttype;
thistype = lookup_name(thistype, 1);
thistype = TREE_TYPE (thistype);
if (tplist)
tplist = chainon (tplist, build_tree_list (NULL_TREE, thistype));
else
tplist = build_tree_list(NULL_TREE, thistype);
/* then suck up the comma */
n++;
scan_tokens(n+1);
this_param = *nth_token(n);
if (this_param.yychar == ',')
{
n++;
scan_tokens(n+1);
continue;
}
if (this_param.yychar == '>')
break;
return 0;
}
/* once we're done, lookup_template_class -> identifier */
tc = lookup_template_class (nth_token(0)->yylval.ttype,tplist);
/* then lookup_name on that to get a type, if there is one */
tc = lookup_name (tc, 1);
if (tc)
{
int i;
/* don't actually eat the trailing '>'... we can replace it! */
for (i=0; i<n; i++)
consume_token();
/* IDENTIFIER_TYPE_VALUE (DECL_NAME (tc)) = */
return DECL_NAME (tc);
}
return NULL_TREE;
}
#endif
#if 0
static tree
hack_more_ids (n)
int n;
{
/*
* The recursion should probably do consume_tokens(), since once we've started
* down an IDENTIFIER SCOPE ... chain, we don't need to back-track - we just
* get as much as we can, make SCOPE_REF's out of it, and return it.
*/
struct token this_iter, this2_iter;
int tmp_y;
scan_tokens(n+1);
this_iter = *nth_token(n);
tmp_y = nth_token(n)->yychar;
if (tmp_y == IDENTIFIER || tmp_y == TYPENAME)
{
scan_tokens(n+2+2);
if (nth_token(n+1)->yychar == SCOPE)
{
if (nth_token(n+1+2)->yychar == SCOPE)
{
tree hmi;
consume_token(); /* last IDENTIFIER (this_iter) */
consume_token(); /* last SCOPE */
this2_iter = *nth_token(n);
hmi = hack_more_ids (n);
if (hmi)
return build_parse_node (SCOPE_REF, this_iter.yylval.ttype, hmi);
consume_token(); /* last IDENTIFIER (this2_iter) */
return build_parse_node (SCOPE_REF, this_iter.yylval.ttype,
this2_iter.yylval.ttype);
}
else
{
/* consume_token(); */ /* last IDENTIFIER */
/* leave whatever else we got */
/* return this_iter.yylval.ttype; */
return NULL_TREE;
}
}
}
return NULL_TREE; /* @@ may need to backtrack */
}
#else
/* niklas@appli.se says: I didn't understand how the code above was intended
* to work, so I rewrote it (also changed the interface a bit). This code
* dives down an IDENTIFIER/TYPENAME SCOPE ... chain as long as the parsed
* type prefix constitutes recognizable (by resolve_scope_to_name) types.
* Interface changed like this:
* 1. Takes an extra argument containing the name of the the type recognized
* so far.
* 2. Now returns the name of the type instead of a SCOPE_REF. */
static
tree
hack_more_ids
(
n
,
outer
)
int
n
;
tree
outer
;
{
int
ch
;
tree
type
,
val
,
inner
,
outer_t
;
scan_tokens
(
n
+
2
);
if
(
nth_token
(
n
+
1
)
->
yychar
!=
SCOPE
||
((
ch
=
nth_token
(
n
+
2
)
->
yychar
)
!=
IDENTIFIER
&&
ch
!=
TYPENAME
))
return
NULL_TREE
;
inner
=
nth_token
(
n
+
2
)
->
yylval
.
ttype
;
val
=
build_parse_node
(
SCOPE_REF
,
outer
,
inner
);
outer_t
=
TREE_TYPE
(
outer
);
if
(
outer_t
&&
TREE_CODE
(
outer_t
)
==
UNINSTANTIATED_P_TYPE
)
{
tree
t
=
make_lang_type
(
UNINSTANTIATED_P_TYPE
);
tree
id
=
inner
;
tree
d
=
build_lang_decl
(
TYPE_DECL
,
id
,
t
);
TYPE_NAME
(
t
)
=
d
;
TYPE_VALUES
(
t
)
=
TYPE_VALUES
(
outer_t
);
TYPE_CONTEXT
(
t
)
=
outer_t
;
/*
pushdecl_top_level (d);
*/
pushdecl
(
d
);
type
=
val
;
TREE_TYPE
(
type
)
=
t
;
}
else
{
type
=
resolve_scope_to_name
(
NULL_TREE
,
val
);
if
(
type
==
NULL_TREE
)
return
NULL_TREE
;
}
consume_token
();
consume_token
();
val
=
hack_more_ids
(
n
,
type
);
if
(
!
val
)
consume_token
();
return
val
?
val
:
type
;
}
#endif
#if 0
static struct token
hack_scope ()
{
/* we've got a :: - what follows is either a global var or a type. */
/* hmm, template names can be in the global scope too... */
tree t1;
struct token rt;
scan_tokens(1);
if (nth_token(1)->yychar == IDENTIFIER)
{
/* @@ this is probably not right, but doesn't get hit yet */
t1 = build_parse_node (SCOPE_REF,
NULL_TREE, /* to get "global" scope */
hack_more_ids(0)); /* do some prefetching */
rt.yylval.ttype = t1;
rt.yychar = /*SCOPED_*/TYPENAME;
return rt;
}
else
{
rt = *nth_token(0);
consume_token();
return rt;
}
}
#endif
/*
* Generations:
*
* PINST: PTYPE { saved_arg_count = arg_count($1) }
* '<' { arg_c = 0; } PARGS '>'
* ;
* PARG: TYPE
* | VALUE
* ;
* (of course the arg counting doesn't work for recursion... Do it right.)
* PARGS: PARG { assert(arg_c == saved_arg_count); }
* | PARG ',' PARGS { arg_c++; }
* ;
* ATYPE: PINST
* | TYPEID
* ;
* TYPE: ATYPE
* | ATYPE { basetype = $1; } '::' TYPEKIDS
* ;
* TYPEKIDS: TYPE { assert ($1 is a member of basetype); }
* | TYPEKIDS { basetype += $1} TYPE { assert( $3 is in basetype ); }
* ;
*
*
* state0: ; ATYPE
* TYPE '<': ac = args($0), base = CALL state1, state3
* TYPE '::': base=$0, state3
* else return TYPE
* state1: ; begin PARGS
* if(ac < list length) punt
* PARG ",": add to list, state1
* PARG ">": add to list, return
* else unravel
* state3: ; begin TYPEKIDS
* TYPE:
*/
#ifdef SPEW_DEBUG
#ifdef SPEW_DEBUG
/* debug_yychar takes a yychar (token number) value and prints its name. */
/* debug_yychar takes a yychar (token number) value and prints its name. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment