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
b7484fbe
Commit
b7484fbe
authored
Mar 15, 1995
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
58th Cygnus<->FSF merge
From-SVN: r9186
parent
a0dabda5
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1459 additions
and
943 deletions
+1459
-943
gcc/cp/ChangeLog
+347
-13
gcc/cp/Makefile.in
+3
-2
gcc/cp/call.c
+13
-1
gcc/cp/class.c
+9
-7
gcc/cp/cp-tree.h
+17
-4
gcc/cp/cvt.c
+203
-127
gcc/cp/decl.c
+138
-76
gcc/cp/decl2.c
+81
-86
gcc/cp/error.c
+11
-4
gcc/cp/except.c
+43
-22
gcc/cp/init.c
+359
-350
gcc/cp/lex.c
+5
-2
gcc/cp/method.c
+3
-1
gcc/cp/parse.y
+24
-20
gcc/cp/pt.c
+18
-4
gcc/cp/tree.c
+4
-0
gcc/cp/typeck.c
+172
-223
gcc/cp/typeck2.c
+9
-1
No files found.
gcc/cp/ChangeLog
View file @
b7484fbe
Mon Mar 13 21:00:28 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator, case ARRAY_REF): Wrap the exp with fold,
and convert the size and integer_one_node to the index type.
Mon Mar 13 08:01:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (get_member_function_from_ptrfunc): Save the instance
argument, and tack it onto the front of the COND_EXPR to make the
semantics come out right. Grab the instance argument from
'*instance_ptrptr', rather than having it passed in separately.
* various: Change various consed-up comparison operations to have
boolean type. Remove the instance argument in calls to
get_member_function_from_ptrfunc.
* error.c (dump_expr): Dump true and false as "true" and "false".
* decl2.c (finish_file): Also set DECL_STATIC_FUNCTION_P on the
global init function.
* decl.c (finish_function): Only set DECL_EXTERNAL here if the
inline function is public.
Sat Mar 11 00:58:03 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* init.c (is_friend): Be more careful about checking
DECL_CLASS_CONTEXT on non-member functions.
* decl2.c (finish_vtable_vardecl): Don't bother calling
assemble_external here.
(prune_vtable_vardecl): New function that just splices out the
vtable decl from the top-level decls.
(import_export_inline): Unset DECL_EXTERNAL at first.
(finish_file): Don't bother calling assemble_external here. Do
splice out all of the vtables.
Fri Mar 10 14:42:29 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (finish_function): If we're not emitting the function yet,
call assemble_external for it.
* decl2.c (finish_prevtable_vardecl): Don't call mark_vtable_entries
here.
(finish_vtable_vardecl): Don't do the linkage deduction thing here.
Also don't splice out the current vtable if it is unused.
(finish_file): Move the second walk_vtables and the synthesis check
inside the 'reconsider' loop. Move thunk emission after the
'reconsider' loop.
Thu Mar 9 16:28:16 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* pt.c (tsubst): Don't bother calling cp_build_type_variant, since it
was passing bogus values for readonly and volatile from the original
template decl, not the resultant type of the tsubst call.
* class.c (duplicate_tag_error): Use cp_error_at to point out the
previous definition of the tag.
Thu Mar 9 10:46:17 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (start_function): Clear base_init_insns and protect_list.
(struct cp_function): Add base_init_insns field.
(push_cp_function_context): Also save base_init_insns.
(pop_cp_function_context): Also restore base_init_insns.
Wed Mar 8 13:31:44 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* init.c (member_init_ok_or_else): Check for initializing a static
member here.
(emit_base_init): Instead of here.
Tue Mar 7 16:03:26 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* call.c (build_method_call): Disable synthesis as needed.
* lex.c (cons_up_default_function): Ditto.
Tue Mar 7 10:14:29 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* parse.y: New rules to allow attributes in a prefix position.
...
...
@@ -10,6 +87,234 @@ Tue Mar 7 10:14:29 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
(grokdeclarator): Added code to support machine attributes.
* Makefile.in (stamp-parse): Expect 5 shift/reduce failures.
Mon Mar 6 15:07:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* call.c (build_method_call): Don't synthesize methods outside of a
function.
Make base initialization more re-entrant so that synthesis on the
fly will work (and, eventually, template instantation on the fly).
* init.c (sort_member_init): Don't bother with members that can't be
initialized. Reorganize a bit. Don't initialize base members here.
(sort_base_init): New function, like sort_member_init, but for base
classes. Steals some code from emit_base_init.
(emit_base_init): Simplify. Call sort_{member,base}_init before
doing any initialization, so we don't have to save
current_{member,base}_init_list in push_cp_function_context.
(expand_aggr_vbase_init_1): Adjust for sort_base_init.
(expand_aggr_vbase_init): Simplify.
* decl.c (struct cp_function): Add protect_list field.
(push_cp_function_context): Also save protect_list.
(pop_cp_function_context): Also restore protect_list.
* call.c (build_method_call): Enable synthesis at point of call.
* lex.c (cons_up_default_function): Ditto.
* parse.y: Turn -ansi checks back into -pedantic checks.
* init.c (build_new): Fix -fcheck-new for array new.
Sat Mar 4 15:55:42 1995 Fergus Henderson <fjh@cs.mu.oz.au>
* typeck.c (build_compound_expr): warn if left-hand operand of
comma expression has no side-effects.
Fri Mar 3 15:16:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* parse.y (primary): Change 'object qualified_id *' rules to 'object
overqualified_id *'.
Fri Mar 3 12:48:17 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* parse.y (unary_expr): Catch doing sizeof an overloaded function.
Make the error look the same as the one we issue in c_sizeof.
* typeck.c (build_binary_op_nodefault): Give an error for trying
to compare a pointer-to-member to `void *'.
Fri Mar 3 11:28:50 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_unary_op): Handle bool increment with smoke and
mirrors here, rather than in expand_increment where it belongs,
because Kenner doesn't agree with me.
Fri Mar 3 00:08:10 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokparms): Catch a PARM_DECL being used for a default
argument as well.
Thu Mar 2 20:05:54 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* init.c (build_new): Don't allow new on a function type.
* parse.y (primary): Avoid a crash when seeing if the arg is of
the same type as that given for the typespec in an explicit dtor call.
Thu Mar 2 00:49:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (finish_function): Change test for calling
mark_inline_for_output.
Wed Mar 1 11:23:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_modify_expr): Complain if
build_default_binary_type_conversion fails.
* init.c (expand_default_init): Handle arguments of unknown type
properly.
* cvt.c (build_expr_type_conversion): Only complain about ambiguity
if 'complain'.
* various: Pass 'complain'.
* typeck.c (comptypes): Be more picky about comparing UPTs.
Wed Mar 1 11:03:41 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator): If declarator is null, say that the
type used has an incomplete type.
Wed Mar 1 10:06:20 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* pt.c (instantiate_template): Copy the template arguments to the
permanent_obstack. Also use simple_cst_equal to compare them when
looking for a previous instantiation.
* tree.c (make_deep_copy): Support copying INTEGER_TYPEs (assuming
they are array domain types).
Tue Feb 28 23:24:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* cp-tree.h: Define WANT_* constants for passing to
build_expr_type_conversion.
* cvt.c (build_expr_type_conversion): New function to build
conversion to one of a group of suitable types.
(build_default_binary_type_conversion): Use it.
* decl2.c (grok_array_decl): Ditto.
* typeck.c (build_unary_op): Ditto.
(build_array_ref): Tidy up a bit.
(build_binary_op): Ditto.
Tue Feb 28 19:57:31 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator): Don't allow decl of an argument as `void'.
Tue Feb 28 17:23:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* parse.y (typed_declspecs1): Add 'typespec reserved_typespecquals
reserved_declspecs' rule.
* parse.y (expr_or_declarator): Remove notype_qualified_id rule.
(direct_notype_declarator): Ditto.
(complex_direct_notype_declarator): Add notype_qualified_id rule.
* lex.c (real_yylex): Handle :> digraph properly.
Tue Feb 28 12:26:29 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator): Check if it's a friend, not if it's
non-virtual, that's being initialized. Move the check up to
before FRIENDP would get cleared. Catch an unnamed var/field
being declared void. Say just `field' instead of `structure field'
in the error message. Only go for the operator name if DECLARATOR
is non-null.
Tue Feb 28 00:08:01 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (start_function): Complain about abstract return type.
(grokdeclarator): Complain about declaring constructors and
destructors to be const or volatile. Complain about declaring
destructors to be static.
* pt.c (uses_template_parms): Handle pmfs.
* decl.c (grokdeclarator): Don't call variable_size for array bounds
that only depend on template constant parameters.
Mon Feb 27 15:38:16 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* error.c (dump_decl): Only look to see if it's a vtable if we
actually have a name to check out.
Mon Feb 27 13:37:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* cvt.c (convert_to_aggr): Lose misleading shortcut.
Sun Feb 26 17:27:32 1995 Doug Evans <dje@canuck.cygnus.com>
* decl.c (set_nested_typename): Always set DECL_IGNORED_P,
not just for dwarf.
Sun Feb 26 00:10:18 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator): Don't allow a static member to be
declared `register'.
* init.c (make_friend_class): Move up to a pedwarn for the warning
about a class declaring friends with itself.
* decl.c (grokdeclarator): You can't do `volatile friend class foo'
or `inline friend class foo'. Only try to make a friend out of
TYPE if we didn't already reset it to integer_type_node.
Sat Feb 25 22:32:03 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator): Don't allow initialization of a
non-virtual function.
* decl.c (start_function): Do a pedwarn if we're changing `main'
to have an int return type.
Sat Feb 25 00:02:05 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_modify_expr): Handle simple assignment from
TARGET_EXPRs by building up an RTL_EXPR to force expansion. Whew.
Fri Feb 24 18:27:14 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator): Also don't allow virtual outside of a
class decl for a scope method definition performed at global binding.
* init.c (build_offset_ref): Don't allow creation of an OFFSET_REF
of a bitfield.
* decl.c (grokdeclarator): Don't allow a const to be declared mutable.
* typeck.c (build_binary_op): Return an error_mark_node if either
one of the args turned into an error_mark_node when we tried to
use default_conversion.
* typeck.c (build_unary_op): Forbid using postfix -- on a bool.
* decl.c (grokdeclarator): Allow `signed' and `unsigned' to be
used on `__wchar_t'.
Fri Feb 24 13:59:53 1995 Mike Stump <mrs@cygnus.com>
* except.c (end_protect_partials): Do it the right way.
Wed Feb 22 15:42:56 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_binary_op_nodefault): Upgrade warning about
comparing distinct pointer types to pedwarn.
* typeck2.c (digest_init): Cope with extra braces.
* typeck.c (build_binary_op_nodefault): Use tree_int_cst_sgn instead
of INT_CST_LT (..., interger_zero_node).
Wed Feb 22 14:45:52 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* except.c [!TRY_NEW_EH] (end_protect_partials): Define dummy
function for systems that don't have EH.
Tue Feb 21 19:18:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* call.c (can_convert_arg): Like can_convert, but takes an arg as
well.
* pt.c (type_unification): Allow implicit conversions for parameters
that do not depend on template parameters.
Tue Feb 21 18:43:48 1995 Douglas Rupp (drupp@cs.washington.edu)
* Make-lang.in, config-lang.in: ($exeext): New macro.
...
...
@@ -19,17 +324,46 @@ Tue Feb 21 18:43:48 1995 Douglas Rupp (drupp@cs.washington.edu)
* cp/g++.c: Added #ifdefs for sys/file.h and process.h for NT.
Modified spawnvp to have to correct number of arguments for OS/2, NT.
Thu Feb 2 15:07:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
Tue Feb 21 18:36:55 1995 Mike Stump <mrs@cygnus.com>
* decl.c (finish_function): Add calls to end_protect_partials to end
the exception region that protects constructors so that partially
constructed objects can be partially destructed when the constructor
throws an exception.
* init.c (perform_member_init, sort_member_init, emit_base_init):
Added support for partially constructed objects.
* init.c (build_partial_cleanup_for): New routine to do partial
cleanups of a base class.
* decl2.c (finish_file): Move the emitting of the exception table
down, after we emit all code that might have exception regions in
them.
* except.c (end_protect_partials, might_have_exceptions_p): New
routines.
(emit_exception_table): Always output table if called.
* cp-tree.h (protect_list, end_protect_partials,
might_have_exceptions_p, emit_exception_table): Added.
Tue Feb 21 16:05:59 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* gc.c (build_typeid): Pass a NULL_TREE, not the bogus, unused
address of a local variable.
* class.c (build_vfn_ref): Only try to build the PLUS_EXPR if we
were given a non-null PTR_TO_INSTPTR.
Tue Feb 21 01:53:18 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (duplicate_decls): Always lay out the merged decl.
* decl2.c (finish_vtable_vardecl): Don't do vtable hack on templates.
(finish_prevtable_vardecl): Ditto.
* class.c (build_vbase_path): Bash types to make the backend happy.
* cvt.c (build_up_reference): Bash the types bashed by
build_vbase_path to be reference types instead of pointer types.
(convert_to_reference): Ditto.
* method.c (synthesize_method): Set interface_{unknown,only}
according to the settings for our class, not the file where it comes
from.
Wed Jan 25 15:02:09 1995 David S. Miller (davem@nadzieja.rutgers.edu)
Sat Feb 18 12:26:48 1995 Mike Stump <mrs@cygnus.com>
* class.c (instantiate_type): Change error message text.
* typeck2.c (store_init_value): Likewise.
* except.c: Handle systems that define __i386__ but not __i386.
Fri Feb 17 15:31:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
...
...
@@ -518,6 +852,11 @@ Tue Jan 24 16:36:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck2.c (build_functional_cast): Don't assume that a NOP_EXPR
will suffice to convert from integer_zero_node.
Wed Jan 25 15:02:09 1995 David S. Miller (davem@nadzieja.rutgers.edu)
* class.c (instantiate_type): Change error message text.
* typeck2.c (store_init_value): Likewise.
Mon Jan 23 21:57:14 1995 Mike Stump <mrs@cygnus.com>
* pt.c (tsubst): When we copy a node, don't forget to copy
...
...
@@ -4034,11 +4373,6 @@ Fri Apr 22 03:27:26 1994 Doug Evans (dje@cygnus.com)
* Language directory reorganization.
See parent makefile.
Fri Apr 22 03:27:26 1994 Doug Evans (dje@cygnus.com)
* Language directory reorganization.
See parent makefile.
Thu Apr 21 18:27:57 1994 Per Bothner (bothner@kalessin.cygnus.com)
* cp-tree.h (THUNK_DELTA): It is normally negative, so
...
...
gcc/cp/Makefile.in
View file @
b7484fbe
...
...
@@ -194,14 +194,15 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
$(CC)
-c
$(ALL_CFLAGS)
$(ALL_CPPFLAGS)
$(INCLUDES)
$(BIG_SWITCHFLAG)
\
`
echo
$(PARSE_C)
| sed
's,^\./,,'
`
CONFLICTS
=
expect 5
shift
/reduce confict and 38 reduce/reduce conflicts.
$(PARSE_H)
:
$(PARSE_C)
$(PARSE_C)
:
$(srcdir)/parse.y
@
echo
expect 5
shift
/reduce confict and 39 reduce/reduce conflicts.
@
echo
$(CONFLICTS)
cd
$(srcdir)
;
$(BISON)
$(BISONFLAGS)
-d
-o
parse.c parse.y
cd
$(srcdir)
;
grep
'^#define[ ]*YYEMPTY'
parse.c
>>
parse.h
#$(PARSE_C) $(PARSE_H) : stamp-parse ; @true
#stamp-parse: $(srcdir)/parse.y
# @echo
expect 1 shift/reduce confict and 39 reduce/reduce conflicts.
# @echo
$(CONFLICTS)
# $(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y
# grep '^#define[ ]*YYEMPTY' y.tab.c >>y.tab.h
# $(srcdir)/../move-if-change y.tab.c $(PARSE_C)
...
...
gcc/cp/call.c
View file @
b7484fbe
...
...
@@ -593,6 +593,15 @@ can_convert (to, from)
return
h
.
code
<
USER_CODE
;
}
int
can_convert_arg
(
to
,
from
,
arg
)
tree
to
,
from
,
arg
;
{
struct
harshness_code
h
;
h
=
convert_harshness
(
to
,
from
,
arg
);
return
h
.
code
<
USER_CODE
;
}
#ifdef DEBUG_MATCHING
static
char
*
print_harshness
(
h
)
...
...
@@ -2371,9 +2380,12 @@ build_method_call (instance, name, parms, basetype_path, flags)
assemble_external
(
function
);
#if 0
/* Is it a synthesized method that needs to be synthesized? */
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
&& DECL_SAVED_INSNS (function) == 0
&& ! TREE_ASM_WRITTEN (function))
&& ! TREE_ASM_WRITTEN (function)
/* Kludge: don't synthesize for default args. */
&& current_function_decl)
synthesize_method (function);
#endif
...
...
gcc/cp/class.c
View file @
b7484fbe
...
...
@@ -240,7 +240,7 @@ build_vbase_path (code, type, expr, path, alias_this)
{
null_expr
=
build1
(
NOP_EXPR
,
TYPE_POINTER_TO
(
last_virtual
),
integer_zero_node
);
expr
=
build
(
COND_EXPR
,
TYPE_POINTER_TO
(
last_virtual
),
build
(
EQ_EXPR
,
integer
_type_node
,
expr
,
build
(
EQ_EXPR
,
boolean
_type_node
,
expr
,
integer_zero_node
),
null_expr
,
nonnull_expr
);
}
...
...
@@ -323,7 +323,7 @@ build_vbase_path (code, type, expr, path, alias_this)
expr
=
save_expr
(
expr
);
return
build
(
COND_EXPR
,
type
,
build
(
EQ_EXPR
,
integer
_type_node
,
expr
,
integer_zero_node
),
build
(
EQ_EXPR
,
boolean
_type_node
,
expr
,
integer_zero_node
),
null_expr
,
build
(
code
,
type
,
expr
,
offset
));
}
...
...
@@ -490,11 +490,12 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
return
aref
;
else
{
*
ptr_to_instptr
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
*
ptr_to_instptr
),
*
ptr_to_instptr
,
convert
(
ptrdiff_type_node
,
build_component_ref
(
aref
,
delta_identifier
,
0
,
0
)));
if
(
ptr_to_instptr
)
*
ptr_to_instptr
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
*
ptr_to_instptr
),
*
ptr_to_instptr
,
convert
(
ptrdiff_type_node
,
build_component_ref
(
aref
,
delta_identifier
,
0
,
0
)));
return
build_component_ref
(
aref
,
pfn_identifier
,
0
,
0
);
}
}
...
...
@@ -2020,6 +2021,7 @@ duplicate_tag_error (t)
tree
t
;
{
cp_error
(
"redefinition of `%#T'"
,
t
);
cp_error_at
(
"previous definition here"
,
t
);
/* Pretend we haven't defined this type. */
...
...
gcc/cp/cp-tree.h
View file @
b7484fbe
...
...
@@ -1836,6 +1836,17 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define CONV_C_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \
| CONV_REINTERPRET | CONV_PRIVATE | CONV_FORCE_TEMP)
/* Used by build_expr_type_conversion to indicate which types are
acceptable as arguments to the expression under consideration. */
#define WANT_INT 1
/* integer types, including bool */
#define WANT_FLOAT 2
/* floating point types */
#define WANT_ENUM 4
/* enumerated types */
#define WANT_POINTER 8
/* pointer types */
#define WANT_NULL 16
/* null pointer constant */
#define WANT_ARITH (WANT_INT | WANT_FLOAT)
/* Anatomy of a DECL_FRIENDLIST (which is a TREE_LIST):
purpose = friend name (IDENTIFIER_NODE);
value = TREE_LIST of FUNCTION_DECLS;
...
...
@@ -1913,8 +1924,8 @@ extern tree convert PROTO((tree, tree));
extern
tree
cp_convert
PROTO
((
tree
,
tree
,
int
,
int
));
extern
tree
convert_force
PROTO
((
tree
,
tree
,
int
));
extern
tree
build_type_conversion
PROTO
((
enum
tree_code
,
tree
,
tree
,
int
));
extern
tree
build_expr_type_conversion
PROTO
((
int
,
tree
,
int
));
extern
int
build_default_binary_type_conversion
PROTO
((
enum
tree_code
,
tree
*
,
tree
*
));
extern
int
build_default_unary_type_conversion
PROTO
((
enum
tree_code
,
tree
*
));
extern
tree
type_promotes_to
PROTO
((
tree
));
/* decl.c */
...
...
@@ -2042,9 +2053,10 @@ extern tree get_namespace_id PROTO((void));
/* in edsel.c */
/* in except.c */
extern
tree
protect_list
;
extern
void
start_protect
PROTO
((
void
));
extern
void
end_protect
PROTO
((
tree
));
extern
void
end_protect_partials
();
extern
void
expand_exception_blocks
PROTO
((
void
));
extern
void
expand_start_try_stmts
PROTO
((
void
));
extern
void
expand_end_try_stmts
PROTO
((
void
));
...
...
@@ -2053,7 +2065,8 @@ extern void expand_end_all_catch PROTO((void));
extern
void
start_catch_block
PROTO
((
tree
,
tree
));
extern
void
end_catch_block
PROTO
((
void
));
extern
void
expand_throw
PROTO
((
tree
));
extern
int
build_exception_table
PROTO
((
void
));
extern
int
might_have_exceptions_p
PROTO
((
void
));
extern
void
emit_exception_table
PROTO
((
void
));
extern
tree
build_throw
PROTO
((
tree
));
extern
void
init_exception_processing
PROTO
((
void
));
...
...
@@ -2093,7 +2106,7 @@ extern tree get_type_value PROTO((tree));
extern
tree
build_member_call
PROTO
((
tree
,
tree
,
tree
));
extern
tree
build_offset_ref
PROTO
((
tree
,
tree
));
extern
tree
get_member_function
PROTO
((
tree
*
,
tree
,
tree
));
extern
tree
get_member_function_from_ptrfunc
PROTO
((
tree
*
,
tree
,
tree
));
extern
tree
get_member_function_from_ptrfunc
PROTO
((
tree
*
,
tree
));
extern
tree
resolve_offset_ref
PROTO
((
tree
));
extern
tree
decl_constant_value
PROTO
((
tree
));
extern
int
is_friend_type
PROTO
((
tree
,
tree
));
...
...
gcc/cp/cvt.c
View file @
b7484fbe
...
...
@@ -903,6 +903,7 @@ convert_to_aggr (type, expr, msgp, protect)
parmlist
=
tree_cons
(
NULL_TREE
,
integer_zero_node
,
parmlist
);
parmtypes
=
tree_cons
(
NULL_TREE
,
TYPE_POINTER_TO
(
basetype
),
parmtypes
);
#if 0
method_name = build_decl_overload (name, parmtypes, 1);
/* constructors are up front. */
...
...
@@ -936,6 +937,7 @@ convert_to_aggr (type, expr, msgp, protect)
}
fndecl = DECL_CHAIN (fndecl);
}
#endif
/* No exact conversion was found. See if an approximate
one will do. */
...
...
@@ -1548,7 +1550,7 @@ build_type_conversion (code, xtype, expr, for_sure)
{
cp_error
(
"ambiguous conversion from `%T' to `%T'"
,
basetype
,
xtype
);
cp_error
(
" candidate conversion
function
s include `%T' and `%T'"
,
cp_error
(
" candidate conversions include `%T' and `%T'"
,
TREE_VALUE
(
winner
),
TREE_VALUE
(
conv
));
return
NULL_TREE
;
}
...
...
@@ -1564,154 +1566,228 @@ build_type_conversion (code, xtype, expr, for_sure)
return
NULL_TREE
;
}
/*
Must convert two aggregate types to non-aggregate type.
Attempts to find a non-ambiguous, "best" type conversion.
Return 1 on success, 0 on failure.
/*
Convert the given EXPR to one of a group of types suitable for use in an
expression. DESIRES is a combination of various WANT_* flags (q.v.)
which indicates which types are suitable. If COMPLAIN is 1, complain
about ambiguity; otherwise, the caller will deal with it. */
@@ What are the real semantics of this supposed to be??? */
int
build_default_binary_type_conversion
(
code
,
arg1
,
arg2
)
enum
tree_code
code
;
tree
*
arg1
,
*
arg2
;
tree
build_expr_type_conversion
(
desires
,
expr
,
complain
)
int
desires
;
tree
expr
;
int
complain
;
{
tree
type1
=
TREE_TYPE
(
*
arg1
);
tree
type2
=
TREE_TYPE
(
*
arg2
);
if
(
TREE_CODE
(
type1
)
==
REFERENCE_TYPE
||
TREE_CODE
(
type1
)
==
POINTER_TYPE
)
type1
=
TREE_TYPE
(
type1
);
if
(
TREE_CODE
(
type2
)
==
REFERENCE_TYPE
||
TREE_CODE
(
type2
)
==
POINTER_TYPE
)
type2
=
TREE_TYPE
(
type2
);
tree
basetype
=
TREE_TYPE
(
expr
);
tree
conv
;
tree
winner
=
NULL_TREE
;
if
(
TREE_CODE
(
TYPE_NAME
(
type1
))
!=
TYPE_DECL
)
if
(
TREE_CODE
(
basetype
)
==
OFFSET_TYPE
)
{
tree
decl
=
typedecl_for_tag
(
type1
);
if
(
decl
)
error
(
"type conversion nonexistent for type `%s'"
,
IDENTIFIER_POINTER
(
DECL_NAME
(
decl
)));
else
error
(
"type conversion nonexistent for non-C++ type"
);
return
0
;
}
if
(
TREE_CODE
(
TYPE_NAME
(
type2
))
!=
TYPE_DECL
)
{
tree
decl
=
typedecl_for_tag
(
type2
);
if
(
decl
)
error
(
"type conversion nonexistent for type `%s'"
,
IDENTIFIER_POINTER
(
decl
));
else
error
(
"type conversion nonexistent for non-C++ type"
);
return
0
;
expr
=
resolve_offset_ref
(
expr
);
basetype
=
TREE_TYPE
(
expr
);
}
if
(
!
IS_AGGR_TYPE
(
type1
)
||
!
TYPE_HAS_CONVERSION
(
type1
))
{
if
(
!
IS_AGGR_TYPE
(
type2
)
||
!
TYPE_HAS_CONVERSION
(
type2
))
cp_error
(
"no conversion from `%T' and `%T' to types with default `%O' "
,
type1
,
type2
,
code
);
else
cp_error
(
"no conversion from `%T' to type with default `%O'"
,
type1
,
code
);
return
0
;
}
else
if
(
!
IS_AGGR_TYPE
(
type2
)
||
!
TYPE_HAS_CONVERSION
(
type2
))
{
cp_error
(
"no conversion from `%T' to type with default `%O'"
,
type2
,
code
);
return
0
;
}
if
(
!
IS_AGGR_TYPE
(
basetype
))
switch
(
TREE_CODE
(
basetype
))
{
case
INTEGER_TYPE
:
if
((
desires
&
WANT_NULL
)
&&
TREE_CODE
(
expr
)
==
INTEGER_CST
&&
integer_zerop
(
expr
))
return
expr
;
/* else fall through... */
case
BOOLEAN_TYPE
:
return
(
desires
&
WANT_INT
)
?
expr
:
NULL_TREE
;
case
ENUMERAL_TYPE
:
return
(
desires
&
WANT_ENUM
)
?
expr
:
NULL_TREE
;
case
REAL_TYPE
:
return
(
desires
&
WANT_FLOAT
)
?
expr
:
NULL_TREE
;
case
POINTER_TYPE
:
return
(
desires
&
WANT_POINTER
)
?
expr
:
NULL_TREE
;
case
FUNCTION_TYPE
:
case
ARRAY_TYPE
:
return
(
desires
&
WANT_POINTER
)
?
default_conversion
(
expr
)
:
NULL_TREE
;
default
:
return
NULL_TREE
;
}
if
(
code
==
TRUTH_ANDIF_EXPR
||
code
==
TRUTH_ORIF_EXPR
)
{
*
arg1
=
convert
(
boolean_type_node
,
*
arg1
);
*
arg2
=
convert
(
boolean_type_node
,
*
arg2
);
}
else
if
(
TYPE_HAS_INT_CONVERSION
(
type1
))
{
if
(
TYPE_HAS_REAL_CONVERSION
(
type1
))
cp_pedwarn
(
"ambiguous type conversion for type `%T', defaulting to int"
,
type1
);
*
arg1
=
build_type_conversion
(
code
,
integer_type_node
,
*
arg1
,
1
);
*
arg2
=
build_type_conversion
(
code
,
integer_type_node
,
*
arg2
,
1
);
}
else
if
(
TYPE_HAS_REAL_CONVERSION
(
type1
))
{
*
arg1
=
build_type_conversion
(
code
,
double_type_node
,
*
arg1
,
1
);
*
arg2
=
build_type_conversion
(
code
,
double_type_node
,
*
arg2
,
1
);
}
else
{
*
arg1
=
build_type_conversion
(
code
,
ptr_type_node
,
*
arg1
,
1
);
if
(
*
arg1
==
error_mark_node
)
error
(
"ambiguous pointer conversion"
);
*
arg2
=
build_type_conversion
(
code
,
ptr_type_node
,
*
arg2
,
1
);
if
(
*
arg1
!=
error_mark_node
&&
*
arg2
==
error_mark_node
)
error
(
"ambiguous pointer conversion"
);
}
if
(
*
arg1
==
0
)
{
if
(
*
arg2
==
0
&&
type1
!=
type2
)
cp_error
(
"default type conversion for types `%T' and `%T' failed"
,
type1
,
type2
);
else
cp_error
(
"default type conversion for type `%T' failed"
,
type1
);
return
0
;
}
else
if
(
*
arg2
==
0
)
if
(
!
TYPE_HAS_CONVERSION
(
basetype
))
return
NULL_TREE
;
for
(
conv
=
lookup_conversions
(
basetype
);
conv
;
conv
=
TREE_CHAIN
(
conv
))
{
cp_error
(
"default type conversion for type `%T' failed"
,
type2
);
return
0
;
int
win
=
0
;
if
(
winner
&&
TREE_PURPOSE
(
winner
)
==
TREE_PURPOSE
(
conv
))
continue
;
switch
(
TREE_CODE
(
TREE_VALUE
(
conv
)))
{
case
BOOLEAN_TYPE
:
case
INTEGER_TYPE
:
win
=
(
desires
&
WANT_INT
);
break
;
case
ENUMERAL_TYPE
:
win
=
(
desires
&
WANT_ENUM
);
break
;
case
REAL_TYPE
:
win
=
(
desires
&
WANT_FLOAT
);
break
;
case
POINTER_TYPE
:
win
=
(
desires
&
WANT_POINTER
);
break
;
}
if
(
win
)
{
if
(
winner
)
{
if
(
complain
)
{
cp_error
(
"ambiguous default type conversion from `%T'"
,
basetype
);
cp_error
(
" candidate conversions include `%T' and `%T'"
,
TREE_VALUE
(
winner
),
TREE_VALUE
(
conv
));
}
return
error_mark_node
;
}
else
winner
=
conv
;
}
}
return
1
;
if
(
winner
)
return
build_type_conversion_1
(
TREE_VALUE
(
winner
),
basetype
,
expr
,
TREE_PURPOSE
(
winner
),
1
);
return
NULL_TREE
;
}
/* Must convert
an aggregate type
to non-aggregate type.
/* Must convert
two aggregate types
to non-aggregate type.
Attempts to find a non-ambiguous, "best" type conversion.
Return 1 on success, 0 on failure.
The type of the argument is expected to be of aggregate type here.
@@ What are the real semantics of this supposed to be??? */
int
build_default_
unary_type_conversion
(
code
,
arg
)
build_default_
binary_type_conversion
(
code
,
arg1
,
arg2
)
enum
tree_code
code
;
tree
*
arg
;
tree
*
arg
1
,
*
arg2
;
{
tree
type
=
TREE_TYPE
(
*
arg
);
if
(
!
TYPE_HAS_CONVERSION
(
type
))
switch
(
code
)
{
cp_error
(
"type conversion required for type `%T'"
,
type
);
return
0
;
}
case
MULT_EXPR
:
case
TRUNC_DIV_EXPR
:
case
CEIL_DIV_EXPR
:
case
FLOOR_DIV_EXPR
:
case
ROUND_DIV_EXPR
:
case
EXACT_DIV_EXPR
:
*
arg1
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg1
,
0
);
*
arg2
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg2
,
0
);
break
;
if
(
code
==
TRUTH_NOT_EXPR
)
*
arg
=
convert
(
boolean_type_node
,
*
arg
);
else
if
(
TYPE_HAS_INT_CONVERSION
(
type
))
{
if
(
TYPE_HAS_REAL_CONVERSION
(
type
))
cp_pedwarn
(
"ambiguous type conversion for type `%T', defaulting to int"
,
type
);
*
arg
=
build_type_conversion
(
code
,
integer_type_node
,
*
arg
,
1
);
}
else
if
(
TYPE_HAS_REAL_CONVERSION
(
type
))
*
arg
=
build_type_conversion
(
code
,
double_type_node
,
*
arg
,
1
);
else
{
*
arg
=
build_type_conversion
(
code
,
ptr_type_node
,
*
arg
,
1
);
if
(
*
arg
==
error_mark_node
)
error
(
"ambiguous pointer conversion"
);
}
if
(
*
arg
==
NULL_TREE
)
{
cp_error
(
"default type conversion for type `%T' failed"
,
type
);
return
0
;
case
TRUNC_MOD_EXPR
:
case
FLOOR_MOD_EXPR
:
case
LSHIFT_EXPR
:
case
RSHIFT_EXPR
:
case
BIT_AND_EXPR
:
case
BIT_XOR_EXPR
:
case
BIT_IOR_EXPR
:
*
arg1
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
*
arg1
,
0
);
*
arg2
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
*
arg2
,
0
);
break
;
case
PLUS_EXPR
:
{
tree
a1
,
a2
,
p1
,
p2
;
int
wins
;
a1
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg1
,
0
);
a2
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg2
,
0
);
p1
=
build_expr_type_conversion
(
WANT_POINTER
,
*
arg1
,
0
);
p2
=
build_expr_type_conversion
(
WANT_POINTER
,
*
arg2
,
0
);
wins
=
(
a1
&&
a2
)
+
(
a1
&&
p2
)
+
(
p1
&&
a2
);
if
(
wins
>
1
)
error
(
"ambiguous default type conversion for `operator +'"
);
if
(
a1
&&
a2
)
*
arg1
=
a1
,
*
arg2
=
a2
;
else
if
(
a1
&&
p2
)
*
arg1
=
a1
,
*
arg2
=
p2
;
else
*
arg1
=
p1
,
*
arg2
=
a2
;
break
;
}
case
MINUS_EXPR
:
{
tree
a1
,
a2
,
p1
,
p2
;
int
wins
;
a1
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg1
,
0
);
a2
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg2
,
0
);
p1
=
build_expr_type_conversion
(
WANT_POINTER
,
*
arg1
,
0
);
p2
=
build_expr_type_conversion
(
WANT_POINTER
,
*
arg2
,
0
);
wins
=
(
a1
&&
a2
)
+
(
p1
&&
p2
)
+
(
p1
&&
a2
);
if
(
wins
>
1
)
error
(
"ambiguous default type conversion for `operator -'"
);
if
(
a1
&&
a2
)
*
arg1
=
a1
,
*
arg2
=
a2
;
else
if
(
p1
&&
p2
)
*
arg1
=
p1
,
*
arg2
=
p2
;
else
*
arg1
=
p1
,
*
arg2
=
a2
;
break
;
}
case
GT_EXPR
:
case
LT_EXPR
:
case
GE_EXPR
:
case
LE_EXPR
:
case
EQ_EXPR
:
case
NE_EXPR
:
{
tree
a1
,
a2
,
p1
,
p2
;
int
wins
;
a1
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg1
,
0
);
a2
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg2
,
0
);
p1
=
build_expr_type_conversion
(
WANT_POINTER
|
WANT_NULL
,
*
arg1
,
0
);
p2
=
build_expr_type_conversion
(
WANT_POINTER
|
WANT_NULL
,
*
arg2
,
0
);
wins
=
(
a1
&&
a2
)
+
(
p1
&&
p2
);
if
(
wins
>
1
)
cp_error
(
"ambiguous default type conversion for `%O'"
,
code
);
if
(
a1
&&
a2
)
*
arg1
=
a1
,
*
arg2
=
a2
;
else
*
arg1
=
p1
,
*
arg2
=
p2
;
break
;
}
case
TRUTH_ANDIF_EXPR
:
case
TRUTH_ORIF_EXPR
:
*
arg1
=
convert
(
boolean_type_node
,
*
arg1
);
*
arg2
=
convert
(
boolean_type_node
,
*
arg2
);
break
;
default
:
*
arg1
=
NULL_TREE
;
*
arg2
=
NULL_TREE
;
}
return
1
;
if
(
*
arg1
==
error_mark_node
||
*
arg2
==
error_mark_node
)
cp_error
(
"ambiguous default type conversion for `%O'"
,
code
);
if
(
*
arg1
&&
*
arg2
)
return
1
;
return
0
;
}
/* Implements integral promotion (4.1) and float->double promotion. */
...
...
gcc/cp/decl.c
View file @
b7484fbe
...
...
@@ -1664,13 +1664,10 @@ set_nested_typename (decl, classname, name, type)
type_decl
=
build_decl
(
TYPE_DECL
,
nested
,
type
);
DECL_NESTED_TYPENAME
(
type_decl
)
=
nested
;
SET_DECL_ARTIFICIAL
(
type_decl
);
#ifdef DWARF_DEBUGGING_INFO
/* Mark the TYPE_DECL node created just above as a
gratuitous one so that dwarfout.c will know not to
generate a TAG_typedef DIE for it. */
if
(
write_symbols
==
DWARF_DEBUG
)
DECL_IGNORED_P
(
type_decl
)
=
1
;
#endif
/* DWARF_DEBUGGING_INFO */
/* Mark the TYPE_DECL node created just above as a gratuitous one so that
dwarfout.c will know not to generate a TAG_typedef DIE for it, and
sdbout.c won't try to output a .def for "::foo". */
DECL_IGNORED_P
(
type_decl
)
=
1
;
/* Remove this when local classes are fixed. */
SET_IDENTIFIER_TYPE_VALUE
(
nested
,
type
);
...
...
@@ -2447,21 +2444,16 @@ duplicate_decls (newdecl, olddecl)
TREE_TYPE
(
newdecl
)
=
TREE_TYPE
(
olddecl
)
=
newtype
;
/* Lay the type out, unless already done. */
if
(
oldtype
!=
TREE_TYPE
(
newdecl
))
{
if
(
TREE_TYPE
(
newdecl
)
!=
error_mark_node
)
layout_type
(
TREE_TYPE
(
newdecl
));
if
(
TREE_CODE
(
newdecl
)
!=
FUNCTION_DECL
&&
TREE_CODE
(
newdecl
)
!=
TYPE_DECL
&&
TREE_CODE
(
newdecl
)
!=
CONST_DECL
&&
TREE_CODE
(
newdecl
)
!=
TEMPLATE_DECL
)
layout_decl
(
newdecl
,
0
);
}
else
{
/* Since the type is OLDDECL's, make OLDDECL's size go with. */
DECL_SIZE
(
newdecl
)
=
DECL_SIZE
(
olddecl
);
}
if
(
oldtype
!=
TREE_TYPE
(
newdecl
)
&&
TREE_TYPE
(
newdecl
)
!=
error_mark_node
)
layout_type
(
TREE_TYPE
(
newdecl
));
if
(
TREE_CODE
(
newdecl
)
==
VAR_DECL
||
TREE_CODE
(
newdecl
)
==
PARM_DECL
||
TREE_CODE
(
newdecl
)
==
RESULT_DECL
||
TREE_CODE
(
newdecl
)
==
FIELD_DECL
||
TREE_CODE
(
newdecl
)
==
TYPE_DECL
)
layout_decl
(
newdecl
,
0
);
/* Merge the type qualifiers. */
if
(
TREE_READONLY
(
newdecl
))
...
...
@@ -7660,7 +7652,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
TREE_CODE
(
type
)
==
REAL_TYPE
)
error
(
"short, signed or unsigned invalid for `%s'"
,
name
);
else
if
(
TREE_CODE
(
type
)
!=
INTEGER_TYPE
||
type
==
wchar_type_node
)
else
if
(
TREE_CODE
(
type
)
!=
INTEGER_TYPE
)
error
(
"long, short, signed or unsigned invalid for `%s'"
,
name
);
else
if
(
RIDBIT_SETP
(
RID_LONG
,
specbits
)
&&
RIDBIT_SETP
(
RID_SHORT
,
specbits
))
...
...
@@ -7780,6 +7772,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
error
(
"non-object member `%s' cannot be declared `mutable'"
,
name
);
RIDBIT_RESET
(
RID_MUTABLE
,
specbits
);
}
else
if
(
constp
)
{
error
(
"const `%s' cannot be declared `mutable'"
,
name
);
RIDBIT_RESET
(
RID_MUTABLE
,
specbits
);
}
else
if
(
staticp
)
{
error
(
"static `%s' cannot be declared `mutable'"
,
name
);
...
...
@@ -7820,7 +7817,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
/* Give error if `virtual' is used outside of class declaration. */
if
(
virtualp
&&
current_class_name
==
NULL_TREE
)
if
(
virtualp
&&
(
current_class_name
==
NULL_TREE
||
decl_context
!=
FIELD
))
{
error
(
"virtual outside class declaration"
);
virtualp
=
0
;
...
...
@@ -7972,14 +7970,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
{
if
(
decl_context
==
FIELD
)
{
tree
tmp
=
TREE_OPERAND
(
declarator
,
0
);
register
int
op
=
IDENTIFIER_OPNAME_P
(
tmp
);
tree
tmp
=
NULL_TREE
;
register
int
op
=
0
;
if
(
declarator
)
{
tmp
=
TREE_OPERAND
(
declarator
,
0
);
op
=
IDENTIFIER_OPNAME_P
(
tmp
);
}
error
(
"storage class specified for %s `%s'"
,
IS_SIGNATURE
(
current_class_type
)
?
(
op
?
"signature member operator"
:
"signature member function"
)
:
(
op
?
"member operator"
:
"
structure
field"
),
:
(
op
?
"member operator"
:
"field"
),
op
?
operator_name_string
(
tmp
)
:
name
);
}
else
...
...
@@ -8092,6 +8096,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
{
register
tree
itype
=
NULL_TREE
;
register
tree
size
=
TREE_OPERAND
(
declarator
,
1
);
/* The index is a signed object `sizetype' bits wide. */
tree
index_type
=
signed_type
(
sizetype
);
declarator
=
TREE_OPERAND
(
declarator
,
0
);
...
...
@@ -8181,8 +8187,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
cp_error
(
"size of array `%D' is negative"
,
dname
);
size
=
integer_one_node
;
}
itype
=
build_index_type
(
size_binop
(
MINUS_EXPR
,
size
,
integer_one_node
));
}
else
{
...
...
@@ -8194,15 +8198,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
else
cp_pedwarn
(
"ANSI C++ forbids variable-size array"
);
}
dont_grok_size
:
itype
=
build_binary_op
(
MINUS_EXPR
,
size
,
integer_one_node
,
1
);
/* Make sure the array size remains visibly nonconstant
even if it is (eg) a const variable with known value.
*/
even if it is (eg) a const variable with known value. */
size_varies
=
1
;
itype
=
variable_size
(
itype
);
itype
=
build_index_type
(
itype
);
}
dont_grok_size
:
itype
=
fold
(
build_binary_op
(
MINUS_EXPR
,
convert
(
index_type
,
size
),
convert
(
index_type
,
integer_one_node
),
1
));
if
(
!
TREE_CONSTANT
(
itype
))
itype
=
variable_size
(
itype
);
itype
=
build_index_type
(
itype
);
resume_momentary
(
yes
);
}
...
...
@@ -8262,10 +8271,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
inner_decl
&&
TREE_CODE
(
inner_decl
)
==
SCOPE_REF
)
inner_decl
=
TREE_OPERAND
(
inner_decl
,
1
);
/* Pick up type qualifiers which should be applied to `this'. */
quals
=
TREE_OPERAND
(
declarator
,
2
);
/* Say it's a definition only for the CALL_EXPR
closest to the identifier. */
funcdecl_p
=
inner_decl
&&
TREE_CODE
(
inner_decl
)
==
IDENTIFIER_NODE
;
inner_decl
&&
(
TREE_CODE
(
inner_decl
)
==
IDENTIFIER_NODE
||
TREE_CODE
(
inner_decl
)
==
BIT_NOT_EXPR
);
if
(
ctype
==
NULL_TREE
&&
decl_context
==
FIELD
...
...
@@ -8289,14 +8302,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
may not be static. */
if
(
staticp
==
2
)
error
(
"destructor cannot be static member function"
);
if
(
TYPE_READONLY
(
type
))
{
error
(
"destructors cannot be declared `const'"
);
return
void_type_node
;
}
if
(
TYPE_VOLATILE
(
type
))
if
(
quals
)
{
error
(
"destructors cannot be declared `volatile'"
);
error
(
"destructors cannot be declared `
const' or `
volatile'"
);
return
void_type_node
;
}
if
(
decl_context
==
FIELD
)
...
...
@@ -8320,16 +8328,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
pedwarn
(
"constructors cannot be declared virtual"
);
virtualp
=
0
;
}
if
(
TYPE_READONLY
(
type
)
)
if
(
quals
)
{
error
(
"constructors cannot be declared `const'"
);
error
(
"constructors cannot be declared `const'
or `volatile'
"
);
return
void_type_node
;
}
if
(
TYPE_VOLATILE
(
type
))
{
error
(
"constructors cannot be declared `volatile'"
);
return
void_type_node
;
}
{
RID_BIT_TYPE
tmp_bits
;
bcopy
((
void
*
)
&
specbits
,
(
void
*
)
&
tmp_bits
,
sizeof
(
RID_BIT_TYPE
));
...
...
@@ -8358,20 +8361,22 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
decl_context
==
FIELD
)
staticp
=
0
;
}
else
if
(
friendp
&&
virtualp
)
else
if
(
friendp
)
{
/* Cannot be both friend and virtual. */
error
(
"virtual functions cannot be friends"
);
RIDBIT_RESET
(
RID_FRIEND
,
specbits
);
friendp
=
0
;
if
(
initialized
)
error
(
"can't initialize friend function `%s'"
,
name
);
if
(
virtualp
)
{
/* Cannot be both friend and virtual. */
error
(
"virtual functions cannot be friends"
);
RIDBIT_RESET
(
RID_FRIEND
,
specbits
);
friendp
=
0
;
}
}
if
(
decl_context
==
NORMAL
&&
friendp
)
error
(
"friend declaration not in class definition"
);
/* Pick up type qualifiers which should be applied to `this'. */
quals
=
TREE_OPERAND
(
declarator
,
2
);
/* Traditionally, declaring return type float means double. */
if
(
flag_traditional
...
...
@@ -8836,13 +8841,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
/* Special case: "friend class foo" looks like a TYPENAME context. */
if
(
friendp
)
{
/* A friendly class? */
if
(
current_class_type
)
make_friend_class
(
current_class_type
,
TYPE_MAIN_VARIANT
(
type
));
else
error
(
"trying to make class `%s' a friend of global scope"
,
TYPE_NAME_STRING
(
type
));
type
=
void_type_node
;
if
(
volatilep
)
{
cp_error
(
"`volatile' specified for friend class declaration"
);
volatilep
=
0
;
}
if
(
inlinep
)
{
cp_error
(
"`inline' specified for friend class declaration"
);
inlinep
=
0
;
}
/* Only try to do this stuff if we didn't already give up. */
if
(
type
!=
integer_type_node
)
{
/* A friendly class? */
if
(
current_class_type
)
make_friend_class
(
current_class_type
,
TYPE_MAIN_VARIANT
(
type
));
else
error
(
"trying to make class `%s' a friend of global scope"
,
TYPE_NAME_STRING
(
type
));
type
=
void_type_node
;
}
}
else
if
(
quals
)
{
...
...
@@ -8878,7 +8898,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
TYPE_MAIN_VARIANT
(
type
)
==
void_type_node
&&
decl_context
!=
PARM
)
{
if
(
TREE_CODE
(
declarator
)
==
IDENTIFIER_NODE
)
if
(
!
declarator
)
error
(
"unnamed variable or field declared void"
);
else
if
(
TREE_CODE
(
declarator
)
==
IDENTIFIER_NODE
)
{
if
(
IDENTIFIER_OPNAME_P
(
declarator
))
#if 0 /* How could this happen? */
...
...
@@ -8921,6 +8943,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
type
=
build_pointer_type
(
type
);
else
if
(
TREE_CODE
(
type
)
==
OFFSET_TYPE
)
type
=
build_pointer_type
(
type
);
else
if
(
type
==
void_type_node
&&
declarator
)
{
error
(
"declaration of `%s' as void"
,
name
);
return
NULL_TREE
;
}
decl
=
build_decl
(
PARM_DECL
,
declarator
,
type
);
...
...
@@ -9030,7 +9057,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
else
if
(
TYPE_SIZE
(
type
)
==
NULL_TREE
&&
!
staticp
&&
(
TREE_CODE
(
type
)
!=
ARRAY_TYPE
||
initialized
==
0
))
{
cp_error
(
"field `%D' has incomplete type"
,
declarator
);
if
(
declarator
)
cp_error
(
"field `%D' has incomplete type"
,
declarator
);
else
cp_error
(
"name `%T' has incomplete type"
,
type
);
/* If we're instantiating a template, tell them which
instantiation made the field's type be incomplete. */
...
...
@@ -9302,6 +9332,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
staticp
=
0
;
RIDBIT_RESET
(
RID_STATIC
,
specbits
);
}
if
(
RIDBIT_SETP
(
RID_REGISTER
,
specbits
)
&&
TREE_STATIC
(
decl
))
{
cp_error
(
"static member `%D' declared `register'"
,
decl
);
RIDBIT_RESET
(
RID_REGISTER
,
specbits
);
}
if
(
RIDBIT_SETP
(
RID_EXTERN
,
specbits
))
{
cp_error
(
"cannot explicitly declare member `%#D' to have extern linkage"
,
...
...
@@ -9583,7 +9618,8 @@ grokparms (first_parm, funcdef_flag)
any_init
++
;
if
(
TREE_CODE
(
init
)
==
SAVE_EXPR
)
PARM_DECL_EXPR
(
init
)
=
1
;
else
if
(
TREE_CODE
(
init
)
==
VAR_DECL
)
else
if
(
TREE_CODE
(
init
)
==
VAR_DECL
||
TREE_CODE
(
init
)
==
PARM_DECL
)
{
if
(
IDENTIFIER_LOCAL_VALUE
(
DECL_NAME
(
init
)))
{
...
...
@@ -10656,6 +10692,8 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
original_result_rtx
=
NULL_RTX
;
current_function_obstack_index
=
0
;
current_function_obstack_usage
=
0
;
base_init_insns
=
NULL_RTX
;
protect_list
=
NULL_TREE
;
clear_temp_name
();
...
...
@@ -10751,7 +10789,7 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
if
(
TREE_TYPE
(
TREE_TYPE
(
decl1
))
!=
integer_type_node
)
{
if
(
pedantic
||
warn_return_type
)
warning
(
"return type for `main' changed to integer type"
);
pedwarn
(
"return type for `main' changed to integer type"
);
TREE_TYPE
(
decl1
)
=
fntype
=
default_function_type
;
}
warn_about_return_type
=
0
;
...
...
@@ -10795,6 +10833,10 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
DECL_RESULT
(
decl1
)
=
build_decl
(
RESULT_DECL
,
0
,
TREE_TYPE
(
fntype
));
}
if
(
TYPE_LANG_SPECIFIC
(
TREE_TYPE
(
fntype
))
&&
CLASSTYPE_ABSTRACT_VIRTUALS
(
TREE_TYPE
(
fntype
)))
abstract_virtuals_error
(
decl1
,
TREE_TYPE
(
fntype
));
if
(
warn_about_return_type
)
warning
(
"return-type defaults to `int'"
);
...
...
@@ -10824,14 +10866,19 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
DECL_EXTERNAL
(
decl1
)
=
current_extern_inline
;
DECL_INTERFACE_KNOWN
(
decl1
)
=
1
;
}
else
if
(
current_extern_inline
)
{
/* `extern inline' acts like a declaration except for
defining how to inline. So set DECL_EXTERNAL in that case. */
DECL_EXTERNAL
(
decl1
)
=
1
;
DECL_INTERFACE_KNOWN
(
decl1
)
=
1
;
}
else
{
/* This is a definition, not a reference.
So normally clear DECL_EXTERNAL.
However, `extern inline' acts like a declaration except for
defining how to inline. So set DECL_EXTERNAL in that case. */
DECL_EXTERNAL
(
decl1
)
=
current_extern_inline
;
So clear DECL_EXTERNAL. */
DECL_EXTERNAL
(
decl1
)
=
0
;
if
(
DECL_INLINE
(
decl1
)
&&
(
DECL_FUNCTION_MEMBER_P
(
decl1
)
||
DECL_TEMPLATE_INSTANTIATION
(
decl1
)))
/* We know nothing yet */
;
...
...
@@ -11423,6 +11470,7 @@ finish_function (lineno, call_poplevel, nested)
if
(
DECL_CONSTRUCTOR_P
(
current_function_decl
))
{
end_protect_partials
();
expand_label
(
ctor_label
);
ctor_label
=
NULL_TREE
;
...
...
@@ -11503,6 +11551,8 @@ finish_function (lineno, call_poplevel, nested)
if
(
mark
!=
get_last_insn
())
reorder_insns
(
next_insn
(
mark
),
get_last_insn
(),
last_parm_insn
);
end_protect_partials
();
/* This is where the body of the constructor ends. */
expand_label
(
ctor_label
);
ctor_label
=
NULL_TREE
;
...
...
@@ -11643,8 +11693,14 @@ finish_function (lineno, call_poplevel, nested)
/* Run the optimizers and output the assembler code for this function. */
rest_of_compilation
(
fndecl
);
if
(
DECL_DEFER_OUTPUT
(
fndecl
))
mark_inline_for_output
(
fndecl
);
if
(
DECL_SAVED_INSNS
(
fndecl
)
&&
!
TREE_ASM_WRITTEN
(
fndecl
))
{
/* Set DECL_EXTERNAL so that assemble_external will be called as
necessary. We'll clear it again in import_export_inline. */
if
(
TREE_PUBLIC
(
fndecl
))
DECL_EXTERNAL
(
fndecl
)
=
1
;
mark_inline_for_output
(
fndecl
);
}
if
(
ctype
&&
TREE_ASM_WRITTEN
(
fndecl
))
note_debug_info_needed
(
ctype
);
...
...
@@ -12121,7 +12177,9 @@ struct cp_function
tree
shadowed_labels
;
tree
ctor_label
;
tree
dtor_label
;
tree
protect_list
;
rtx
result_rtx
;
rtx
base_init_insns
;
struct
cp_function
*
next
;
struct
binding_level
*
binding_level
;
};
...
...
@@ -12156,6 +12214,8 @@ push_cp_function_context (toplev)
p
->
just_assigned_this
=
current_function_just_assigned_this
;
p
->
parms_stored
=
current_function_parms_stored
;
p
->
result_rtx
=
original_result_rtx
;
p
->
base_init_insns
=
base_init_insns
;
p
->
protect_list
=
protect_list
;
}
/* Restore the variables used during compilation of a C++ function. */
...
...
@@ -12197,10 +12257,12 @@ pop_cp_function_context (toplev)
current_binding_level
=
p
->
binding_level
;
ctor_label
=
p
->
ctor_label
;
dtor_label
=
p
->
dtor_label
;
protect_list
=
p
->
protect_list
;
current_function_assigns_this
=
p
->
assigns_this
;
current_function_just_assigned_this
=
p
->
just_assigned_this
;
current_function_parms_stored
=
p
->
parms_stored
;
original_result_rtx
=
p
->
result_rtx
;
base_init_insns
=
p
->
base_init_insns
;
free
(
p
);
}
gcc/cp/decl2.c
View file @
b7484fbe
...
...
@@ -1027,6 +1027,7 @@ grok_array_decl (array_expr, index_exp)
tree
array_expr
,
index_exp
;
{
tree
type
=
TREE_TYPE
(
array_expr
);
tree
p1
,
p2
,
i1
,
i2
;
if
(
type
==
error_mark_node
||
index_exp
==
error_mark_node
)
return
error_mark_node
;
...
...
@@ -1049,28 +1050,38 @@ grok_array_decl (array_expr, index_exp)
array_expr
,
index_exp
,
NULL_TREE
);
/* Otherwise, create an ARRAY_REF for a pointer or array type. */
if
(
TREE_CODE
(
type
)
==
POINTER_TYPE
||
TREE_CODE
(
type
)
==
ARRAY_TYPE
)
return
build_array_ref
(
array_expr
,
index_exp
);
/* Woops, looks like they did something like `5[a]' instead of `a[5]'.
We don't emit a warning or error for this, since it's allowed
by ARM $8.2.4. */
if
(
TREE_CODE
(
type
)
==
ARRAY_TYPE
)
p1
=
array_expr
;
else
p1
=
build_expr_type_conversion
(
WANT_POINTER
,
array_expr
,
0
);
type
=
TREE_TYPE
(
index_exp
);
if
(
TREE_CODE
(
TREE_TYPE
(
index_exp
))
==
ARRAY_TYPE
)
p2
=
index_exp
;
else
p2
=
build_expr_type_conversion
(
WANT_POINTER
,
index_exp
,
0
);
if
(
TREE_CODE
(
type
)
==
OFFSET_TYPE
||
TREE_CODE
(
type
)
==
REFERENCE_TYPE
)
type
=
TREE_TYPE
(
type
);
i1
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
array_expr
,
0
);
i2
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
index_exp
,
0
);
if
(
TREE_CODE
(
type
)
==
POINTER_TYPE
||
TREE_CODE
(
type
)
==
ARRAY_TYPE
)
return
build_array_ref
(
index_exp
,
array_expr
);
if
((
p1
&&
i2
)
&&
(
i1
&&
p2
))
error
(
"ambiguous conversion for array subscript"
);
/* The expression E1[E2] is identical (by definition) to *((E1)+(E2)). */
return
build_indirect_ref
(
build_binary_op
(
PLUS_EXPR
,
array_expr
,
index_exp
,
1
),
"array indexing"
);
if
(
p1
&&
i2
)
array_expr
=
p1
,
index_exp
=
i2
;
else
if
(
i1
&&
p2
)
array_expr
=
p2
,
index_exp
=
i1
;
else
{
cp_error
(
"invalid types `%T[%T]' for array subscript"
,
type
,
TREE_TYPE
(
index_exp
));
return
error_mark_node
;
}
if
(
array_expr
==
error_mark_node
||
index_exp
==
error_mark_node
)
error
(
"ambiguous conversion for array subscript"
);
return
build_array_ref
(
array_expr
,
index_exp
);
}
/* Given the cast expression EXP, checking out its validity. Either return
...
...
@@ -2487,8 +2498,8 @@ import_export_vtable (decl, type, final)
}
else
{
/* We can only
do this optimization if we have real non-inline
virtual
functions in our class, or if we come from a template. */
/* We can only
wait to decide if we have real non-inline virtual
functions in our class, or if we come from a template. */
int
found
=
CLASSTYPE_TEMPLATE_INSTANTIATION
(
type
);
...
...
@@ -2543,7 +2554,8 @@ finish_prevtable_vardecl (prev, vars)
tree
ctype
=
DECL_CONTEXT
(
vars
);
import_export_template
(
ctype
);
if
(
CLASSTYPE_INTERFACE_UNKNOWN
(
ctype
)
&&
TYPE_VIRTUAL_P
(
ctype
))
if
(
CLASSTYPE_INTERFACE_UNKNOWN
(
ctype
)
&&
TYPE_VIRTUAL_P
(
ctype
)
&&
!
CLASSTYPE_TEMPLATE_INSTANTIATION
(
ctype
))
{
tree
method
;
for
(
method
=
CLASSTYPE_METHODS
(
ctype
);
method
!=
NULL_TREE
;
...
...
@@ -2562,19 +2574,11 @@ finish_prevtable_vardecl (prev, vars)
import_export_vtable
(
vars
,
ctype
,
1
);
if
(
write_virtuals
>=
0
if
(
flag_rtti
&&
write_virtuals
>=
0
&&
!
DECL_EXTERNAL
(
vars
)
&&
(
TREE_PUBLIC
(
vars
)
||
TREE_USED
(
vars
)))
{
extern
tree
the_null_vtable_entry
;
/* Kick out the type descriptor before writing out the vtable. */
if
(
flag_rtti
)
{
build_t_desc
(
ctype
,
1
);
}
/* Write it out. */
mark_vtable_entries
(
vars
);
build_t_desc
(
ctype
,
1
);
}
}
...
...
@@ -2582,39 +2586,13 @@ static void
finish_vtable_vardecl
(
prev
,
vars
)
tree
prev
,
vars
;
{
tree
ctype
=
DECL_CONTEXT
(
vars
);
import_export_template
(
ctype
);
if
(
CLASSTYPE_INTERFACE_UNKNOWN
(
ctype
)
&&
TYPE_VIRTUAL_P
(
ctype
))
{
tree
method
;
for
(
method
=
CLASSTYPE_METHODS
(
ctype
);
method
!=
NULL_TREE
;
method
=
DECL_NEXT_METHOD
(
method
))
{
if
(
DECL_VINDEX
(
method
)
!=
NULL_TREE
&&
!
DECL_SAVED_INSNS
(
method
)
&&
!
DECL_ABSTRACT_VIRTUAL_P
(
method
))
{
SET_CLASSTYPE_INTERFACE_KNOWN
(
ctype
);
CLASSTYPE_VTABLE_NEEDS_WRITING
(
ctype
)
=
!
DECL_EXTERNAL
(
method
);
CLASSTYPE_INTERFACE_ONLY
(
ctype
)
=
DECL_EXTERNAL
(
method
);
if
(
flag_rtti
)
cp_warning
(
"compiler error: rtti entry for `%T' decided too late"
,
ctype
);
break
;
}
}
}
import_export_vtable
(
vars
,
ctype
,
1
);
if
(
write_virtuals
>=
0
&&
!
DECL_EXTERNAL
(
vars
)
&&
(
TREE_PUBLIC
(
vars
)
||
TREE_USED
(
vars
)))
{
extern
tree
the_null_vtable_entry
;
/* Write it out. */
mark_vtable_entries
(
vars
);
if
(
TREE_TYPE
(
DECL_INITIAL
(
vars
))
==
0
)
store_init_value
(
vars
,
DECL_INITIAL
(
vars
));
store_init_value
(
vars
,
DECL_INITIAL
(
vars
));
#ifdef DWARF_DEBUGGING_INFO
if
(
write_symbols
==
DWARF_DEBUG
)
...
...
@@ -2646,8 +2624,18 @@ finish_vtable_vardecl (prev, vars)
rest_of_decl_compilation
(
vars
,
NULL_PTR
,
1
,
1
);
}
else
if
(
TREE_USED
(
vars
))
assemble_external
(
vars
);
else
if
(
!
TREE_USED
(
vars
))
/* We don't know what to do with this one yet. */
return
;
/* We know that PREV must be non-zero here. */
TREE_CHAIN
(
prev
)
=
TREE_CHAIN
(
vars
);
}
static
void
prune_vtable_vardecl
(
prev
,
vars
)
tree
prev
,
vars
;
{
/* We know that PREV must be non-zero here. */
TREE_CHAIN
(
prev
)
=
TREE_CHAIN
(
vars
);
}
...
...
@@ -2731,6 +2719,8 @@ import_export_inline (decl)
if
(
DECL_INTERFACE_KNOWN
(
decl
))
return
;
DECL_EXTERNAL
(
decl
)
=
0
;
if
(
DECL_TEMPLATE_INSTANTIATION
(
decl
))
{
if
(
DECL_IMPLICIT_INSTANTIATION
(
decl
)
&&
flag_implicit_templates
)
...
...
@@ -2773,7 +2763,6 @@ finish_file ()
tree
fnname
;
tree
vars
=
static_aggregates
;
int
needs_cleaning
=
0
,
needs_messing_up
=
0
;
int
have_exception_handlers
=
build_exception_table
();
if
(
flag_detailed_statistics
)
dump_tree_statistics
();
...
...
@@ -2788,7 +2777,7 @@ finish_file ()
we'll need here. */
push_lang_context
(
lang_name_c
);
if
(
static_ctors
||
vars
||
have_exception_handlers
)
if
(
static_ctors
||
vars
||
might_have_exceptions_p
()
)
needs_messing_up
=
1
;
if
(
static_dtors
)
needs_cleaning
=
1
;
...
...
@@ -2900,7 +2889,7 @@ finish_file ()
push_momentary
();
expand_start_bindings
(
0
);
if
(
have_exception_handlers
)
if
(
might_have_exceptions_p
()
)
register_exception_table
();
while
(
vars
)
...
...
@@ -2931,6 +2920,7 @@ finish_file ()
/* 9.5p5: The initializer of a static member of a class has
the same acess rights as a member function. */
DECL_CLASS_CONTEXT
(
current_function_decl
)
=
DECL_CONTEXT
(
decl
);
DECL_STATIC_FUNCTION_P
(
current_function_decl
)
=
1
;
#if 0
if (init)
...
...
@@ -3061,30 +3051,9 @@ finish_file ()
pushdecl
(
vars
);
#endif
walk_vtables
((
void
(
*
)())
0
,
finish_vtable_vardecl
);
if
(
flag_handle_signatures
)
walk_sigtables
((
void
(
*
)())
0
,
finish_sigtable_vardecl
);
for
(
vars
=
saved_inlines
;
vars
;
vars
=
TREE_CHAIN
(
vars
))
{
tree
decl
=
TREE_VALUE
(
vars
);
if
(
DECL_ARTIFICIAL
(
decl
)
&&
!
DECL_INITIAL
(
decl
)
&&
TREE_USED
(
decl
))
synthesize_method
(
decl
);
}
for
(
vars
=
getdecls
();
vars
;
vars
=
TREE_CHAIN
(
vars
))
{
if
(
TREE_CODE
(
vars
)
==
THUNK_DECL
)
emit_thunk
(
vars
);
else
if
(
TREE_CODE
(
vars
)
==
FUNCTION_DECL
&&
!
DECL_INTERFACE_KNOWN
(
vars
)
&&
DECL_DECLARED_STATIC
(
vars
))
TREE_PUBLIC
(
vars
)
=
0
;
}
/* Now write out inline functions which had their addresses taken and
which were not declared virtual and which were not declared `extern
inline'. */
...
...
@@ -3098,10 +3067,23 @@ finish_file ()
tree
place
=
TREE_CHAIN
(
saved_inlines
);
reconsider
=
0
;
walk_vtables
((
void
(
*
)())
0
,
finish_vtable_vardecl
);
for
(;
place
;
place
=
TREE_CHAIN
(
place
))
{
tree
decl
=
TREE_VALUE
(
place
);
if
(
DECL_ARTIFICIAL
(
decl
)
&&
!
DECL_INITIAL
(
decl
))
{
if
(
TREE_USED
(
decl
))
synthesize_method
(
decl
);
else
{
last
=
place
;
continue
;
}
}
if
(
TREE_ASM_WRITTEN
(
decl
)
||
DECL_SAVED_INSNS
(
decl
)
==
0
)
{
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
...
...
@@ -3114,9 +3096,7 @@ finish_file ()
{
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
if
(
DECL_EXTERNAL
(
decl
))
assemble_external
(
decl
);
else
if
(
!
DECL_EXTERNAL
(
decl
))
{
reconsider
=
1
;
temporary_allocation
();
...
...
@@ -3132,6 +3112,21 @@ finish_file ()
}
}
walk_vtables
((
void
(
*
)())
0
,
prune_vtable_vardecl
);
for
(
vars
=
getdecls
();
vars
;
vars
=
TREE_CHAIN
(
vars
))
{
if
(
TREE_CODE
(
vars
)
==
THUNK_DECL
)
emit_thunk
(
vars
);
else
if
(
TREE_CODE
(
vars
)
==
FUNCTION_DECL
&&
!
DECL_INTERFACE_KNOWN
(
vars
)
&&
DECL_DECLARED_STATIC
(
vars
))
TREE_PUBLIC
(
vars
)
=
0
;
}
if
(
might_have_exceptions_p
())
emit_exception_table
();
if
(
write_virtuals
==
2
)
{
/* Now complain about an virtual function tables promised
...
...
gcc/cp/error.c
View file @
b7484fbe
...
...
@@ -585,7 +585,7 @@ dump_decl (t, v)
break
;
case
VAR_DECL
:
if
(
VTABLE_NAME_P
(
DECL_NAME
(
t
)))
if
(
DECL_NAME
(
t
)
&&
VTABLE_NAME_P
(
DECL_NAME
(
t
)))
{
OB_PUTS
(
"vtable for "
);
dump_type
(
DECL_CONTEXT
(
t
),
v
);
...
...
@@ -933,9 +933,16 @@ dump_expr (t, nop)
char
*
p
=
enum_name_string
(
t
,
type
);
OB_PUTCP
(
p
);
}
else
if
(
type
==
char_type_node
||
type
==
signed_char_type_node
||
type
==
unsigned_char_type_node
)
else
if
(
type
==
boolean_type_node
)
{
if
(
t
==
boolean_false_node
)
OB_PUTS
(
"false"
);
else
if
(
t
==
boolean_true_node
)
OB_PUTS
(
"true"
);
else
my_friendly_abort
(
366
);
}
else
if
(
type
==
char_type_node
)
{
OB_PUTC
(
'\''
);
dump_char
(
TREE_INT_CST_LOW
(
t
));
...
...
gcc/cp/except.c
View file @
b7484fbe
...
...
@@ -31,6 +31,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "obstack.h"
#include "expr.h"
tree
protect_list
;
extern
void
(
*
interim_eh_hook
)
PROTO
((
tree
));
/* holds the fndecl for __builtin_return_address () */
...
...
@@ -53,6 +55,11 @@ tree builtin_return_address_fndecl;
#define __mips
#endif
#endif
#ifdef __i386__
#ifndef __i386
#define __i386
#endif
#endif
#if defined(__i386) || defined(__rs6000) || defined(__hppa) || defined(__mc68000) || defined (__mips) || defined (__arm) || defined (__alpha)
#define TRY_NEW_EH
#endif
...
...
@@ -872,11 +879,13 @@ void
end_protect
(
finalization
)
tree
finalization
;
{
struct
ehEntry
*
entry
=
pop_eh_entry
(
&
ehstack
)
;
struct
ehEntry
*
entry
;
if
(
!
doing_eh
(
0
))
return
;
entry
=
pop_eh_entry
(
&
ehstack
);
emit_label
(
entry
->
end_label
);
entry
->
finalization
=
finalization
;
...
...
@@ -1574,11 +1583,29 @@ expand_throw (exp)
/* end of: my-cp-except.c */
#endif
void
end_protect_partials
()
{
while
(
protect_list
)
{
end_protect
(
TREE_VALUE
(
protect_list
));
protect_list
=
TREE_CHAIN
(
protect_list
);
}
}
int
might_have_exceptions_p
()
{
#ifdef TRY_NEW_EH
if
(
eh_table_output_queue
.
head
)
return
1
;
#endif
return
0
;
}
/* Output the exception table.
Return the number of handlers. */
int
build
_exception_table
()
void
emit
_exception_table
()
{
int
count
=
0
;
#ifdef TRY_NEW_EH
...
...
@@ -1587,7 +1614,15 @@ build_exception_table ()
tree
eh_node_decl
;
if
(
!
doing_eh
(
0
))
return
0
;
return
;
exception_section
();
/* Beginning marker for table. */
ASM_OUTPUT_ALIGN
(
asm_out_file
,
2
);
ASM_OUTPUT_LABEL
(
asm_out_file
,
"__EXCEPTION_TABLE__"
);
output_exception_table_entry
(
asm_out_file
,
const0_rtx
,
const0_rtx
,
const0_rtx
);
while
(
entry
=
dequeue_eh_entry
(
&
eh_table_output_queue
))
{
...
...
@@ -1596,32 +1631,18 @@ build_exception_table ()
if
(
context
&&
!
TREE_ASM_WRITTEN
(
context
))
continue
;
if
(
count
==
0
)
{
exception_section
();
/* Beginning marker for table. */
ASM_OUTPUT_ALIGN
(
asm_out_file
,
2
);
ASM_OUTPUT_LABEL
(
asm_out_file
,
"__EXCEPTION_TABLE__"
);
output_exception_table_entry
(
asm_out_file
,
const0_rtx
,
const0_rtx
,
const0_rtx
);
}
count
++
;
output_exception_table_entry
(
asm_out_file
,
entry
->
start_label
,
entry
->
end_label
,
entry
->
exception_handler_label
);
}
if
(
count
)
{
/* Ending marker for table. */
ASM_OUTPUT_LABEL
(
asm_out_file
,
"__EXCEPTION_END__"
);
output_exception_table_entry
(
asm_out_file
,
constm1_rtx
,
constm1_rtx
,
constm1_rtx
);
}
/* Ending marker for table. */
ASM_OUTPUT_LABEL
(
asm_out_file
,
"__EXCEPTION_END__"
);
output_exception_table_entry
(
asm_out_file
,
constm1_rtx
,
constm1_rtx
,
constm1_rtx
);
#endif
/* TRY_NEW_EH */
return
count
;
}
void
...
...
gcc/cp/init.c
View file @
b7484fbe
...
...
@@ -157,8 +157,8 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
/* 348 - 351 */
/* Subroutine of emit_base_init. */
static
void
perform_member_init
(
member
,
name
,
init
,
explicit
)
tree
member
,
name
,
init
;
perform_member_init
(
member
,
name
,
init
,
explicit
,
protect_list
)
tree
member
,
name
,
init
,
*
protect_list
;
int
explicit
;
{
tree
decl
;
...
...
@@ -223,27 +223,44 @@ perform_member_init (member, name, init, explicit)
}
}
expand_cleanups_to
(
NULL_TREE
);
if
(
flag_handle_exceptions
&&
TYPE_NEEDS_DESTRUCTOR
(
type
))
cp_warning
(
"caution, member `%D' may not be destroyed in the presense of an exception during construction"
,
member
);
if
(
TYPE_NEEDS_DESTRUCTOR
(
type
))
{
tree
expr
=
build_component_ref
(
C_C_D
,
name
,
0
,
explicit
);
expr
=
build_delete
(
type
,
expr
,
integer_zero_node
,
LOOKUP_NONVIRTUAL
|
LOOKUP_DESTRUCTOR
,
0
);
if
(
expr
!=
error_mark_node
)
{
start_protect
();
*
protect_list
=
tree_cons
(
NULL_TREE
,
expr
,
*
protect_list
);
}
}
}
extern
int
warn_reorder
;
/* Subroutine of emit_member_init. */
static
tree
sort_member_init
(
t
)
tree
t
;
{
extern
int
warn_reorder
;
tree
x
,
member
,
name
,
field
,
init
;
tree
init_list
=
NULL_TREE
;
tree
fields_to_unmark
=
NULL_TREE
;
int
found
;
int
last_pos
=
0
;
tree
last_field
;
for
(
member
=
TYPE_FIELDS
(
t
);
member
;
member
=
TREE_CHAIN
(
member
))
{
int
pos
;
found
=
0
;
/* member could be, for example, a CONST_DECL for an enumerated
tag; we don't want to try to initialize that, since it already
has a value. */
if
(
TREE_CODE
(
member
)
!=
FIELD_DECL
||
!
DECL_NAME
(
member
))
continue
;
for
(
x
=
current_member_init_list
,
pos
=
0
;
x
;
x
=
TREE_CHAIN
(
x
),
++
pos
)
{
/* If we cleared this out, then pay no attention to it. */
...
...
@@ -266,17 +283,9 @@ sort_member_init (t)
if
(
field
==
member
)
{
/* See if we already found an initializer for this field. */
if
(
found
)
{
if
(
DECL_NAME
(
field
))
cp_error
(
"multiple initializations given for member `%D'"
,
field
);
continue
;
}
else
if
(
warn_reorder
)
{
if
(
pos
<
last_pos
&&
warn_reorder
)
if
(
pos
<
last_pos
)
{
cp_warning_at
(
"member initializers for `%#D'"
,
last_field
);
cp_warning_at
(
" and `%#D'"
,
field
);
...
...
@@ -286,78 +295,193 @@ sort_member_init (t)
last_field
=
field
;
}
init_list
=
chainon
(
init_list
,
build_tree_list
(
name
,
TREE_VALUE
(
x
)));
/* Make sure we won't try to work on this init again. */
TREE_PURPOSE
(
x
)
=
NULL_TREE
;
found
=
1
;
break
;
x
=
build_tree_list
(
name
,
TREE_VALUE
(
x
))
;
goto
got_it
;
}
}
/* If we didn't find MEMBER in the list, create a dummy entry
so the two lists (INIT_LIST and the list of members) will be
symmetrical. */
if
(
!
found
)
init_list
=
chainon
(
init_list
,
build_tree_list
(
NULL_TREE
,
NULL_TREE
));
x
=
build_tree_list
(
NULL_TREE
,
NULL_TREE
);
got_it
:
init_list
=
chainon
(
init_list
,
x
);
}
/* Initializers for base members go at the end. */
for
(
x
=
current_member_init_list
;
x
;
x
=
TREE_CHAIN
(
x
))
{
if
(
TREE_PURPOSE
(
x
))
name
=
TREE_PURPOSE
(
x
);
if
(
name
)
{
name
=
TREE_PURPOSE
(
x
);
init
=
TREE_VALUE
(
x
);
/* XXX: this may need the COMPONENT_REF operand 0 check if
it turns out we actually get them. */
field
=
IDENTIFIER_CLASS_VALUE
(
name
);
/* If one member shadows another, get the outermost one. */
if
(
TREE_CODE
(
field
)
==
TREE_LIST
)
if
(
purpose_member
(
name
,
init_list
))
{
field
=
TREE_VALUE
(
field
);
if
(
decl_type_context
(
field
)
!=
current_class_type
)
cp_error
(
"field `%D' not in immediate context"
,
field
)
;
cp_error
(
"multiple initializations given for member `%D'"
,
IDENTIFIER_CLASS_VALUE
(
name
));
continue
;
}
init_list
=
chainon
(
init_list
,
build_tree_list
(
name
,
TREE_VALUE
(
x
)));
TREE_PURPOSE
(
x
)
=
NULL_TREE
;
}
}
#if 0
/* It turns out if you have an anonymous union in the
class, a member from it can end up not being on the
list of fields (rather, the type is), and therefore
won't be seen by the for loop above. */
return
init_list
;
}
/* The code in this for loop is derived from a general loop
which had this check in it. Theoretically, we've hit
every initialization for the list of members in T, so
we shouldn't have anything but these left in this list. */
my_friendly_assert (DECL_FIELD_CONTEXT (field) != t, 351);
#endif
static
void
sort_base_init
(
t
,
rbase_ptr
,
vbase_ptr
)
tree
t
,
*
rbase_ptr
,
*
vbase_ptr
;
{
tree
binfos
=
BINFO_BASETYPES
(
TYPE_BINFO
(
t
));
int
n_baseclasses
=
binfos
?
TREE_VEC_LENGTH
(
binfos
)
:
0
;
int
i
;
tree
x
;
tree
last
;
/* For warn_reorder. */
int
last_pos
=
0
;
tree
last_base
=
NULL_TREE
;
tree
rbases
=
NULL_TREE
;
tree
vbases
=
NULL_TREE
;
if
(
TREE_HAS_CONSTRUCTOR
(
field
))
/* First walk through and splice out vbase and invalid initializers.
Also replace names with binfos. */
last
=
tree_cons
(
NULL_TREE
,
NULL_TREE
,
current_base_init_list
);
for
(
x
=
TREE_CHAIN
(
last
);
x
;
x
=
TREE_CHAIN
(
x
))
{
tree
basename
=
TREE_PURPOSE
(
x
);
tree
binfo
;
if
(
basename
==
NULL_TREE
)
{
/* Initializer for single base class. Must not
use multiple inheritance or this is ambiguous. */
switch
(
n_baseclasses
)
{
if
(
DECL_NAME
(
field
))
error
(
"multiple initializations given for member `%s'"
,
IDENTIFIER_POINTER
(
DECL_NAME
(
field
)));
continue
;
case
0
:
cp_error
(
"`%T' does not have a base class to initialize"
,
current_class_type
);
return
;
case
1
:
break
;
default
:
cp_error
(
"unnamed initializer ambiguous for `%T' which uses multiple inheritance"
,
current_class_type
);
return
;
}
binfo
=
TREE_VEC_ELT
(
binfos
,
0
);
}
else
if
(
is_aggr_typedef
(
basename
,
1
))
{
binfo
=
binfo_or_else
(
IDENTIFIER_TYPE_VALUE
(
basename
),
t
);
if
(
binfo
==
NULL_TREE
)
continue
;
TREE_HAS_CONSTRUCTOR
(
field
)
=
1
;
fields_to_unmark
=
tree_cons
(
NULL_TREE
,
field
,
fields_to_unmark
);
/* Virtual base classes are special cases. Their initializers
are recorded with this constructor, and they are used when
this constructor is the top-level constructor called. */
if
(
TREE_VIA_VIRTUAL
(
binfo
))
{
tree
v
=
CLASSTYPE_VBASECLASSES
(
t
);
while
(
BINFO_TYPE
(
v
)
!=
BINFO_TYPE
(
binfo
))
v
=
TREE_CHAIN
(
v
);
perform_member_init
(
field
,
name
,
init
,
1
);
TREE_PURPOSE
(
x
)
=
NULL_TREE
;
vbases
=
tree_cons
(
v
,
TREE_VALUE
(
x
),
vbases
);
continue
;
}
else
{
/* Otherwise, if it is not an immediate base class, complain. */
for
(
i
=
n_baseclasses
-
1
;
i
>=
0
;
i
--
)
if
(
BINFO_TYPE
(
binfo
)
==
BINFO_TYPE
(
TREE_VEC_ELT
(
binfos
,
i
)))
break
;
if
(
i
<
0
)
{
cp_error
(
"`%T' is not an immediate base class of `%T'"
,
IDENTIFIER_TYPE_VALUE
(
basename
),
current_class_type
);
continue
;
}
}
}
else
my_friendly_abort
(
365
);
TREE_PURPOSE
(
x
)
=
binfo
;
TREE_CHAIN
(
last
)
=
x
;
last
=
x
;
}
TREE_CHAIN
(
last
)
=
NULL_TREE
;
/* Unmark fields which are initialized for the base class. */
while
(
fields_to_unmark
)
/* Now walk through our regular bases and make sure they're initialized. */
for
(
i
=
0
;
i
<
n_baseclasses
;
++
i
)
{
TREE_HAS_CONSTRUCTOR
(
TREE_VALUE
(
fields_to_unmark
))
=
0
;
/* XXX is this a memory leak? */
fields_to_unmark
=
TREE_CHAIN
(
fields_to_unmark
);
tree
base_binfo
=
TREE_VEC_ELT
(
binfos
,
i
);
int
pos
;
if
(
TREE_VIA_VIRTUAL
(
base_binfo
))
continue
;
for
(
x
=
current_base_init_list
,
pos
=
0
;
x
;
x
=
TREE_CHAIN
(
x
),
++
pos
)
{
tree
binfo
=
TREE_PURPOSE
(
x
);
if
(
binfo
==
NULL_TREE
)
continue
;
if
(
binfo
==
base_binfo
)
{
if
(
warn_reorder
)
{
if
(
pos
<
last_pos
)
{
cp_warning_at
(
"base initializers for `%#T'"
,
last_base
);
cp_warning_at
(
" and `%#T'"
,
BINFO_TYPE
(
binfo
));
warning
(
" will be re-ordered to match inheritance order"
);
}
last_pos
=
pos
;
last_base
=
BINFO_TYPE
(
binfo
);
}
/* Make sure we won't try to work on this init again. */
TREE_PURPOSE
(
x
)
=
NULL_TREE
;
x
=
build_tree_list
(
binfo
,
TREE_VALUE
(
x
));
goto
got_it
;
}
}
/* If we didn't find BASE_BINFO in the list, create a dummy entry
so the two lists (RBASES and the list of bases) will be
symmetrical. */
x
=
build_tree_list
(
NULL_TREE
,
NULL_TREE
);
got_it
:
rbases
=
chainon
(
rbases
,
x
);
}
return
init_list
;
*
rbase_ptr
=
rbases
;
*
vbase_ptr
=
vbases
;
}
/* Perform partial cleanups for a base for exception handling. */
static
tree
build_partial_cleanup_for
(
binfo
)
tree
binfo
;
{
tree
expr
=
convert_pointer_to_real
(
binfo
,
build_unary_op
(
ADDR_EXPR
,
C_C_D
,
0
));
return
build_delete
(
TREE_TYPE
(
expr
),
expr
,
integer_zero_node
,
LOOKUP_NONVIRTUAL
|
LOOKUP_DESTRUCTOR
,
0
);
}
/* Perform whatever initializations have yet to be done on the base
...
...
@@ -385,13 +509,14 @@ emit_base_init (t, immediately)
{
extern
tree
in_charge_identifier
;
tree
member
,
vbases
;
tree
init_list
;
int
pass
,
star
t
;
tree
member
,
x
;
tree
mem_
init_list
;
tree
rbase_init_list
,
vbase_init_lis
t
;
tree
t_binfo
=
TYPE_BINFO
(
t
);
tree
binfos
=
BINFO_BASETYPES
(
t_binfo
);
int
i
,
n_baseclasses
=
binfos
?
TREE_VEC_LENGTH
(
binfos
)
:
0
;
int
have_init_list
=
0
,
from_init_list
;
my_friendly_assert
(
protect_list
==
NULL_TREE
,
999
);
if
(
!
immediately
)
{
...
...
@@ -407,172 +532,31 @@ emit_base_init (t, immediately)
emit_line_note_force
(
DECL_SOURCE_FILE
(
current_function_decl
),
DECL_SOURCE_LINE
(
current_function_decl
));
start
=
!
TYPE_USES_VIRTUAL_BASECLASSES
(
t
);
for
(
pass
=
start
;
pass
<
2
;
pass
++
)
{
tree
vbase_init_list
=
NULL_TREE
;
for
(
init_list
=
current_base_init_list
;
init_list
;
init_list
=
TREE_CHAIN
(
init_list
))
{
tree
basename
=
TREE_PURPOSE
(
init_list
);
tree
binfo
;
tree
init
=
TREE_VALUE
(
init_list
);
if
(
basename
==
NULL_TREE
)
{
/* Initializer for single base class. Must not
use multiple inheritance or this is ambiguous. */
switch
(
n_baseclasses
)
{
case
0
:
cp_error
(
"`%T' does not have a base class to initialize"
,
current_class_type
);
return
;
case
1
:
break
;
default
:
cp_error
(
"unnamed initializer ambiguous for `%T' which uses multiple inheritance"
,
current_class_type
);
return
;
}
binfo
=
TREE_VEC_ELT
(
binfos
,
0
);
}
else
if
(
is_aggr_typedef
(
basename
,
1
))
{
binfo
=
binfo_or_else
(
IDENTIFIER_TYPE_VALUE
(
basename
),
t
);
if
(
binfo
==
NULL_TREE
)
continue
;
/* Virtual base classes are special cases. Their initializers
are recorded with this constructor, and they are used when
this constructor is the top-level constructor called. */
if
(
!
TREE_VIA_VIRTUAL
(
binfo
))
{
/* Otherwise, if it is not an immediate base class, complain. */
for
(
i
=
n_baseclasses
-
1
;
i
>=
0
;
i
--
)
if
(
BINFO_TYPE
(
binfo
)
==
BINFO_TYPE
(
TREE_VEC_ELT
(
binfos
,
i
)))
break
;
if
(
i
<
0
)
{
cp_error
(
"`%T' is not an immediate base class of `%T'"
,
IDENTIFIER_TYPE_VALUE
(
basename
),
current_class_type
);
continue
;
}
}
}
else
continue
;
/* The base initialization list goes up to the first
base class which can actually use it. */
if
(
pass
==
start
)
{
char
*
msgp
=
(
!
TYPE_HAS_CONSTRUCTOR
(
BINFO_TYPE
(
binfo
)))
?
"cannot pass initialization up to class `%s'"
:
0
;
while
(
!
TYPE_HAS_CONSTRUCTOR
(
BINFO_TYPE
(
binfo
))
&&
BINFO_BASETYPES
(
binfo
)
!=
NULL_TREE
&&
TREE_VEC_LENGTH
(
BINFO_BASETYPES
(
binfo
))
==
1
)
{
/* ?? This should be fixed in RENO by forcing
default constructors to exist. */
SET_BINFO_BASEINIT_MARKED
(
binfo
);
binfo
=
BINFO_BASETYPE
(
binfo
,
0
);
}
/* We used to give an error if this wasn't true, saying that
there's no constructor for the initialization of basename.
This turned out to be incorrect---it should use the
default constructor, since a user could try to initialize
the class in a derived class's base initializer list. */
if
(
TYPE_HAS_CONSTRUCTOR
(
BINFO_TYPE
(
binfo
)))
{
if
(
msgp
)
{
if
(
pedantic
)
error_with_aggr_type
(
binfo
,
msgp
);
else
msgp
=
NULL
;
}
}
if
(
BINFO_BASEINIT_MARKED
(
binfo
))
{
msgp
=
"class `%s' initializer already specified"
;
error
(
msgp
,
IDENTIFIER_POINTER
(
basename
));
}
if
(
msgp
)
continue
;
SET_BINFO_BASEINIT_MARKED
(
binfo
);
if
(
TREE_VIA_VIRTUAL
(
binfo
))
{
vbase_init_list
=
tree_cons
(
init
,
BINFO_TYPE
(
binfo
),
vbase_init_list
);
continue
;
}
if
(
pass
==
0
)
continue
;
}
else
if
(
TREE_VIA_VIRTUAL
(
binfo
))
continue
;
mem_init_list
=
sort_member_init
(
t
);
current_member_init_list
=
NULL_TREE
;
member
=
convert_pointer_to
(
binfo
,
current_class_decl
);
expand_aggr_init_1
(
binfo
,
0
,
build_indirect_ref
(
member
,
NULL_PTR
),
init
,
BINFO_OFFSET_ZEROP
(
binfo
),
LOOKUP_NORMAL
);
expand_cleanups_to
(
NULL_TREE
);
}
sort_base_init
(
t
,
&
rbase_init_list
,
&
vbase_init_list
);
current_base_init_list
=
NULL_TREE
;
if
(
pass
==
0
)
{
tree
first_arg
=
TREE_CHAIN
(
DECL_ARGUMENTS
(
current_function_decl
));
tree
vbases
;
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
t
))
{
tree
first_arg
=
TREE_CHAIN
(
DECL_ARGUMENTS
(
current_function_decl
));
if
(
DECL_NAME
(
current_function_decl
)
==
NULL_TREE
&&
TREE_CHAIN
(
first_arg
)
!=
NULL_TREE
)
{
/* If there are virtual baseclasses without initialization
specified, and this is a default X(X&) constructor,
build the initialization list so that each virtual baseclass
of the new object is initialized from the virtual baseclass
of the incoming arg. */
tree
init_arg
=
build_unary_op
(
ADDR_EXPR
,
TREE_CHAIN
(
first_arg
),
0
);
for
(
vbases
=
CLASSTYPE_VBASECLASSES
(
t
);
vbases
;
vbases
=
TREE_CHAIN
(
vbases
))
{
if
(
BINFO_BASEINIT_MARKED
(
vbases
)
==
0
)
{
member
=
convert_pointer_to
(
vbases
,
init_arg
);
if
(
member
==
init_arg
)
member
=
TREE_CHAIN
(
first_arg
);
else
TREE_TYPE
(
member
)
=
build_reference_type
(
BINFO_TYPE
(
vbases
));
vbase_init_list
=
tree_cons
(
convert_from_reference
(
member
),
vbases
,
vbase_init_list
);
SET_BINFO_BASEINIT_MARKED
(
vbases
);
}
}
}
expand_start_cond
(
first_arg
,
0
);
expand_aggr_vbase_init
(
t_binfo
,
C_C_D
,
current_class_decl
,
vbase_init_list
);
expand_end_cond
();
}
expand_start_cond
(
first_arg
,
0
);
expand_aggr_vbase_init
(
t_binfo
,
C_C_D
,
current_class_decl
,
vbase_init_list
);
expand_end_cond
();
}
current_base_init_list
=
NULL_TREE
;
/* Now, perform default initialization of all base classes which
have not yet been initialized, and unmark baseclasses which
have been initialized. */
/* Now, perform initialization of non-virtual base classes. */
for
(
i
=
0
;
i
<
n_baseclasses
;
i
++
)
{
tree
base
=
current_class_decl
;
tree
base_binfo
=
TREE_VEC_ELT
(
binfos
,
i
);
tree
init
=
void_list_node
;
if
(
TREE_VIA_VIRTUAL
(
base_binfo
))
continue
;
#if 0 /* Once unsharing happens soon enough. */
my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo);
...
...
@@ -580,109 +564,113 @@ emit_base_init (t, immediately)
BINFO_INHERITANCE_CHAIN
(
base_binfo
)
=
t_binfo
;
#endif
if
(
TYPE_NEEDS_CONSTRUCTING
(
BINFO_TYPE
(
base_binfo
)))
{
if
(
!
TREE_VIA_VIRTUAL
(
base_binfo
)
&&
!
BINFO_BASEINIT_MARKED
(
base_binfo
))
{
tree
ref
;
if
(
TREE_PURPOSE
(
rbase_init_list
))
init
=
TREE_VALUE
(
rbase_init_list
);
else
if
(
TYPE_NEEDS_CONSTRUCTING
(
BINFO_TYPE
(
base_binfo
)))
init
=
NULL_TREE
;
if
(
BINFO_OFFSET_ZEROP
(
base_binfo
))
base
=
build1
(
NOP_EXPR
,
TYPE_POINTER_TO
(
BINFO_TYPE
(
base_binfo
)),
current_class_decl
);
else
base
=
build
(
PLUS_EXPR
,
TYPE_POINTER_TO
(
BINFO_TYPE
(
base_binfo
)),
current_class_decl
,
BINFO_OFFSET
(
base_binfo
));
ref
=
build_indirect_ref
(
base
,
NULL_PTR
);
expand_aggr_init_1
(
base_binfo
,
0
,
ref
,
NULL_TREE
,
BINFO_OFFSET_ZEROP
(
base_binfo
),
LOOKUP_NORMAL
);
expand_cleanups_to
(
NULL_TREE
);
}
if
(
init
!=
void_list_node
)
{
member
=
convert_pointer_to
(
base_binfo
,
current_class_decl
);
expand_aggr_init_1
(
base_binfo
,
0
,
build_indirect_ref
(
member
,
NULL_PTR
),
init
,
BINFO_OFFSET_ZEROP
(
base_binfo
),
LOOKUP_NORMAL
);
expand_cleanups_to
(
NULL_TREE
);
}
CLEAR_BINFO_BASEINIT_MARKED
(
base_binfo
);
if
(
!
TYPE_USES_VIRTUAL_BASECLASSES
(
t
))
if
(
TYPE_NEEDS_DESTRUCTOR
(
BINFO_TYPE
(
base_binfo
)
))
{
while
(
!
TYPE_HAS_CONSTRUCTOR
(
BINFO_TYPE
(
base_binfo
))
&&
BINFO_BASETYPES
(
base_binfo
)
!=
NULL_TREE
&&
TREE_VEC_LENGTH
(
BINFO_BASETYPES
(
base_binfo
))
==
1
)
{
/* ?? This should be fixed in RENO by forcing
default constructors to exist. It is needed for symmetry
with code above. */
base_binfo
=
BINFO_BASETYPE
(
base_binfo
,
0
);
CLEAR_BINFO_BASEINIT_MARKED
(
base_binfo
);
}
start_protect
();
protect_list
=
tree_cons
(
NULL_TREE
,
build_partial_cleanup_for
(
base_binfo
),
protect_list
);
}
rbase_init_list
=
TREE_CHAIN
(
rbase_init_list
);
}
/* Initialize all the virtual function table fields that
do come from virtual base classes. */
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
t
))
expand_indirect_vtbls_init
(
t_binfo
,
C_C_D
,
current_class_decl
,
0
);
for
(
vbases
=
CLASSTYPE_VBASECLASSES
(
t
);
vbases
;
vbases
=
TREE_CHAIN
(
vbases
))
CLEAR_BINFO_BASEINIT_MARKED
(
vbases
);
/* Initialize all the virtual function table fields that
do not come from virtual base classes. */
expand_direct_vtbls_init
(
t_binfo
,
t_binfo
,
1
,
1
,
current_class_decl
);
if
(
current_member_init_list
)
{
init_list
=
sort_member_init
(
t
);
have_init_list
=
1
;
}
for
(
member
=
TYPE_FIELDS
(
t
);
member
;
member
=
TREE_CHAIN
(
member
))
{
tree
init
,
name
;
from_init_list
=
0
;
int
from_init_list
;
/* member could be, for example, a CONST_DECL for an enumerated
tag; we don't want to try to initialize that, since it already
has a value. */
if
(
TREE_CODE
(
member
)
!=
FIELD_DECL
||
!
DECL_NAME
(
member
))
continue
;
/* See if we had a user-specified member initialization. */
if
(
have_init_list
)
if
(
TREE_PURPOSE
(
mem_init_list
)
)
{
if
(
TREE_PURPOSE
(
init_list
))
{
name
=
TREE_PURPOSE
(
init_list
);
init
=
TREE_VALUE
(
init_list
);
from_init_list
=
1
;
name
=
TREE_PURPOSE
(
mem_init_list
);
init
=
TREE_VALUE
(
mem_init_list
);
from_init_list
=
1
;
if
(
TREE_STATIC
(
member
))
{
cp_error
(
"field `%#D' is static; only point of initialization is its declaration"
,
member
);
continue
;
}
/* Also see if it's ever a COMPONENT_REF here. If it is, we
need to do `expand_assignment (name, init, 0, 0);' and
a continue. */
my_friendly_assert
(
TREE_CODE
(
name
)
!=
COMPONENT_REF
,
349
);
}
init_list
=
TREE_CHAIN
(
init_list
);
/* Also see if it's ever a COMPONENT_REF here. If it is, we
need to do `expand_assignment (name, init, 0, 0);' and
a continue. */
my_friendly_assert
(
TREE_CODE
(
name
)
!=
COMPONENT_REF
,
349
);
}
if
(
!
from_init_list
)
else
{
/* member could be, for example, a CONST_DECL for an enumerated
tag; we don't want to try to initialize that, since it already
has a value. */
if
(
TREE_CODE
(
member
)
!=
FIELD_DECL
||
!
DECL_NAME
(
member
))
continue
;
name
=
DECL_NAME
(
member
);
init
=
DECL_INITIAL
(
member
);
from_init_list
=
0
;
}
perform_member_init
(
member
,
name
,
init
,
from_init_list
);
perform_member_init
(
member
,
name
,
init
,
from_init_list
,
&
protect_list
);
mem_init_list
=
TREE_CHAIN
(
mem_init_list
);
}
current_member_init_list
=
NULL_TREE
;
/* Now initialize any members from our bases. */
while
(
mem_init_list
)
{
tree
name
,
init
,
field
;
if
(
TREE_PURPOSE
(
mem_init_list
))
{
name
=
TREE_PURPOSE
(
mem_init_list
);
init
=
TREE_VALUE
(
mem_init_list
);
/* XXX: this may need the COMPONENT_REF operand 0 check if
it turns out we actually get them. */
field
=
IDENTIFIER_CLASS_VALUE
(
name
);
/* If one member shadows another, get the outermost one. */
if
(
TREE_CODE
(
field
)
==
TREE_LIST
)
{
field
=
TREE_VALUE
(
field
);
if
(
decl_type_context
(
field
)
!=
current_class_type
)
cp_error
(
"field `%D' not in immediate context"
,
field
);
}
#if 0
/* It turns out if you have an anonymous union in the
class, a member from it can end up not being on the
list of fields (rather, the type is), and therefore
won't be seen by the for loop above. */
/* The code in this for loop is derived from a general loop
which had this check in it. Theoretically, we've hit
every initialization for the list of members in T, so
we shouldn't have anything but these left in this list. */
my_friendly_assert (DECL_FIELD_CONTEXT (field) != t, 351);
#endif
perform_member_init
(
field
,
name
,
init
,
1
,
&
protect_list
);
}
mem_init_list
=
TREE_CHAIN
(
mem_init_list
);
}
if
(
!
immediately
)
{
...
...
@@ -750,14 +738,13 @@ static void
expand_aggr_vbase_init_1
(
binfo
,
exp
,
addr
,
init_list
)
tree
binfo
,
exp
,
addr
,
init_list
;
{
tree
init
=
value_member
(
BINFO_TYPE
(
binfo
)
,
init_list
);
tree
init
=
purpose_member
(
binfo
,
init_list
);
tree
ref
=
build_indirect_ref
(
addr
,
NULL_PTR
);
if
(
init
)
init
=
TREE_
PURPOS
E
(
init
);
init
=
TREE_
VALU
E
(
init
);
/* Call constructors, but don't set up vtables. */
expand_aggr_init_1
(
binfo
,
exp
,
ref
,
init
,
0
,
LOOKUP_COMPLAIN
);
expand_cleanups_to
(
NULL_TREE
);
CLEAR_BINFO_VBASE_INIT_MARKED
(
binfo
);
}
/* Initialize this object's virtual base class pointers. This must be
...
...
@@ -781,38 +768,14 @@ expand_aggr_vbase_init (binfo, exp, addr, init_list)
if
(
result
)
expand_expr_stmt
(
build_compound_expr
(
result
));
/* Mark everything as having an initializer
(either explicit or default). */
for
(
vbases
=
CLASSTYPE_VBASECLASSES
(
type
);
vbases
;
vbases
=
TREE_CHAIN
(
vbases
))
SET_BINFO_VBASE_INIT_MARKED
(
vbases
);
/* First, initialize baseclasses which could be baseclasses
for other virtual baseclasses. */
for
(
vbases
=
CLASSTYPE_VBASECLASSES
(
type
);
vbases
;
vbases
=
TREE_CHAIN
(
vbases
))
/* Don't initialize twice. */
if
(
BINFO_VBASE_INIT_MARKED
(
vbases
))
{
tree
tmp
=
result
;
while
(
BINFO_TYPE
(
vbases
)
!=
BINFO_TYPE
(
TREE_PURPOSE
(
tmp
)))
tmp
=
TREE_CHAIN
(
tmp
);
expand_aggr_vbase_init_1
(
vbases
,
exp
,
TREE_OPERAND
(
TREE_VALUE
(
tmp
),
0
),
init_list
);
}
/* Now initialize the baseclasses which don't have virtual baseclasses. */
for
(;
result
;
result
=
TREE_CHAIN
(
result
))
/* Don't initialize twice. */
if
(
BINFO_VBASE_INIT_MARKED
(
TREE_PURPOSE
(
result
)))
{
my_friendly_abort
(
47
);
expand_aggr_vbase_init_1
(
TREE_PURPOSE
(
result
),
exp
,
TREE_OPERAND
(
TREE_VALUE
(
result
),
0
),
init_list
);
}
for
(
vbases
=
CLASSTYPE_VBASECLASSES
(
type
);
vbases
;
vbases
=
TREE_CHAIN
(
vbases
))
{
tree
tmp
=
purpose_member
(
vbases
,
result
);
expand_aggr_vbase_init_1
(
vbases
,
exp
,
TREE_OPERAND
(
TREE_VALUE
(
tmp
),
0
),
init_list
);
}
}
}
...
...
@@ -862,7 +825,7 @@ member_init_ok_or_else (field, type, member_name)
if
(
field
==
NULL_TREE
)
{
cp_error
(
"class `%T' does not have any field named `%s'"
,
type
,
member_name
);
member_name
);
return
0
;
}
if
(
DECL_CONTEXT
(
field
)
!=
type
...
...
@@ -872,6 +835,13 @@ member_init_ok_or_else (field, type, member_name)
field
);
return
0
;
}
if
(
TREE_STATIC
(
field
))
{
cp_error
(
"field `%#D' is static; only point of initialization is its declaration"
,
field
);
return
0
;
}
return
1
;
}
...
...
@@ -1209,7 +1179,8 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
tree
rval
;
tree
parms
;
if
(
init
==
NULL_TREE
||
TREE_CODE
(
init
)
==
TREE_LIST
)
if
(
init
==
NULL_TREE
||
(
TREE_CODE
(
init
)
==
TREE_LIST
&&
!
TREE_TYPE
(
init
)))
{
parms
=
init
;
if
(
parms
)
...
...
@@ -2044,6 +2015,12 @@ build_offset_ref (cname, name)
return
t
;
}
if
(
TREE_CODE
(
t
)
==
FIELD_DECL
&&
DECL_BIT_FIELD
(
t
))
{
cp_error
(
"illegal pointer to bit field `%D'"
,
t
);
return
error_mark_node
;
}
/* static class functions too. */
if
(
TREE_CODE
(
t
)
==
FUNCTION_DECL
&&
TREE_CODE
(
TREE_TYPE
(
t
))
==
FUNCTION_TYPE
)
my_friendly_abort
(
53
);
...
...
@@ -2085,7 +2062,7 @@ get_member_function (exp_addr_ptr, exp, member)
if
(
UNITS_PER_WORD
<=
1
)
my_friendly_abort
(
54
);
e1
=
build
(
GT_EXPR
,
integer
_type_node
,
e0
,
integer_zero_node
);
e1
=
build
(
GT_EXPR
,
boolean
_type_node
,
e0
,
integer_zero_node
);
e1
=
build_compound_expr
(
tree_cons
(
NULL_TREE
,
exp_addr
,
build_tree_list
(
NULL_TREE
,
e1
)));
e1
=
save_expr
(
e1
);
...
...
@@ -2240,7 +2217,7 @@ resolve_offset_ref (exp)
}
else
if
(
TYPE_PTRMEMFUNC_P
(
TREE_TYPE
(
member
)))
{
return
get_member_function_from_ptrfunc
(
&
addr
,
base
,
member
);
return
get_member_function_from_ptrfunc
(
&
addr
,
member
);
}
my_friendly_abort
(
56
);
/* NOTREACHED */
...
...
@@ -2322,7 +2299,13 @@ is_friend (type, supplicant)
{
tree
list
=
DECL_FRIENDLIST
(
TYPE_NAME
(
type
));
tree
name
=
DECL_NAME
(
supplicant
);
tree
ctype
=
DECL_CLASS_CONTEXT
(
supplicant
);
tree
ctype
;
if
(
DECL_FUNCTION_MEMBER_P
(
supplicant
))
ctype
=
DECL_CLASS_CONTEXT
(
supplicant
);
else
ctype
=
NULL_TREE
;
for
(;
list
;
list
=
TREE_CHAIN
(
list
))
{
if
(
name
==
TREE_PURPOSE
(
list
))
...
...
@@ -2353,8 +2336,14 @@ is_friend (type, supplicant)
}
{
tree
context
=
declp
?
DECL_CLASS_CONTEXT
(
supplicant
)
:
DECL_CONTEXT
(
TYPE_NAME
(
supplicant
));
tree
context
;
if
(
!
declp
)
context
=
DECL_CONTEXT
(
TYPE_NAME
(
supplicant
));
else
if
(
DECL_FUNCTION_MEMBER_P
(
supplicant
))
context
=
DECL_CLASS_CONTEXT
(
supplicant
);
else
context
=
NULL_TREE
;
if
(
context
)
return
is_friend
(
type
,
context
);
...
...
@@ -2508,7 +2497,7 @@ make_friend_class (type, friend_type)
}
if
(
type
==
friend_type
)
{
warning
(
"class `%s' is implicitly friends with itself"
,
pedwarn
(
"class `%s' is implicitly friends with itself"
,
TYPE_NAME_STRING
(
type
));
return
;
}
...
...
@@ -2803,7 +2792,7 @@ build_new (placement, decl, init, use_global_new)
{
tree
type
,
true_type
,
size
,
rval
;
tree
nelts
;
tree
alloc_expr
;
tree
alloc_expr
,
alloc_temp
;
int
has_array
=
0
;
enum
tree_code
code
=
NEW_EXPR
;
...
...
@@ -2927,6 +2916,12 @@ build_new (placement, decl, init, use_global_new)
type
=
true_type
=
TREE_TYPE
(
type
);
}
if
(
TREE_CODE
(
type
)
==
FUNCTION_TYPE
)
{
error
(
"new cannot be applied to a function type"
);
return
error_mark_node
;
}
/* When the object being created is an array, the new-expression yields a
pointer to the initial element (if any) of the array. For example,
both new int and new int[10] return an int*. 5.3.4. */
...
...
@@ -2956,7 +2951,7 @@ build_new (placement, decl, init, use_global_new)
if
(
true_type
==
void_type_node
)
{
error
(
"invalid type
for new: `void'
"
);
error
(
"invalid type
`void' for new
"
);
return
error_mark_node
;
}
...
...
@@ -3032,12 +3027,19 @@ build_new (placement, decl, init, use_global_new)
TREE_CALLS_NEW
(
rval
)
=
1
;
}
if
(
flag_check_new
)
if
(
flag_check_new
&&
rval
)
{
if
(
rval
)
rval
=
save_expr
(
rval
);
alloc_expr
=
rval
;
/* For array new, we need to make sure that the call to new is
not expanded as part of the RTL_EXPR for the initialization,
so we can't just use save_expr here. */
alloc_temp
=
get_temp_name
(
TREE_TYPE
(
rval
),
0
);
alloc_expr
=
build
(
MODIFY_EXPR
,
TREE_TYPE
(
rval
),
alloc_temp
,
rval
);
TREE_SIDE_EFFECTS
(
alloc_expr
)
=
1
;
rval
=
alloc_temp
;
}
else
alloc_expr
=
NULL_TREE
;
/* 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
...
...
@@ -3184,10 +3186,17 @@ build_new (placement, decl, init, use_global_new)
done
:
if
(
flag_check_new
&&
alloc_expr
&&
rval
!=
alloc_expr
)
if
(
alloc_expr
)
{
tree
ifexp
=
build_binary_op
(
NE_EXPR
,
alloc_expr
,
integer_zero_node
,
1
);
rval
=
build_conditional_expr
(
ifexp
,
rval
,
alloc_expr
);
/* Did we modify the storage? */
if
(
rval
!=
alloc_temp
)
{
tree
ifexp
=
build_binary_op
(
NE_EXPR
,
alloc_expr
,
integer_zero_node
,
1
);
rval
=
build_conditional_expr
(
ifexp
,
rval
,
alloc_temp
);
}
else
rval
=
alloc_expr
;
}
if
(
rval
&&
TREE_TYPE
(
rval
)
!=
build_pointer_type
(
type
))
...
...
@@ -3354,7 +3363,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
}
}
expand_start_cond
(
build
(
GE_EXPR
,
integer
_type_node
,
expand_start_cond
(
build
(
GE_EXPR
,
boolean
_type_node
,
iterator
,
integer_zero_node
),
0
);
expand_start_loop_continue_elsewhere
(
1
);
...
...
@@ -3394,7 +3403,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
expand_assignment
(
base2
,
build
(
PLUS_EXPR
,
TYPE_POINTER_TO
(
type
),
base2
,
size
),
0
,
0
);
expand_loop_continue_here
();
expand_exit_loop_if_false
(
0
,
build
(
NE_EXPR
,
integer
_type_node
,
expand_exit_loop_if_false
(
0
,
build
(
NE_EXPR
,
boolean
_type_node
,
build
(
PREDECREMENT_EXPR
,
integer_type_node
,
iterator
,
integer_one_node
),
minus_one
));
if
(
obey_regdecls
)
...
...
@@ -3975,7 +3984,7 @@ build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
body
=
tree_cons
(
NULL_TREE
,
build
(
EXIT_EXPR
,
void_type_node
,
build
(
EQ_EXPR
,
integer
_type_node
,
base
,
tbase
)),
build
(
EQ_EXPR
,
boolean
_type_node
,
base
,
tbase
)),
body
);
loop
=
build
(
LOOP_EXPR
,
void_type_node
,
build_compound_expr
(
body
));
...
...
@@ -4031,7 +4040,7 @@ build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
/* Outermost wrapper: If pointer is null, punt. */
body
=
build
(
COND_EXPR
,
void_type_node
,
build
(
NE_EXPR
,
integer
_type_node
,
base
,
integer_zero_node
),
build
(
NE_EXPR
,
boolean
_type_node
,
base
,
integer_zero_node
),
body
,
integer_zero_node
);
body
=
build1
(
NOP_EXPR
,
void_type_node
,
body
);
...
...
gcc/cp/lex.c
View file @
b7484fbe
...
...
@@ -4541,8 +4541,6 @@ real_yylex ()
{
value
=
'}'
;
goto
done
;
}
else
if
(
c
==
'%'
&&
c1
==
':'
)
{
value
=
'#'
;
goto
done
;
}
else
if
(
c
==
':'
&&
c1
==
'>'
)
{
value
=
']'
;
goto
done
;
}
nextchar
=
c1
;
token_buffer
[
1
]
=
0
;
...
...
@@ -4560,6 +4558,11 @@ real_yylex ()
value
=
SCOPE
;
yylval
.
itype
=
1
;
}
else
if
(
c
==
'>'
)
{
value
=
']'
;
goto
done
;
}
else
{
nextchar
=
c
;
...
...
gcc/cp/method.c
View file @
b7484fbe
...
...
@@ -2211,12 +2211,14 @@ synthesize_method (fndecl)
int
nested
=
(
current_function_decl
!=
NULL_TREE
);
int
toplev
=
(
decl_function_context
(
fndecl
)
==
NULL_TREE
);
char
*
f
=
input_filename
;
tree
base
=
DECL_CLASS_CONTEXT
(
fndecl
);
if
(
nested
)
push_cp_function_context
(
toplev
);
input_filename
=
DECL_SOURCE_FILE
(
fndecl
);
extract_interface_info
();
interface_unknown
=
CLASSTYPE_INTERFACE_UNKNOWN
(
base
);
interface_only
=
CLASSTYPE_INTERFACE_ONLY
(
base
);
start_function
(
NULL_TREE
,
fndecl
,
NULL_TREE
,
1
);
store_parm_decls
();
...
...
gcc/cp/parse.y
View file @
b7484fbe
...
...
@@ -1074,8 +1074,10 @@ unary_expr:
{
tree t = TREE_VALUE ($2);
if (t != NULL_TREE
&& TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids using sizeof() on a function");
&& ((TREE_TYPE (t)
&& TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
|| is_overloaded_fn (t)))
pedwarn ("ANSI C++ forbids taking the sizeof a function type");
}
$$ = c_sizeof (TREE_TYPE ($2)); }
| SIZEOF '(' type_id ')' %prec HYPERUNARY
...
...
@@ -1142,7 +1144,7 @@ new_initializer:
syntactically valid but semantically invalid. */
| '=' init
{
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids initialization of new expression with `='");
$$ = $2;
}
...
...
@@ -1169,7 +1171,7 @@ cast_expr:
{
tree init = build_nt (CONSTRUCTOR, NULL_TREE,
nreverse ($3));
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids constructor-expressions");
/* Indicate that this was a GNU C constructor expression. */
TREE_HAS_CONSTRUCTOR (init) = 1;
...
...
@@ -1289,7 +1291,6 @@ unqualified_id:
expr_or_declarator:
notype_unqualified_id
| notype_qualified_id
| '*' expr_or_declarator %prec UNARY
{ $$ = build_parse_node (INDIRECT_REF, $2); }
| '&' expr_or_declarator %prec UNARY
...
...
@@ -1301,9 +1302,6 @@ expr_or_declarator:
direct_notype_declarator:
complex_direct_notype_declarator
| notype_unqualified_id
| notype_qualified_id
{ push_nested_class (TREE_TYPE (OP0 ($$)), 3);
TREE_COMPLEXITY ($$) = current_class_depth; }
| '(' expr_or_declarator ')'
{ $$ = finish_decl_parsing ($2); }
;
...
...
@@ -1360,7 +1358,7 @@ primary:
$<ttype>$ = expand_start_stmt_expr (); }
compstmt ')'
{ tree rtl_exp;
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids braced-groups within expressions");
rtl_exp = expand_end_stmt_expr ($<ttype>2);
/* The statements have side effects, so the group does. */
...
...
@@ -1554,7 +1552,7 @@ primary:
| object unqualified_id %prec UNARY
{ got_object = NULL_TREE;
$$ = build_component_ref ($$, $2, NULL_TREE, 1); }
| object qualified_id %prec UNARY
| object
over
qualified_id %prec UNARY
{ got_object = NULL_TREE;
$$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
| object unqualified_id '(' nonnull_exprlist ')'
...
...
@@ -1589,7 +1587,7 @@ primary:
(LOOKUP_NORMAL|LOOKUP_AGGR));
#endif
}
| object qualified_id '(' nonnull_exprlist ')'
| object
over
qualified_id '(' nonnull_exprlist ')'
{
got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
...
...
@@ -1601,7 +1599,7 @@ primary:
else
$$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4);
}
| object qualified_id LEFT_RIGHT
| object
over
qualified_id LEFT_RIGHT
{
got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
...
...
@@ -1617,8 +1615,9 @@ primary:
| object '~' TYPESPEC LEFT_RIGHT
{
got_object = NULL_TREE;
if (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3))))
if (IDENTIFIER_GLOBAL_VALUE ($3)
&& (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3)))))
cp_error ("`%E' is not of type `%T'", $1, $3);
$$ = convert (void_type_node, $1);
}
...
...
@@ -1654,7 +1653,7 @@ primary_no_id:
}
$<ttype>$ = expand_start_stmt_expr (); }
compstmt ')'
{ if (
flag_ansi
)
{ if (
pedantic
)
pedwarn ("ANSI C++ forbids braced-groups within expressions");
$$ = expand_end_stmt_expr ($<ttype>2); }
| primary_no_id '(' nonnull_exprlist ')'
...
...
@@ -1816,6 +1815,8 @@ typed_declspecs1:
{ $$ = decl_tree_cons (NULL_TREE, $2, $$); }
| typespec reserved_declspecs %prec HYPERUNARY
{ $$ = decl_tree_cons (NULL_TREE, $$, $2); }
| typespec reserved_typespecquals reserved_declspecs
{ $$ = decl_tree_cons (NULL_TREE, $$, chainon ($2, $3)); }
| declmods typespec reserved_declspecs
{ $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); }
| declmods typespec reserved_typespecquals
...
...
@@ -1902,11 +1903,11 @@ typespec: structsp
| complete_type_name
| TYPEOF '(' expr ')'
{ $$ = TREE_TYPE ($3);
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids `typeof'"); }
| TYPEOF '(' type_id ')'
{ $$ = groktypename ($3);
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids `typeof'"); }
| SIGOF '(' expr ')'
{ tree type = TREE_TYPE ($3);
...
...
@@ -2763,7 +2764,7 @@ new_type_id:
non-constant dimension. */
| '(' type_id ')' '[' expr ']'
{
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new");
$$ = build_parse_node (ARRAY_REF, TREE_VALUE ($2), $5);
$$ = build_decl_list (TREE_PURPOSE ($2), $$);
...
...
@@ -2905,6 +2906,9 @@ complex_direct_notype_declarator:
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
| direct_notype_declarator '[' ']'
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
| notype_qualified_id
{ push_nested_class (TREE_TYPE (OP0 ($$)), 3);
TREE_COMPLEXITY ($$) = current_class_depth; }
;
qualified_id:
...
...
@@ -3107,7 +3111,7 @@ errstmt: error ';'
maybe_label_decls:
/* empty */
| label_decls
{ if (
flag_ansi
)
{ if (
pedantic
)
pedwarn ("ANSI C++ forbids label declarations"); }
;
...
...
@@ -3323,7 +3327,7 @@ simple_stmt:
register tree label
= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
if (value1 != error_mark_node
&& value2 != error_mark_node)
...
...
gcc/cp/pt.c
View file @
b7484fbe
...
...
@@ -755,6 +755,8 @@ uses_template_parms (t)
case
REFERENCE_TYPE
:
return
uses_template_parms
(
TREE_TYPE
(
t
));
case
RECORD_TYPE
:
if
(
TYPE_PTRMEMFUNC_FLAG
(
t
))
return
uses_template_parms
(
TYPE_PTRMEMFUNC_FN_TYPE
(
t
));
case
UNION_TYPE
:
if
(
!
TYPE_NAME
(
t
))
return
0
;
...
...
@@ -1153,9 +1155,8 @@ tsubst (t, args, nargs, in_decl)
&&
type
!=
integer_type_node
&&
type
!=
void_type_node
&&
type
!=
char_type_node
)
type
=
cp_build_type_variant
(
tsubst
(
type
,
args
,
nargs
,
in_decl
),
TYPE_READONLY
(
type
),
TYPE_VOLATILE
(
type
));
type
=
tsubst
(
type
,
args
,
nargs
,
in_decl
);
switch
(
TREE_CODE
(
t
))
{
case
RECORD_TYPE
:
...
...
@@ -1679,12 +1680,16 @@ instantiate_template (tmpl, targ_ptr)
my_friendly_assert
(
TREE_CODE
(
tmpl
)
==
TEMPLATE_DECL
,
283
);
len
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
tmpl
));
i
=
len
;
while
(
i
--
)
targ_ptr
[
i
]
=
copy_to_permanent
(
targ_ptr
[
i
]);
for
(
fndecl
=
DECL_TEMPLATE_INSTANTIATIONS
(
tmpl
);
fndecl
;
fndecl
=
TREE_CHAIN
(
fndecl
))
{
tree
*
t1
=
&
TREE_VEC_ELT
(
TREE_PURPOSE
(
fndecl
),
0
);
for
(
i
=
len
-
1
;
i
>=
0
;
i
--
)
if
(
t1
[
i
]
!=
targ_ptr
[
i
]
)
if
(
simple_cst_equal
(
t1
[
i
],
targ_ptr
[
i
])
<=
0
)
goto
no_match
;
/* Here, we have a match. */
...
...
@@ -2036,6 +2041,15 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
return
1
;
if
(
arg
==
unknown_type_node
)
return
1
;
if
(
!
uses_template_parms
(
parm
)
&&
TREE_CODE_CLASS
(
TREE_CODE
(
arg
))
!=
't'
)
{
if
(
can_convert_arg
(
parm
,
TREE_TYPE
(
arg
),
arg
))
continue
;
return
1
;
}
#if 0
if (TREE_CODE (arg) == VAR_DECL)
arg = TREE_TYPE (arg);
...
...
gcc/cp/tree.c
View file @
b7484fbe
...
...
@@ -1740,6 +1740,9 @@ make_deep_copy (t)
case
ARRAY_TYPE
:
return
build_array_type
(
make_deep_copy
(
TREE_TYPE
(
t
)),
make_deep_copy
(
TYPE_DOMAIN
(
t
)));
case
INTEGER_TYPE
:
return
build_index_type
(
make_deep_copy
(
TYPE_MAX_VALUE
(
t
)));
case
OFFSET_TYPE
:
return
build_offset_type
(
make_deep_copy
(
TYPE_OFFSET_BASETYPE
(
t
)),
make_deep_copy
(
TREE_TYPE
(
t
)));
...
...
@@ -1749,6 +1752,7 @@ make_deep_copy (t)
build_function_type
(
make_deep_copy
(
TREE_TYPE
(
t
)),
make_deep_copy
(
TREE_CHAIN
(
TYPE_ARG_TYPES
(
t
)))));
case
RECORD_TYPE
:
if
(
TYPE_PTRMEMFUNC_P
(
t
))
return
build_ptrmemfunc_type
...
...
gcc/cp/typeck.c
View file @
b7484fbe
...
...
@@ -719,7 +719,28 @@ comptypes (type1, type2, strict)
return
1
;
case
UNINSTANTIATED_P_TYPE
:
return
UPT_TEMPLATE
(
t1
)
==
UPT_TEMPLATE
(
t2
);
if
(
UPT_TEMPLATE
(
t1
)
!=
UPT_TEMPLATE
(
t2
))
return
0
;
{
int
i
=
TREE_VEC_LENGTH
(
UPT_PARMS
(
t1
));
tree
*
p1
=
&
TREE_VEC_ELT
(
UPT_PARMS
(
t1
),
0
);
tree
*
p2
=
&
TREE_VEC_ELT
(
UPT_PARMS
(
t2
),
0
);
while
(
i
--
)
{
if
(
TREE_CODE_CLASS
(
TREE_CODE
(
p1
[
i
]))
==
't'
)
{
if
(
!
comptypes
(
p1
[
i
],
p2
[
i
],
1
))
return
0
;
}
else
{
if
(
simple_cst_equal
(
p1
[
i
],
p2
[
i
])
<=
0
)
return
0
;
}
}
}
return
1
;
}
return
attrval
==
2
&&
val
==
1
?
2
:
val
;
}
...
...
@@ -1834,26 +1855,6 @@ build_array_ref (array, idx)
return
error_mark_node
;
itype
=
TREE_TYPE
(
idx
);
/* We must check here for the reference, so we can do the possible
conversions immediately afterwards. */
if
(
TREE_CODE
(
itype
)
==
REFERENCE_TYPE
)
{
idx
=
convert_from_reference
(
idx
);
itype
=
TREE_TYPE
(
idx
);
}
if
(
IS_AGGR_TYPE
(
itype
))
{
if
(
TYPE_HAS_INT_CONVERSION
(
itype
))
idx
=
build_type_conversion
(
CONVERT_EXPR
,
integer_type_node
,
idx
,
1
);
else
{
error_with_aggr_type
(
itype
,
"type `%s' requires integer conversion for array indexing"
);
return
error_mark_node
;
}
}
if
(
TREE_CODE
(
TREE_TYPE
(
array
))
==
ARRAY_TYPE
&&
TREE_CODE
(
array
)
!=
INDIRECT_REF
)
...
...
@@ -1902,19 +1903,19 @@ build_array_ref (array, idx)
return
error_mark_node
;
}
/* Note in C++ we don't bother warning about subscripting a
`register' array, since it's valid in C++ to take the address
of something with that storage specification. */
if
(
pedantic
&&
!
lvalue_p
(
array
))
pedwarn
(
"ANSI C++ forbids subscripting non-lvalue array"
);
if
(
pedantic
)
/* Note in C++ it is valid to subscript a `register' array, since
it is valid to take the address of something with that
storage specification. */
if
(
extra_warnings
)
{
tree
foo
=
array
;
while
(
TREE_CODE
(
foo
)
==
COMPONENT_REF
)
foo
=
TREE_OPERAND
(
foo
,
0
);
if
(
TREE_CODE
(
foo
)
==
VAR_DECL
&&
DECL_REGISTER
(
foo
))
pedwarn
(
"ANSI C++ forbids subscripting non-lvalue array
"
);
warning
(
"subscripting array declared `register'
"
);
}
type
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
TREE_TYPE
(
array
)));
...
...
@@ -2122,7 +2123,7 @@ build_x_function_call (function, params, decl)
decl
=
C_C_D
;
decl_addr
=
build_unary_op
(
ADDR_EXPR
,
decl
,
0
);
function
=
get_member_function_from_ptrfunc
(
&
decl_addr
,
decl
,
function
=
get_member_function_from_ptrfunc
(
&
decl_addr
,
TREE_OPERAND
(
function
,
1
));
params
=
tree_cons
(
NULL_TREE
,
decl_addr
,
params
);
return
build_function_call
(
function
,
params
);
...
...
@@ -2184,9 +2185,8 @@ build_x_function_call (function, params, decl)
instance to use, if the member points to a virtual member. */
tree
get_member_function_from_ptrfunc
(
instance_ptrptr
,
instance
,
function
)
get_member_function_from_ptrfunc
(
instance_ptrptr
,
function
)
tree
*
instance_ptrptr
;
tree
instance
;
tree
function
;
{
if
(
TREE_CODE
(
function
)
==
OFFSET_REF
)
...
...
@@ -2200,7 +2200,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
tree
index
=
save_expr
(
build_component_ref
(
function
,
index_identifier
,
0
,
0
));
tree
e1
=
build
(
GT_EXPR
,
delta
_type_node
,
index
,
tree
e1
=
build
(
GT_EXPR
,
boolean
_type_node
,
index
,
convert
(
delta_type_node
,
integer_zero_node
));
tree
delta
=
convert
(
ptrdiff_type_node
,
build_component_ref
(
function
,
delta_identifier
,
0
,
0
));
...
...
@@ -2209,9 +2209,16 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
tree
e3
;
tree
aref
,
vtbl
;
tree
instance
;
tree
instance_ptr
=
*
instance_ptrptr
;
if
(
TREE_SIDE_EFFECTS
(
instance_ptr
))
instance_ptr
=
save_expr
(
instance_ptr
);
/* convert down to the right base, before using the instance. */
instance
=
convert_pointer_to_real
(
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
fntype
)),
build_unary_op
(
ADDR_EXPR
,
instance
,
0
));
instance
=
convert_pointer_to_real
(
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
fntype
)),
instance_ptr
);
if
(
instance
==
error_mark_node
)
return
instance
;
...
...
@@ -2238,9 +2245,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
delta
,
1
);
}
*
instance_ptrptr
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
*
instance_ptrptr
),
*
instance_ptrptr
,
delta
);
*
instance_ptrptr
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
instance_ptr
),
instance_ptr
,
delta
);
if
(
flag_vtable_thunks
)
e2
=
aref
;
else
...
...
@@ -2249,6 +2255,12 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
e3
=
PFN_FROM_PTRMEMFUNC
(
function
);
TREE_TYPE
(
e2
)
=
TREE_TYPE
(
e3
);
function
=
build_conditional_expr
(
e1
,
e2
,
e3
);
/* Make sure this doesn't get evaluated first inside one of the
branches of the COND_EXPR. */
if
(
TREE_CODE
(
instance_ptr
)
==
SAVE_EXPR
)
function
=
build
(
COMPOUND_EXPR
,
TREE_TYPE
(
function
),
instance_ptr
,
function
);
}
return
function
;
}
...
...
@@ -2325,7 +2337,7 @@ build_function_call_real (function, params, require_complete, flags)
{
tree
instance_ptr
=
build_unary_op
(
ADDR_EXPR
,
C_C_D
,
0
);
fntype
=
TYPE_PTRMEMFUNC_FN_TYPE
(
fntype
);
function
=
get_member_function_from_ptrfunc
(
&
instance_ptr
,
C_C_D
,
function
);
function
=
get_member_function_from_ptrfunc
(
&
instance_ptr
,
function
);
}
is_method
=
(
TREE_CODE
(
fntype
)
==
POINTER_TYPE
...
...
@@ -2715,7 +2727,6 @@ build_binary_op (code, arg1, arg2, convert_p)
tree
arg1
,
arg2
;
int
convert_p
;
{
tree
type1
,
type2
;
tree
args
[
2
];
args
[
0
]
=
arg1
;
...
...
@@ -2724,64 +2735,39 @@ build_binary_op (code, arg1, arg2, convert_p)
if
(
convert_p
)
{
tree
args_save
[
2
];
tree
type0
,
type1
;
args
[
0
]
=
args_save
[
0
]
=
default_conversion
(
args
[
0
]);
args
[
1
]
=
args_save
[
1
]
=
default_conversion
(
args
[
1
]);
if
(
args
[
0
]
==
error_mark_node
||
args
[
1
]
==
error_mark_node
)
return
error_mark_node
;
type0
=
TREE_TYPE
(
args
[
0
]);
type1
=
TREE_TYPE
(
args
[
1
]);
if
(
type_unknown_p
(
args
[
0
]))
{
args
[
0
]
=
instantiate_type
(
TREE_TYPE
(
args
[
1
])
,
args
[
0
],
1
);
args
[
0
]
=
instantiate_type
(
type1
,
args
[
0
],
1
);
args
[
0
]
=
default_conversion
(
args
[
0
]);
}
else
if
(
type_unknown_p
(
args
[
1
]))
{
args
[
1
]
=
require_instantiated_type
(
TREE_TYPE
(
args
[
0
]),
args
[
1
],
args
[
1
]
=
require_instantiated_type
(
type0
,
args
[
1
],
error_mark_node
);
args
[
1
]
=
default_conversion
(
args
[
1
]);
}
type1
=
TREE_TYPE
(
args
[
0
]);
type2
=
TREE_TYPE
(
args
[
1
]);
if
(
IS_AGGR_TYPE_2
(
type1
,
type2
))
if
(
IS_AGGR_TYPE
(
type0
)
||
IS_AGGR_TYPE
(
type1
))
{
/* Try to convert this to something reasonable. */
if
(
!
build_default_binary_type_conversion
(
code
,
&
args
[
0
],
&
args
[
1
]))
return
error_mark_node
;
}
else
if
(
IS_AGGR_TYPE
(
type1
)
||
IS_AGGR_TYPE
(
type2
))
{
int
convert_index
=
IS_AGGR_TYPE
(
type2
);
/* Avoid being tripped up by things like (ARG1 != 0). */
tree
types
[
2
],
try
;
types
[
0
]
=
type1
;
types
[
1
]
=
type2
;
if
(
code
==
TRUTH_ANDIF_EXPR
||
code
==
TRUTH_ORIF_EXPR
)
try
=
build_type_conversion
(
code
,
boolean_type_node
,
args
[
convert_index
],
1
);
else
{
try
=
build_type_conversion
(
code
,
types
[
convert_index
^
1
],
args
[
convert_index
],
1
);
if
(
try
==
0
&&
args
[
1
]
==
integer_zero_node
&&
(
code
==
NE_EXPR
||
code
==
EQ_EXPR
))
try
=
build_type_conversion
(
code
,
ptr_type_node
,
args
[
convert_index
],
1
);
}
if
(
try
==
0
)
{
cp_error
(
"no match for `%O(%#T, %#T)'"
,
code
,
TREE_TYPE
(
arg1
),
TREE_TYPE
(
arg2
));
return
error_mark_node
;
}
if
(
try
==
error_mark_node
)
error
(
"ambiguous pointer conversion"
);
args
[
convert_index
]
=
try
;
}
if
(
args
[
0
]
==
args_save
[
0
])
args
[
0
]
=
arg1
;
if
(
args
[
1
]
==
args_save
[
1
])
...
...
@@ -3094,7 +3080,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
{
tree
base
=
common_base_type
(
tt0
,
tt1
);
if
(
base
==
NULL_TREE
)
cp_
warning
(
"comparison of distinct object pointer types `%T' and `%T'"
,
type0
,
type1
);
cp_
pedwarn
(
"comparison of distinct object pointer types `%T' and `%T'"
,
type0
,
type1
);
else
if
(
base
==
error_mark_node
)
{
cp_error
(
"comparison of pointer types `%T' and `%T' requires conversion to ambiguous supertype"
,
type0
,
type1
);
...
...
@@ -3119,6 +3105,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
if
(
pedantic
&&
TREE_CODE
(
tt1
)
==
FUNCTION_TYPE
&&
tree_int_cst_lt
(
TYPE_SIZE
(
type0
),
TYPE_SIZE
(
type1
)))
pedwarn
(
"ANSI C++ forbids comparison of `void *' with function pointer"
);
else
if
(
TREE_CODE
(
tt1
)
==
OFFSET_TYPE
)
pedwarn
(
"ANSI C++ forbids conversion of a pointer to member to `void *'"
);
}
else
if
(
tt1
==
void_type_node
)
{
...
...
@@ -3291,18 +3279,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
}
else
if
(
code0
==
POINTER_TYPE
&&
TREE_CODE
(
op1
)
==
INTEGER_CST
&&
integer_zerop
(
op1
))
{
op1
=
null_pointer_node
;
if
(
pedantic
)
pedwarn
(
"ordered comparison of pointer with integer zero"
);
}
op1
=
null_pointer_node
;
else
if
(
code1
==
POINTER_TYPE
&&
TREE_CODE
(
op0
)
==
INTEGER_CST
&&
integer_zerop
(
op0
))
{
op0
=
null_pointer_node
;
if
(
pedantic
)
pedwarn
(
"ANSI C++ forbids ordered comparison of pointer with integer zero"
);
}
op0
=
null_pointer_node
;
else
if
(
code0
==
POINTER_TYPE
&&
code1
==
INTEGER_TYPE
)
{
if
(
pedantic
)
...
...
@@ -3482,14 +3462,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
/* Do the checking based on the original operand trees, so that
casts will be considered, but default promotions won't be. */
if
(
TREE_UNSIGNED
(
comp_type
)
&&
((
op0_signed
&&
(
TREE_CODE
(
op0
)
!=
INTEGER_CST
||
(
TREE_CODE
(
op0
)
==
INTEGER_CST
&&
INT_CST_LT
(
op0
,
integer_zero_node
))))
||
(
op1_signed
&&
(
TREE_CODE
(
op1
)
!=
INTEGER_CST
||
(
TREE_CODE
(
op1
)
==
INTEGER_CST
&&
INT_CST_LT
(
op1
,
integer_zero_node
))))))
&&
((
op0_signed
&&
(
TREE_CODE
(
orig_op0
)
!=
INTEGER_CST
||
tree_int_cst_sgn
(
orig_op0
)
==
-
1
))
||
(
op1_signed
&&
(
TREE_CODE
(
orig_op1
)
!=
INTEGER_CST
||
tree_int_cst_sgn
(
orig_op1
)
==
-
1
))))
warning
(
"comparison between signed and unsigned"
);
/* Warn if two unsigned values are being compared in a size
...
...
@@ -3830,121 +3806,46 @@ build_unary_op (code, xarg, noconvert)
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
register
tree
arg
=
xarg
;
register
tree
argtype
=
0
;
register
enum
tree_code
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
char
*
errstring
=
NULL
;
tree
val
;
int
isaggrtype
;
if
(
typecode
==
ERROR_MARK
)
if
(
arg
==
error_mark_node
)
return
error_mark_node
;
if
(
typecode
==
REFERENCE_TYPE
&&
code
!=
ADDR_EXPR
&&
!
noconvert
)
{
arg
=
convert_from_reference
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
}
if
(
typecode
==
ENUMERAL_TYPE
)
typecode
=
INTEGER_TYPE
;
if
(
typecode
==
BOOLEAN_TYPE
&&
!
noconvert
)
typecode
=
INTEGER_TYPE
;
isaggrtype
=
IS_AGGR_TYPE_CODE
(
typecode
);
switch
(
code
)
{
case
CONVERT_EXPR
:
/* This is used for unary plus, because a CONVERT_EXPR
is enough to prevent anybody from looking inside for
associativity, but won't generate any code. */
if
(
!
(
typecode
==
INTEGER_TYPE
||
typecode
==
REAL_TYPE
))
errstring
=
"wrong type argument to unary plus"
;
else
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
arg
=
build1
(
NON_LVALUE_EXPR
,
TREE_TYPE
(
arg
),
arg
);
break
;
case
NEGATE_EXPR
:
if
(
typecode
==
OFFSET_TYPE
)
{
arg
=
resolve_offset_ref
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
isaggrtype
=
IS_AGGR_TYPE_CODE
(
typecode
);
}
if
(
isaggrtype
)
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
|
WANT_POINTER
,
arg
,
1
)))
errstring
=
"wrong type argument to unary plus"
;
else
{
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
else
{
cp_error
(
"type conversion for type `%T' not allowed"
,
TREE_TYPE
(
arg
));
return
error_mark_node
;
}
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
noconvert
=
1
;
arg
=
default_conversion
(
arg
);
arg
=
build1
(
NON_LVALUE_EXPR
,
TREE_TYPE
(
arg
),
arg
);
}
break
;
if
(
!
(
typecode
==
INTEGER_TYPE
||
typecode
==
REAL_TYPE
))
errstring
=
"wrong type argument to unary minus"
;
case
NEGATE_EXPR
:
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
arg
,
1
)))
errstring
=
"wrong type argument to unary minus"
;
else
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
break
;
case
BIT_NOT_EXPR
:
if
(
typecode
==
OFFSET_TYPE
)
{
arg
=
resolve_offset_ref
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
isaggrtype
=
IS_AGGR_TYPE_CODE
(
typecode
);
}
if
(
isaggrtype
)
{
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
else
{
cp_error
(
"type conversion for type `%T' not allowed"
,
TREE_TYPE
(
arg
));
return
error_mark_node
;
}
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
noconvert
=
1
;
}
if
(
typecode
!=
INTEGER_TYPE
)
errstring
=
"wrong type argument to bit-complement"
;
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
arg
,
1
)))
errstring
=
"wrong type argument to bit-complement"
;
else
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
break
;
case
ABS_EXPR
:
if
(
typecode
==
OFFSET_TYPE
)
{
arg
=
resolve_offset_ref
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
isaggrtype
=
IS_AGGR_TYPE_CODE
(
typecode
);
}
if
(
isaggrtype
)
{
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
else
{
cp_error
(
"type conversion for type `%T' not allowed"
,
TREE_TYPE
(
arg
));
return
error_mark_node
;
}
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
noconvert
=
1
;
}
if
(
!
(
typecode
==
INTEGER_TYPE
||
typecode
==
REAL_TYPE
))
errstring
=
"wrong type argument to abs"
;
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
arg
,
1
)))
errstring
=
"wrong type argument to abs"
;
else
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
break
;
...
...
@@ -3973,21 +3874,8 @@ build_unary_op (code, xarg, noconvert)
/* Report invalid types. */
if
(
typecode
==
OFFSET_TYPE
)
{
arg
=
resolve_offset_ref
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
isaggrtype
=
IS_AGGR_TYPE_CODE
(
typecode
);
}
if
(
isaggrtype
)
{
arg
=
default_conversion
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
}
if
(
typecode
!=
POINTER_TYPE
&&
typecode
!=
INTEGER_TYPE
&&
typecode
!=
REAL_TYPE
)
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_POINTER
,
arg
,
1
)))
{
if
(
code
==
PREINCREMENT_EXPR
)
errstring
=
"no pre-increment operator for type"
;
...
...
@@ -4024,7 +3912,7 @@ build_unary_op (code, xarg, noconvert)
/* Compute the increment. */
if
(
typecode
==
POINTER_TYPE
)
if
(
TREE_CODE
(
argtype
)
==
POINTER_TYPE
)
{
enum
tree_code
tmp
=
TREE_CODE
(
TREE_TYPE
(
argtype
));
if
(
TYPE_SIZE
(
TREE_TYPE
(
argtype
))
==
0
)
...
...
@@ -4081,7 +3969,37 @@ build_unary_op (code, xarg, noconvert)
?
"increment"
:
"decrement"
)))
return
error_mark_node
;
val
=
build
(
code
,
TREE_TYPE
(
arg
),
arg
,
inc
);
/* Forbid using -- on `bool'. */
if
(
TREE_TYPE
(
arg
)
==
boolean_type_node
)
{
if
(
code
==
POSTDECREMENT_EXPR
||
code
==
PREDECREMENT_EXPR
)
{
cp_error
(
"invalid use of `--' on bool variable `%D'"
,
arg
);
return
error_mark_node
;
}
#if 0
/* This will only work if someone can convince Kenner to accept
my patch to expand_increment. (jason) */
val = build (code, TREE_TYPE (arg), arg, inc);
#else
if
(
code
==
POSTINCREMENT_EXPR
)
{
arg
=
stabilize_reference
(
arg
);
val
=
build
(
MODIFY_EXPR
,
TREE_TYPE
(
arg
),
arg
,
boolean_true_node
);
TREE_SIDE_EFFECTS
(
val
)
=
1
;
arg
=
save_expr
(
arg
);
val
=
build
(
COMPOUND_EXPR
,
TREE_TYPE
(
arg
),
val
,
arg
);
val
=
build
(
COMPOUND_EXPR
,
TREE_TYPE
(
arg
),
arg
,
val
);
}
else
val
=
build
(
MODIFY_EXPR
,
TREE_TYPE
(
arg
),
arg
,
boolean_true_node
);
#endif
}
else
val
=
build
(
code
,
TREE_TYPE
(
arg
),
arg
,
inc
);
TREE_SIDE_EFFECTS
(
val
)
=
1
;
return
convert
(
result_type
,
val
);
}
...
...
@@ -4090,7 +4008,8 @@ build_unary_op (code, xarg, noconvert)
/* Note that this operation never does default_conversion
regardless of NOCONVERT. */
if
(
typecode
==
REFERENCE_TYPE
)
argtype
=
TREE_TYPE
(
arg
);
if
(
TREE_CODE
(
argtype
)
==
REFERENCE_TYPE
)
{
arg
=
build1
(
CONVERT_EXPR
,
build_pointer_type
(
TREE_TYPE
(
TREE_TYPE
(
arg
))),
arg
);
TREE_REFERENCE_EXPR
(
arg
)
=
1
;
...
...
@@ -4194,13 +4113,12 @@ build_unary_op (code, xarg, noconvert)
;
/* Anything not already handled and not a true memory reference
is an error. */
else
if
(
typecode
!=
FUNCTION_TYPE
&&
typecode
!=
METHOD_TYPE
else
if
(
TREE_CODE
(
argtype
)
!=
FUNCTION_TYPE
&&
TREE_CODE
(
argtype
)
!=
METHOD_TYPE
&&
!
lvalue_or_else
(
arg
,
"unary `&'"
))
return
error_mark_node
;
/* Ordinary case; arg is a COMPONENT_REF or a decl. */
argtype
=
TREE_TYPE
(
arg
);
/* If the lvalue is const or volatile,
merge that into the type that the address will point to. */
if
(
TREE_CODE_CLASS
(
TREE_CODE
(
arg
))
==
'd'
...
...
@@ -4900,10 +4818,25 @@ build_compound_expr (list)
rest
=
build_compound_expr
(
TREE_CHAIN
(
list
));
/* When pedantic, a compound expression can be neither an lvalue
nor an integer constant expression. */
if
(
!
TREE_SIDE_EFFECTS
(
TREE_VALUE
(
list
))
&&
!
pedantic
)
return
rest
;
if
(
!
TREE_SIDE_EFFECTS
(
TREE_VALUE
(
list
)))
{
/* the left-hand operand of a comma expression is like an expression
statement: we should warn if it doesn't have any side-effects,
unless it was explicitly cast to (void). */
if
((
extra_warnings
||
warn_unused
)
&&
!
(
TREE_CODE
(
TREE_VALUE
(
list
))
==
CONVERT_EXPR
&&
TREE_TYPE
(
TREE_VALUE
(
list
))
==
void_type_node
))
warning
(
"left-hand operand of comma expression has no effect"
);
/* When pedantic, a compound expression can be neither an lvalue
nor an integer constant expression. */
if
(
!
pedantic
)
return
rest
;
}
#if 0 /* this requires a gcc backend patch to export warn_if_unused_value */
else if (warn_unused)
warn_if_unused_value (TREE_VALUE(list));
#endif
return
build
(
COMPOUND_EXPR
,
TREE_TYPE
(
rest
),
break_out_cleanups
(
TREE_VALUE
(
list
)),
rest
);
...
...
@@ -5629,8 +5562,6 @@ build_modify_expr (lhs, modifycode, rhs)
cp_error
(
"`%T' does not define operator="
,
lhstype
);
else
if
(
!
TYPE_HAS_REAL_ASSIGNMENT
(
lhstype
)
&&
!
TYPE_HAS_COMPLEX_ASSIGN_REF
(
lhstype
)
/* FIXME find some way to deal with TARGET_EXPRs here. */
&&
TREE_CODE
(
newrhs
)
!=
TARGET_EXPR
&&
TYPE_MAIN_VARIANT
(
lhstype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
newrhs
)))
/* Do the default thing */
;
else
...
...
@@ -5697,7 +5628,11 @@ build_modify_expr (lhs, modifycode, rhs)
newrhs
=
build_binary_op
(
modifycode
,
lhs
,
rhs_tmp
,
1
);
}
else
return
error_mark_node
;
{
cp_error
(
"no match for `%O(%#T, %#T)'"
,
modifycode
,
TREE_TYPE
(
lhs
),
TREE_TYPE
(
rhs
));
return
error_mark_node
;
}
}
else
{
...
...
@@ -6008,18 +5943,32 @@ build_modify_expr (lhs, modifycode, rhs)
}
else
newrhs
=
convert_for_assignment
(
lhstype
,
newrhs
,
"assignment"
,
NULL_TREE
,
0
);
if
(
flag_elide_constructors
==
0
&&
TREE_CODE
(
newrhs
)
==
CALL_EXPR
&&
TREE_ADDRESSABLE
(
lhstype
))
NULL_TREE
,
0
);
if
(
TREE_CODE
(
newrhs
)
==
CALL_EXPR
&&
TYPE_NEEDS_CONSTRUCTING
(
lhstype
))
newrhs
=
build_cplus_new
(
lhstype
,
newrhs
,
0
);
if
(
TREE_CODE
(
newrhs
)
==
TARGET_EXPR
)
{
/* Can't initialized directly from a CALL_EXPR, since
we don't know about what doesn't alias what. */
/* Can't initialize directly from a TARGET_EXPR, since that would
cause the lhs to be constructed twice. So we force the
TARGET_EXPR to be expanded. expand_expr should really do this
by itself. */
tree
xval
=
make_node
(
RTL_EXPR
);
rtx
rtxval
;
tree
temp
=
get_temp_name
(
lhstype
,
0
);
newrhs
=
build
(
COMPOUND_EXPR
,
lhstype
,
build_modify_expr
(
temp
,
INIT_EXPR
,
newrhs
),
temp
);
do_pending_stack_adjust
();
start_sequence_for_rtl_expr
(
xval
);
emit_note
(
0
,
-
1
);
rtxval
=
expand_expr
(
newrhs
,
NULL
,
VOIDmode
,
0
);
do_pending_stack_adjust
();
TREE_SIDE_EFFECTS
(
xval
)
=
1
;
RTL_EXPR_SEQUENCE
(
xval
)
=
get_insns
();
end_sequence
();
RTL_EXPR_RTL
(
xval
)
=
rtxval
;
TREE_TYPE
(
xval
)
=
lhstype
;
newrhs
=
xval
;
}
}
...
...
@@ -6172,7 +6121,7 @@ get_delta_difference (from, to, force)
}
if
(
TREE_VIA_VIRTUAL
(
binfo
))
{
warning
(
"pointer to member conversion to virtual base class will only work if you
r
very careful"
);
warning
(
"pointer to member conversion to virtual base class will only work if you
are
very careful"
);
}
return
build_binary_op
(
MINUS_EXPR
,
integer_zero_node
,
...
...
@@ -6180,7 +6129,7 @@ get_delta_difference (from, to, force)
}
if
(
TREE_VIA_VIRTUAL
(
binfo
))
{
warning
(
"pointer to member conversion from virtual base class will only work if you
r
very careful"
);
warning
(
"pointer to member conversion from virtual base class will only work if you
are
very careful"
);
}
return
BINFO_OFFSET
(
binfo
);
}
...
...
@@ -6241,7 +6190,7 @@ build_ptrmemfunc (type, pfn, force)
force
);
delta
=
build_binary_op
(
PLUS_EXPR
,
delta
,
ndelta
,
1
);
delta2
=
build_binary_op
(
PLUS_EXPR
,
ndelta2
,
delta2
,
1
);
e1
=
fold
(
build
(
GT_EXPR
,
integer
_type_node
,
index
,
integer_zero_node
));
e1
=
fold
(
build
(
GT_EXPR
,
boolean
_type_node
,
index
,
integer_zero_node
));
u
=
build_nt
(
CONSTRUCTOR
,
0
,
tree_cons
(
delta2_identifier
,
delta2
,
NULL_TREE
));
u
=
build_nt
(
CONSTRUCTOR
,
0
,
tree_cons
(
NULL_TREE
,
delta
,
...
...
gcc/cp/typeck2.c
View file @
b7484fbe
...
...
@@ -329,7 +329,7 @@ ack (s, v, v2)
silly. So instead, we just do the equivalent of a call to fatal in the
same situation (call exit). */
/* First used: 0 (reserved), Last used: 36
4
. Free: */
/* First used: 0 (reserved), Last used: 36
6
. Free: */
static
int
abortcount
=
0
;
...
...
@@ -855,6 +855,14 @@ digest_init (type, init, tail)
}
init
=
element
;
}
while
(
TREE_CODE
(
init
)
==
CONSTRUCTOR
)
{
cp_pedwarn
(
"braces around scalar initializer for `%T'"
,
type
);
init
=
CONSTRUCTOR_ELTS
(
init
);
if
(
TREE_CHAIN
(
init
))
cp_pedwarn
(
"ignoring extra initializers for `%T'"
,
type
);
init
=
TREE_VALUE
(
init
);
}
return
convert_for_initialization
(
0
,
type
,
init
,
LOOKUP_NORMAL
,
"initialization"
,
NULL_TREE
,
0
);
...
...
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