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)
Tue Mar 7 10:14:29 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* parse.y: New rules to allow attributes in a prefix position.
* 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)
...
@@ -10,6 +87,234 @@ Tue Mar 7 10:14:29 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
(grokdeclarator): Added code to support machine attributes.
(grokdeclarator): Added code to support machine attributes.
* Makefile.in (stamp-parse): Expect 5 shift/reduce failures.
* 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)
Tue Feb 21 18:43:48 1995 Douglas Rupp (drupp@cs.washington.edu)
* Make-lang.in, config-lang.in: ($exeext): New macro.
* 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)
...
@@ -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.
* 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.
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.
* method.c (synthesize_method): Set interface_{unknown,only}
* cvt.c (build_up_reference): Bash the types bashed by
according to the settings for our class, not the file where it comes
build_vbase_path to be reference types instead of pointer types.
from.
(convert_to_reference): Ditto.
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.
* except.c: Handle systems that define __i386__ but not __i386.
* typeck2.c (store_init_value): Likewise.
Fri Feb 17 15:31:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
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>
...
@@ -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
* typeck2.c (build_functional_cast): Don't assume that a NOP_EXPR
will suffice to convert from integer_zero_node.
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>
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
* 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)
...
@@ -4034,11 +4373,6 @@ Fri Apr 22 03:27:26 1994 Doug Evans (dje@cygnus.com)
* Language directory reorganization.
* Language directory reorganization.
See parent makefile.
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)
Thu Apr 21 18:27:57 1994 Per Bothner (bothner@kalessin.cygnus.com)
* cp-tree.h (THUNK_DELTA): It is normally negative, so
* 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
...
@@ -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)
\
$(CC)
-c
$(ALL_CFLAGS)
$(ALL_CPPFLAGS)
$(INCLUDES)
$(BIG_SWITCHFLAG)
\
`
echo
$(PARSE_C)
| sed
's,^\./,,'
`
`
echo
$(PARSE_C)
| sed
's,^\./,,'
`
CONFLICTS
=
expect 5
shift
/reduce confict and 38 reduce/reduce conflicts.
$(PARSE_H)
:
$(PARSE_C)
$(PARSE_H)
:
$(PARSE_C)
$(PARSE_C)
:
$(srcdir)/parse.y
$(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)
;
$(BISON)
$(BISONFLAGS)
-d
-o
parse.c parse.y
cd
$(srcdir)
;
grep
'^#define[ ]*YYEMPTY'
parse.c
>>
parse.h
cd
$(srcdir)
;
grep
'^#define[ ]*YYEMPTY'
parse.c
>>
parse.h
#$(PARSE_C) $(PARSE_H) : stamp-parse ; @true
#$(PARSE_C) $(PARSE_H) : stamp-parse ; @true
#stamp-parse: $(srcdir)/parse.y
#stamp-parse: $(srcdir)/parse.y
# @echo
expect 1 shift/reduce confict and 39 reduce/reduce conflicts.
# @echo
$(CONFLICTS)
# $(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y
# $(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y
# grep '^#define[ ]*YYEMPTY' y.tab.c >>y.tab.h
# grep '^#define[ ]*YYEMPTY' y.tab.c >>y.tab.h
# $(srcdir)/../move-if-change y.tab.c $(PARSE_C)
# $(srcdir)/../move-if-change y.tab.c $(PARSE_C)
...
...
gcc/cp/call.c
View file @
b7484fbe
...
@@ -593,6 +593,15 @@ can_convert (to, from)
...
@@ -593,6 +593,15 @@ can_convert (to, from)
return
h
.
code
<
USER_CODE
;
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
#ifdef DEBUG_MATCHING
static
char
*
static
char
*
print_harshness
(
h
)
print_harshness
(
h
)
...
@@ -2371,9 +2380,12 @@ build_method_call (instance, name, parms, basetype_path, flags)
...
@@ -2371,9 +2380,12 @@ build_method_call (instance, name, parms, basetype_path, flags)
assemble_external
(
function
);
assemble_external
(
function
);
#if 0
#if 0
/* Is it a synthesized method that needs to be synthesized? */
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
&& DECL_SAVED_INSNS (function) == 0
&& 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);
synthesize_method (function);
#endif
#endif
...
...
gcc/cp/class.c
View file @
b7484fbe
...
@@ -240,7 +240,7 @@ build_vbase_path (code, type, expr, path, alias_this)
...
@@ -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
);
null_expr
=
build1
(
NOP_EXPR
,
TYPE_POINTER_TO
(
last_virtual
),
integer_zero_node
);
expr
=
build
(
COND_EXPR
,
TYPE_POINTER_TO
(
last_virtual
),
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
),
integer_zero_node
),
null_expr
,
nonnull_expr
);
null_expr
,
nonnull_expr
);
}
}
...
@@ -323,7 +323,7 @@ build_vbase_path (code, type, expr, path, alias_this)
...
@@ -323,7 +323,7 @@ build_vbase_path (code, type, expr, path, alias_this)
expr
=
save_expr
(
expr
);
expr
=
save_expr
(
expr
);
return
build
(
COND_EXPR
,
type
,
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
,
null_expr
,
build
(
code
,
type
,
expr
,
offset
));
build
(
code
,
type
,
expr
,
offset
));
}
}
...
@@ -490,11 +490,12 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
...
@@ -490,11 +490,12 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
return
aref
;
return
aref
;
else
else
{
{
*
ptr_to_instptr
if
(
ptr_to_instptr
)
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
*
ptr_to_instptr
),
*
ptr_to_instptr
*
ptr_to_instptr
,
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
*
ptr_to_instptr
),
convert
(
ptrdiff_type_node
,
*
ptr_to_instptr
,
build_component_ref
(
aref
,
delta_identifier
,
0
,
0
)));
convert
(
ptrdiff_type_node
,
build_component_ref
(
aref
,
delta_identifier
,
0
,
0
)));
return
build_component_ref
(
aref
,
pfn_identifier
,
0
,
0
);
return
build_component_ref
(
aref
,
pfn_identifier
,
0
,
0
);
}
}
}
}
...
@@ -2020,6 +2021,7 @@ duplicate_tag_error (t)
...
@@ -2020,6 +2021,7 @@ duplicate_tag_error (t)
tree
t
;
tree
t
;
{
{
cp_error
(
"redefinition of `%#T'"
,
t
);
cp_error
(
"redefinition of `%#T'"
,
t
);
cp_error_at
(
"previous definition here"
,
t
);
/* Pretend we haven't defined this type. */
/* 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 */
...
@@ -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 \
#define CONV_C_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \
| CONV_REINTERPRET | CONV_PRIVATE | CONV_FORCE_TEMP)
| 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):
/* Anatomy of a DECL_FRIENDLIST (which is a TREE_LIST):
purpose = friend name (IDENTIFIER_NODE);
purpose = friend name (IDENTIFIER_NODE);
value = TREE_LIST of FUNCTION_DECLS;
value = TREE_LIST of FUNCTION_DECLS;
...
@@ -1913,8 +1924,8 @@ extern tree convert PROTO((tree, tree));
...
@@ -1913,8 +1924,8 @@ extern tree convert PROTO((tree, tree));
extern
tree
cp_convert
PROTO
((
tree
,
tree
,
int
,
int
));
extern
tree
cp_convert
PROTO
((
tree
,
tree
,
int
,
int
));
extern
tree
convert_force
PROTO
((
tree
,
tree
,
int
));
extern
tree
convert_force
PROTO
((
tree
,
tree
,
int
));
extern
tree
build_type_conversion
PROTO
((
enum
tree_code
,
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_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
));
extern
tree
type_promotes_to
PROTO
((
tree
));
/* decl.c */
/* decl.c */
...
@@ -2042,9 +2053,10 @@ extern tree get_namespace_id PROTO((void));
...
@@ -2042,9 +2053,10 @@ extern tree get_namespace_id PROTO((void));
/* in edsel.c */
/* in edsel.c */
/* in except.c */
/* in except.c */
extern
tree
protect_list
;
extern
void
start_protect
PROTO
((
void
));
extern
void
start_protect
PROTO
((
void
));
extern
void
end_protect
PROTO
((
tree
));
extern
void
end_protect
PROTO
((
tree
));
extern
void
end_protect_partials
();
extern
void
expand_exception_blocks
PROTO
((
void
));
extern
void
expand_exception_blocks
PROTO
((
void
));
extern
void
expand_start_try_stmts
PROTO
((
void
));
extern
void
expand_start_try_stmts
PROTO
((
void
));
extern
void
expand_end_try_stmts
PROTO
((
void
));
extern
void
expand_end_try_stmts
PROTO
((
void
));
...
@@ -2053,7 +2065,8 @@ extern void expand_end_all_catch PROTO((void));
...
@@ -2053,7 +2065,8 @@ extern void expand_end_all_catch PROTO((void));
extern
void
start_catch_block
PROTO
((
tree
,
tree
));
extern
void
start_catch_block
PROTO
((
tree
,
tree
));
extern
void
end_catch_block
PROTO
((
void
));
extern
void
end_catch_block
PROTO
((
void
));
extern
void
expand_throw
PROTO
((
tree
));
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
tree
build_throw
PROTO
((
tree
));
extern
void
init_exception_processing
PROTO
((
void
));
extern
void
init_exception_processing
PROTO
((
void
));
...
@@ -2093,7 +2106,7 @@ extern tree get_type_value PROTO((tree));
...
@@ -2093,7 +2106,7 @@ extern tree get_type_value PROTO((tree));
extern
tree
build_member_call
PROTO
((
tree
,
tree
,
tree
));
extern
tree
build_member_call
PROTO
((
tree
,
tree
,
tree
));
extern
tree
build_offset_ref
PROTO
((
tree
,
tree
));
extern
tree
build_offset_ref
PROTO
((
tree
,
tree
));
extern
tree
get_member_function
PROTO
((
tree
*
,
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
resolve_offset_ref
PROTO
((
tree
));
extern
tree
decl_constant_value
PROTO
((
tree
));
extern
tree
decl_constant_value
PROTO
((
tree
));
extern
int
is_friend_type
PROTO
((
tree
,
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)
...
@@ -903,6 +903,7 @@ convert_to_aggr (type, expr, msgp, protect)
parmlist
=
tree_cons
(
NULL_TREE
,
integer_zero_node
,
parmlist
);
parmlist
=
tree_cons
(
NULL_TREE
,
integer_zero_node
,
parmlist
);
parmtypes
=
tree_cons
(
NULL_TREE
,
TYPE_POINTER_TO
(
basetype
),
parmtypes
);
parmtypes
=
tree_cons
(
NULL_TREE
,
TYPE_POINTER_TO
(
basetype
),
parmtypes
);
#if 0
method_name = build_decl_overload (name, parmtypes, 1);
method_name = build_decl_overload (name, parmtypes, 1);
/* constructors are up front. */
/* constructors are up front. */
...
@@ -936,6 +937,7 @@ convert_to_aggr (type, expr, msgp, protect)
...
@@ -936,6 +937,7 @@ convert_to_aggr (type, expr, msgp, protect)
}
}
fndecl = DECL_CHAIN (fndecl);
fndecl = DECL_CHAIN (fndecl);
}
}
#endif
/* No exact conversion was found. See if an approximate
/* No exact conversion was found. See if an approximate
one will do. */
one will do. */
...
@@ -1548,7 +1550,7 @@ build_type_conversion (code, xtype, expr, for_sure)
...
@@ -1548,7 +1550,7 @@ build_type_conversion (code, xtype, expr, for_sure)
{
{
cp_error
(
"ambiguous conversion from `%T' to `%T'"
,
basetype
,
cp_error
(
"ambiguous conversion from `%T' to `%T'"
,
basetype
,
xtype
);
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
));
TREE_VALUE
(
winner
),
TREE_VALUE
(
conv
));
return
NULL_TREE
;
return
NULL_TREE
;
}
}
...
@@ -1564,154 +1566,228 @@ build_type_conversion (code, xtype, expr, for_sure)
...
@@ -1564,154 +1566,228 @@ build_type_conversion (code, xtype, expr, for_sure)
return
NULL_TREE
;
return
NULL_TREE
;
}
}
/*
Must convert two aggregate types to non-aggregate type.
/*
Convert the given EXPR to one of a group of types suitable for use in an
Attempts to find a non-ambiguous, "best" type conversion.
expression. DESIRES is a combination of various WANT_* flags (q.v.)
which indicates which types are suitable. If COMPLAIN is 1, complain
Return 1 on success, 0 on failure.
about ambiguity; otherwise, the caller will deal with it. */
@@ What are the real semantics of this supposed to be??? */
tree
int
build_expr_type_conversion
(
desires
,
expr
,
complain
)
build_default_binary_type_conversion
(
code
,
arg1
,
arg2
)
int
desires
;
enum
tree_code
code
;
tree
expr
;
tree
*
arg1
,
*
arg2
;
int
complain
;
{
{
tree
type1
=
TREE_TYPE
(
*
arg1
);
tree
basetype
=
TREE_TYPE
(
expr
);
tree
type2
=
TREE_TYPE
(
*
arg2
);
tree
conv
;
tree
winner
=
NULL_TREE
;
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
);
if
(
TREE_CODE
(
TYPE_NAME
(
type1
))
!=
TYPE_DECL
)
if
(
TREE_CODE
(
basetype
)
==
OFFSET_TYPE
)
{
{
tree
decl
=
typedecl_for_tag
(
type1
);
expr
=
resolve_offset_ref
(
expr
);
if
(
decl
)
basetype
=
TREE_TYPE
(
expr
);
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
;
}
}
if
(
!
IS_AGGR_TYPE
(
type1
)
||
!
TYPE_HAS_CONVERSION
(
type1
))
if
(
!
IS_AGGR_TYPE
(
basetype
))
{
switch
(
TREE_CODE
(
basetype
))
if
(
!
IS_AGGR_TYPE
(
type2
)
||
!
TYPE_HAS_CONVERSION
(
type2
))
{
cp_error
(
"no conversion from `%T' and `%T' to types with default `%O' "
,
case
INTEGER_TYPE
:
type1
,
type2
,
code
);
if
((
desires
&
WANT_NULL
)
&&
TREE_CODE
(
expr
)
==
INTEGER_CST
else
&&
integer_zerop
(
expr
))
cp_error
(
"no conversion from `%T' to type with default `%O'"
,
return
expr
;
type1
,
code
);
/* else fall through... */
return
0
;
}
case
BOOLEAN_TYPE
:
else
if
(
!
IS_AGGR_TYPE
(
type2
)
||
!
TYPE_HAS_CONVERSION
(
type2
))
return
(
desires
&
WANT_INT
)
?
expr
:
NULL_TREE
;
{
case
ENUMERAL_TYPE
:
cp_error
(
"no conversion from `%T' to type with default `%O'"
,
return
(
desires
&
WANT_ENUM
)
?
expr
:
NULL_TREE
;
type2
,
code
);
case
REAL_TYPE
:
return
0
;
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
if
(
!
TYPE_HAS_CONVERSION
(
basetype
))
||
code
==
TRUTH_ORIF_EXPR
)
return
NULL_TREE
;
{
*
arg1
=
convert
(
boolean_type_node
,
*
arg1
);
for
(
conv
=
lookup_conversions
(
basetype
);
conv
;
conv
=
TREE_CHAIN
(
conv
))
*
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
)
{
{
cp_error
(
"default type conversion for type `%T' failed"
,
type2
);
int
win
=
0
;
return
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.
Attempts to find a non-ambiguous, "best" type conversion.
Return 1 on success, 0 on failure.
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??? */
@@ What are the real semantics of this supposed to be??? */
int
int
build_default_
unary_type_conversion
(
code
,
arg
)
build_default_
binary_type_conversion
(
code
,
arg1
,
arg2
)
enum
tree_code
code
;
enum
tree_code
code
;
tree
*
arg
;
tree
*
arg
1
,
*
arg2
;
{
{
tree
type
=
TREE_TYPE
(
*
arg
);
switch
(
code
)
if
(
!
TYPE_HAS_CONVERSION
(
type
))
{
{
cp_error
(
"type conversion required for type `%T'"
,
type
);
case
MULT_EXPR
:
return
0
;
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
)
case
TRUNC_MOD_EXPR
:
*
arg
=
convert
(
boolean_type_node
,
*
arg
);
case
FLOOR_MOD_EXPR
:
else
if
(
TYPE_HAS_INT_CONVERSION
(
type
))
case
LSHIFT_EXPR
:
{
case
RSHIFT_EXPR
:
if
(
TYPE_HAS_REAL_CONVERSION
(
type
))
case
BIT_AND_EXPR
:
cp_pedwarn
(
"ambiguous type conversion for type `%T', defaulting to int"
,
case
BIT_XOR_EXPR
:
type
);
case
BIT_IOR_EXPR
:
*
arg
=
build_type_conversion
(
code
,
integer_type_node
,
*
arg
,
1
);
*
arg1
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
*
arg1
,
0
);
}
*
arg2
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
*
arg2
,
0
);
else
if
(
TYPE_HAS_REAL_CONVERSION
(
type
))
break
;
*
arg
=
build_type_conversion
(
code
,
double_type_node
,
*
arg
,
1
);
else
case
PLUS_EXPR
:
{
{
*
arg
=
build_type_conversion
(
code
,
ptr_type_node
,
*
arg
,
1
);
tree
a1
,
a2
,
p1
,
p2
;
if
(
*
arg
==
error_mark_node
)
int
wins
;
error
(
"ambiguous pointer conversion"
);
}
a1
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg1
,
0
);
if
(
*
arg
==
NULL_TREE
)
a2
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
*
arg2
,
0
);
{
p1
=
build_expr_type_conversion
(
WANT_POINTER
,
*
arg1
,
0
);
cp_error
(
"default type conversion for type `%T' failed"
,
type
);
p2
=
build_expr_type_conversion
(
WANT_POINTER
,
*
arg2
,
0
);
return
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. */
/* 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)
...
@@ -1664,13 +1664,10 @@ set_nested_typename (decl, classname, name, type)
type_decl
=
build_decl
(
TYPE_DECL
,
nested
,
type
);
type_decl
=
build_decl
(
TYPE_DECL
,
nested
,
type
);
DECL_NESTED_TYPENAME
(
type_decl
)
=
nested
;
DECL_NESTED_TYPENAME
(
type_decl
)
=
nested
;
SET_DECL_ARTIFICIAL
(
type_decl
);
SET_DECL_ARTIFICIAL
(
type_decl
);
#ifdef DWARF_DEBUGGING_INFO
/* Mark the TYPE_DECL node created just above as a gratuitous one so that
/* Mark the TYPE_DECL node created just above as a
dwarfout.c will know not to generate a TAG_typedef DIE for it, and
gratuitous one so that dwarfout.c will know not to
sdbout.c won't try to output a .def for "::foo". */
generate a TAG_typedef DIE for it. */
DECL_IGNORED_P
(
type_decl
)
=
1
;
if
(
write_symbols
==
DWARF_DEBUG
)
DECL_IGNORED_P
(
type_decl
)
=
1
;
#endif
/* DWARF_DEBUGGING_INFO */
/* Remove this when local classes are fixed. */
/* Remove this when local classes are fixed. */
SET_IDENTIFIER_TYPE_VALUE
(
nested
,
type
);
SET_IDENTIFIER_TYPE_VALUE
(
nested
,
type
);
...
@@ -2447,21 +2444,16 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2447,21 +2444,16 @@ duplicate_decls (newdecl, olddecl)
TREE_TYPE
(
newdecl
)
=
TREE_TYPE
(
olddecl
)
=
newtype
;
TREE_TYPE
(
newdecl
)
=
TREE_TYPE
(
olddecl
)
=
newtype
;
/* Lay the type out, unless already done. */
/* Lay the type out, unless already done. */
if
(
oldtype
!=
TREE_TYPE
(
newdecl
))
if
(
oldtype
!=
TREE_TYPE
(
newdecl
)
{
&&
TREE_TYPE
(
newdecl
)
!=
error_mark_node
)
if
(
TREE_TYPE
(
newdecl
)
!=
error_mark_node
)
layout_type
(
TREE_TYPE
(
newdecl
));
layout_type
(
TREE_TYPE
(
newdecl
));
if
(
TREE_CODE
(
newdecl
)
!=
FUNCTION_DECL
if
(
TREE_CODE
(
newdecl
)
==
VAR_DECL
&&
TREE_CODE
(
newdecl
)
!=
TYPE_DECL
||
TREE_CODE
(
newdecl
)
==
PARM_DECL
&&
TREE_CODE
(
newdecl
)
!=
CONST_DECL
||
TREE_CODE
(
newdecl
)
==
RESULT_DECL
&&
TREE_CODE
(
newdecl
)
!=
TEMPLATE_DECL
)
||
TREE_CODE
(
newdecl
)
==
FIELD_DECL
layout_decl
(
newdecl
,
0
);
||
TREE_CODE
(
newdecl
)
==
TYPE_DECL
)
}
layout_decl
(
newdecl
,
0
);
else
{
/* Since the type is OLDDECL's, make OLDDECL's size go with. */
DECL_SIZE
(
newdecl
)
=
DECL_SIZE
(
olddecl
);
}
/* Merge the type qualifiers. */
/* Merge the type qualifiers. */
if
(
TREE_READONLY
(
newdecl
))
if
(
TREE_READONLY
(
newdecl
))
...
@@ -7660,7 +7652,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7660,7 +7652,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
TREE_CODE
(
type
)
==
REAL_TYPE
)
if
(
TREE_CODE
(
type
)
==
REAL_TYPE
)
error
(
"short, signed or unsigned invalid for `%s'"
,
name
);
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
);
error
(
"long, short, signed or unsigned invalid for `%s'"
,
name
);
else
if
(
RIDBIT_SETP
(
RID_LONG
,
specbits
)
else
if
(
RIDBIT_SETP
(
RID_LONG
,
specbits
)
&&
RIDBIT_SETP
(
RID_SHORT
,
specbits
))
&&
RIDBIT_SETP
(
RID_SHORT
,
specbits
))
...
@@ -7780,6 +7772,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7780,6 +7772,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
error
(
"non-object member `%s' cannot be declared `mutable'"
,
name
);
error
(
"non-object member `%s' cannot be declared `mutable'"
,
name
);
RIDBIT_RESET
(
RID_MUTABLE
,
specbits
);
RIDBIT_RESET
(
RID_MUTABLE
,
specbits
);
}
}
else
if
(
constp
)
{
error
(
"const `%s' cannot be declared `mutable'"
,
name
);
RIDBIT_RESET
(
RID_MUTABLE
,
specbits
);
}
else
if
(
staticp
)
else
if
(
staticp
)
{
{
error
(
"static `%s' cannot be declared `mutable'"
,
name
);
error
(
"static `%s' cannot be declared `mutable'"
,
name
);
...
@@ -7820,7 +7817,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7820,7 +7817,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
}
/* Give error if `virtual' is used outside of class declaration. */
/* 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"
);
error
(
"virtual outside class declaration"
);
virtualp
=
0
;
virtualp
=
0
;
...
@@ -7972,14 +7970,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7972,14 +7970,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
{
{
if
(
decl_context
==
FIELD
)
if
(
decl_context
==
FIELD
)
{
{
tree
tmp
=
TREE_OPERAND
(
declarator
,
0
);
tree
tmp
=
NULL_TREE
;
register
int
op
=
IDENTIFIER_OPNAME_P
(
tmp
);
register
int
op
=
0
;
if
(
declarator
)
{
tmp
=
TREE_OPERAND
(
declarator
,
0
);
op
=
IDENTIFIER_OPNAME_P
(
tmp
);
}
error
(
"storage class specified for %s `%s'"
,
error
(
"storage class specified for %s `%s'"
,
IS_SIGNATURE
(
current_class_type
)
IS_SIGNATURE
(
current_class_type
)
?
(
op
?
(
op
?
"signature member operator"
?
"signature member operator"
:
"signature member function"
)
:
"signature member function"
)
:
(
op
?
"member operator"
:
"
structure
field"
),
:
(
op
?
"member operator"
:
"field"
),
op
?
operator_name_string
(
tmp
)
:
name
);
op
?
operator_name_string
(
tmp
)
:
name
);
}
}
else
else
...
@@ -8092,6 +8096,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8092,6 +8096,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
{
{
register
tree
itype
=
NULL_TREE
;
register
tree
itype
=
NULL_TREE
;
register
tree
size
=
TREE_OPERAND
(
declarator
,
1
);
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
);
declarator
=
TREE_OPERAND
(
declarator
,
0
);
...
@@ -8181,8 +8187,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8181,8 +8187,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
cp_error
(
"size of array `%D' is negative"
,
dname
);
cp_error
(
"size of array `%D' is negative"
,
dname
);
size
=
integer_one_node
;
size
=
integer_one_node
;
}
}
itype
=
build_index_type
(
size_binop
(
MINUS_EXPR
,
size
,
integer_one_node
));
}
}
else
else
{
{
...
@@ -8194,15 +8198,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8194,15 +8198,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
else
else
cp_pedwarn
(
"ANSI C++ forbids variable-size array"
);
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
/* 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
;
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
);
resume_momentary
(
yes
);
}
}
...
@@ -8262,10 +8271,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8262,10 +8271,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
inner_decl
&&
TREE_CODE
(
inner_decl
)
==
SCOPE_REF
)
if
(
inner_decl
&&
TREE_CODE
(
inner_decl
)
==
SCOPE_REF
)
inner_decl
=
TREE_OPERAND
(
inner_decl
,
1
);
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
/* Say it's a definition only for the CALL_EXPR
closest to the identifier. */
closest to the identifier. */
funcdecl_p
=
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
if
(
ctype
==
NULL_TREE
&&
decl_context
==
FIELD
&&
decl_context
==
FIELD
...
@@ -8289,14 +8302,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8289,14 +8302,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
may not be static. */
may not be static. */
if
(
staticp
==
2
)
if
(
staticp
==
2
)
error
(
"destructor cannot be static member function"
);
error
(
"destructor cannot be static member function"
);
if
(
TYPE_READONLY
(
type
))
if
(
quals
)
{
error
(
"destructors cannot be declared `const'"
);
return
void_type_node
;
}
if
(
TYPE_VOLATILE
(
type
))
{
{
error
(
"destructors cannot be declared `volatile'"
);
error
(
"destructors cannot be declared `
const' or `
volatile'"
);
return
void_type_node
;
return
void_type_node
;
}
}
if
(
decl_context
==
FIELD
)
if
(
decl_context
==
FIELD
)
...
@@ -8320,16 +8328,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8320,16 +8328,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
pedwarn
(
"constructors cannot be declared virtual"
);
pedwarn
(
"constructors cannot be declared virtual"
);
virtualp
=
0
;
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
;
return
void_type_node
;
}
}
if
(
TYPE_VOLATILE
(
type
))
{
error
(
"constructors cannot be declared `volatile'"
);
return
void_type_node
;
}
{
{
RID_BIT_TYPE
tmp_bits
;
RID_BIT_TYPE
tmp_bits
;
bcopy
((
void
*
)
&
specbits
,
(
void
*
)
&
tmp_bits
,
sizeof
(
RID_BIT_TYPE
));
bcopy
((
void
*
)
&
specbits
,
(
void
*
)
&
tmp_bits
,
sizeof
(
RID_BIT_TYPE
));
...
@@ -8358,20 +8361,22 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8358,20 +8361,22 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
decl_context
==
FIELD
)
if
(
decl_context
==
FIELD
)
staticp
=
0
;
staticp
=
0
;
}
}
else
if
(
friendp
&&
virtualp
)
else
if
(
friendp
)
{
{
/* Cannot be both friend and virtual. */
if
(
initialized
)
error
(
"virtual functions cannot be friends"
);
error
(
"can't initialize friend function `%s'"
,
name
);
RIDBIT_RESET
(
RID_FRIEND
,
specbits
);
if
(
virtualp
)
friendp
=
0
;
{
/* Cannot be both friend and virtual. */
error
(
"virtual functions cannot be friends"
);
RIDBIT_RESET
(
RID_FRIEND
,
specbits
);
friendp
=
0
;
}
}
}
if
(
decl_context
==
NORMAL
&&
friendp
)
if
(
decl_context
==
NORMAL
&&
friendp
)
error
(
"friend declaration not in class definition"
);
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. */
/* Traditionally, declaring return type float means double. */
if
(
flag_traditional
if
(
flag_traditional
...
@@ -8836,13 +8841,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8836,13 +8841,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
/* Special case: "friend class foo" looks like a TYPENAME context. */
/* Special case: "friend class foo" looks like a TYPENAME context. */
if
(
friendp
)
if
(
friendp
)
{
{
/* A friendly class? */
if
(
volatilep
)
if
(
current_class_type
)
{
make_friend_class
(
current_class_type
,
TYPE_MAIN_VARIANT
(
type
));
cp_error
(
"`volatile' specified for friend class declaration"
);
else
volatilep
=
0
;
error
(
"trying to make class `%s' a friend of global scope"
,
}
TYPE_NAME_STRING
(
type
));
if
(
inlinep
)
type
=
void_type_node
;
{
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
)
else
if
(
quals
)
{
{
...
@@ -8878,7 +8898,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8878,7 +8898,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
TYPE_MAIN_VARIANT
(
type
)
==
void_type_node
&&
decl_context
!=
PARM
)
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
(
IDENTIFIER_OPNAME_P
(
declarator
))
#if 0 /* How could this happen? */
#if 0 /* How could this happen? */
...
@@ -8921,6 +8943,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8921,6 +8943,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
type
=
build_pointer_type
(
type
);
type
=
build_pointer_type
(
type
);
else
if
(
TREE_CODE
(
type
)
==
OFFSET_TYPE
)
else
if
(
TREE_CODE
(
type
)
==
OFFSET_TYPE
)
type
=
build_pointer_type
(
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
);
decl
=
build_decl
(
PARM_DECL
,
declarator
,
type
);
...
@@ -9030,7 +9057,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -9030,7 +9057,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
else
if
(
TYPE_SIZE
(
type
)
==
NULL_TREE
&&
!
staticp
else
if
(
TYPE_SIZE
(
type
)
==
NULL_TREE
&&
!
staticp
&&
(
TREE_CODE
(
type
)
!=
ARRAY_TYPE
||
initialized
==
0
))
&&
(
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
/* If we're instantiating a template, tell them which
instantiation made the field's type be incomplete. */
instantiation made the field's type be incomplete. */
...
@@ -9302,6 +9332,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -9302,6 +9332,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
staticp
=
0
;
staticp
=
0
;
RIDBIT_RESET
(
RID_STATIC
,
specbits
);
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
))
if
(
RIDBIT_SETP
(
RID_EXTERN
,
specbits
))
{
{
cp_error
(
"cannot explicitly declare member `%#D' to have extern linkage"
,
cp_error
(
"cannot explicitly declare member `%#D' to have extern linkage"
,
...
@@ -9583,7 +9618,8 @@ grokparms (first_parm, funcdef_flag)
...
@@ -9583,7 +9618,8 @@ grokparms (first_parm, funcdef_flag)
any_init
++
;
any_init
++
;
if
(
TREE_CODE
(
init
)
==
SAVE_EXPR
)
if
(
TREE_CODE
(
init
)
==
SAVE_EXPR
)
PARM_DECL_EXPR
(
init
)
=
1
;
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
)))
if
(
IDENTIFIER_LOCAL_VALUE
(
DECL_NAME
(
init
)))
{
{
...
@@ -10656,6 +10692,8 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
...
@@ -10656,6 +10692,8 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
original_result_rtx
=
NULL_RTX
;
original_result_rtx
=
NULL_RTX
;
current_function_obstack_index
=
0
;
current_function_obstack_index
=
0
;
current_function_obstack_usage
=
0
;
current_function_obstack_usage
=
0
;
base_init_insns
=
NULL_RTX
;
protect_list
=
NULL_TREE
;
clear_temp_name
();
clear_temp_name
();
...
@@ -10751,7 +10789,7 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
...
@@ -10751,7 +10789,7 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
if
(
TREE_TYPE
(
TREE_TYPE
(
decl1
))
!=
integer_type_node
)
if
(
TREE_TYPE
(
TREE_TYPE
(
decl1
))
!=
integer_type_node
)
{
{
if
(
pedantic
||
warn_return_type
)
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
;
TREE_TYPE
(
decl1
)
=
fntype
=
default_function_type
;
}
}
warn_about_return_type
=
0
;
warn_about_return_type
=
0
;
...
@@ -10795,6 +10833,10 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
...
@@ -10795,6 +10833,10 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
DECL_RESULT
(
decl1
)
=
build_decl
(
RESULT_DECL
,
0
,
TREE_TYPE
(
fntype
));
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
)
if
(
warn_about_return_type
)
warning
(
"return-type defaults to `int'"
);
warning
(
"return-type defaults to `int'"
);
...
@@ -10824,14 +10866,19 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
...
@@ -10824,14 +10866,19 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
DECL_EXTERNAL
(
decl1
)
=
current_extern_inline
;
DECL_EXTERNAL
(
decl1
)
=
current_extern_inline
;
DECL_INTERFACE_KNOWN
(
decl1
)
=
1
;
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
else
{
{
/* This is a definition, not a reference.
/* This is a definition, not a reference.
So normally clear DECL_EXTERNAL.
So clear DECL_EXTERNAL. */
However, `extern inline' acts like a declaration except for
DECL_EXTERNAL
(
decl1
)
=
0
;
defining how to inline. So set DECL_EXTERNAL in that case. */
DECL_EXTERNAL
(
decl1
)
=
current_extern_inline
;
if
(
DECL_INLINE
(
decl1
)
&&
(
DECL_FUNCTION_MEMBER_P
(
decl1
)
if
(
DECL_INLINE
(
decl1
)
&&
(
DECL_FUNCTION_MEMBER_P
(
decl1
)
||
DECL_TEMPLATE_INSTANTIATION
(
decl1
)))
||
DECL_TEMPLATE_INSTANTIATION
(
decl1
)))
/* We know nothing yet */
;
/* We know nothing yet */
;
...
@@ -11423,6 +11470,7 @@ finish_function (lineno, call_poplevel, nested)
...
@@ -11423,6 +11470,7 @@ finish_function (lineno, call_poplevel, nested)
if
(
DECL_CONSTRUCTOR_P
(
current_function_decl
))
if
(
DECL_CONSTRUCTOR_P
(
current_function_decl
))
{
{
end_protect_partials
();
expand_label
(
ctor_label
);
expand_label
(
ctor_label
);
ctor_label
=
NULL_TREE
;
ctor_label
=
NULL_TREE
;
...
@@ -11503,6 +11551,8 @@ finish_function (lineno, call_poplevel, nested)
...
@@ -11503,6 +11551,8 @@ finish_function (lineno, call_poplevel, nested)
if
(
mark
!=
get_last_insn
())
if
(
mark
!=
get_last_insn
())
reorder_insns
(
next_insn
(
mark
),
get_last_insn
(),
last_parm_insn
);
reorder_insns
(
next_insn
(
mark
),
get_last_insn
(),
last_parm_insn
);
end_protect_partials
();
/* This is where the body of the constructor ends. */
/* This is where the body of the constructor ends. */
expand_label
(
ctor_label
);
expand_label
(
ctor_label
);
ctor_label
=
NULL_TREE
;
ctor_label
=
NULL_TREE
;
...
@@ -11643,8 +11693,14 @@ finish_function (lineno, call_poplevel, nested)
...
@@ -11643,8 +11693,14 @@ finish_function (lineno, call_poplevel, nested)
/* Run the optimizers and output the assembler code for this function. */
/* Run the optimizers and output the assembler code for this function. */
rest_of_compilation
(
fndecl
);
rest_of_compilation
(
fndecl
);
if
(
DECL_DEFER_OUTPUT
(
fndecl
))
if
(
DECL_SAVED_INSNS
(
fndecl
)
&&
!
TREE_ASM_WRITTEN
(
fndecl
))
mark_inline_for_output
(
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
))
if
(
ctype
&&
TREE_ASM_WRITTEN
(
fndecl
))
note_debug_info_needed
(
ctype
);
note_debug_info_needed
(
ctype
);
...
@@ -12121,7 +12177,9 @@ struct cp_function
...
@@ -12121,7 +12177,9 @@ struct cp_function
tree
shadowed_labels
;
tree
shadowed_labels
;
tree
ctor_label
;
tree
ctor_label
;
tree
dtor_label
;
tree
dtor_label
;
tree
protect_list
;
rtx
result_rtx
;
rtx
result_rtx
;
rtx
base_init_insns
;
struct
cp_function
*
next
;
struct
cp_function
*
next
;
struct
binding_level
*
binding_level
;
struct
binding_level
*
binding_level
;
};
};
...
@@ -12156,6 +12214,8 @@ push_cp_function_context (toplev)
...
@@ -12156,6 +12214,8 @@ push_cp_function_context (toplev)
p
->
just_assigned_this
=
current_function_just_assigned_this
;
p
->
just_assigned_this
=
current_function_just_assigned_this
;
p
->
parms_stored
=
current_function_parms_stored
;
p
->
parms_stored
=
current_function_parms_stored
;
p
->
result_rtx
=
original_result_rtx
;
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. */
/* Restore the variables used during compilation of a C++ function. */
...
@@ -12197,10 +12257,12 @@ pop_cp_function_context (toplev)
...
@@ -12197,10 +12257,12 @@ pop_cp_function_context (toplev)
current_binding_level
=
p
->
binding_level
;
current_binding_level
=
p
->
binding_level
;
ctor_label
=
p
->
ctor_label
;
ctor_label
=
p
->
ctor_label
;
dtor_label
=
p
->
dtor_label
;
dtor_label
=
p
->
dtor_label
;
protect_list
=
p
->
protect_list
;
current_function_assigns_this
=
p
->
assigns_this
;
current_function_assigns_this
=
p
->
assigns_this
;
current_function_just_assigned_this
=
p
->
just_assigned_this
;
current_function_just_assigned_this
=
p
->
just_assigned_this
;
current_function_parms_stored
=
p
->
parms_stored
;
current_function_parms_stored
=
p
->
parms_stored
;
original_result_rtx
=
p
->
result_rtx
;
original_result_rtx
=
p
->
result_rtx
;
base_init_insns
=
p
->
base_init_insns
;
free
(
p
);
free
(
p
);
}
}
gcc/cp/decl2.c
View file @
b7484fbe
...
@@ -1027,6 +1027,7 @@ grok_array_decl (array_expr, index_exp)
...
@@ -1027,6 +1027,7 @@ grok_array_decl (array_expr, index_exp)
tree
array_expr
,
index_exp
;
tree
array_expr
,
index_exp
;
{
{
tree
type
=
TREE_TYPE
(
array_expr
);
tree
type
=
TREE_TYPE
(
array_expr
);
tree
p1
,
p2
,
i1
,
i2
;
if
(
type
==
error_mark_node
||
index_exp
==
error_mark_node
)
if
(
type
==
error_mark_node
||
index_exp
==
error_mark_node
)
return
error_mark_node
;
return
error_mark_node
;
...
@@ -1049,28 +1050,38 @@ grok_array_decl (array_expr, index_exp)
...
@@ -1049,28 +1050,38 @@ grok_array_decl (array_expr, index_exp)
array_expr
,
index_exp
,
NULL_TREE
);
array_expr
,
index_exp
,
NULL_TREE
);
/* Otherwise, create an ARRAY_REF for a pointer or array type. */
/* 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]'.
if
(
TREE_CODE
(
type
)
==
ARRAY_TYPE
)
We don't emit a warning or error for this, since it's allowed
p1
=
array_expr
;
by ARM $8.2.4. */
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
i1
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
array_expr
,
0
);
||
TREE_CODE
(
type
)
==
REFERENCE_TYPE
)
i2
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
index_exp
,
0
);
type
=
TREE_TYPE
(
type
);
if
(
TREE_CODE
(
type
)
==
POINTER_TYPE
if
((
p1
&&
i2
)
&&
(
i1
&&
p2
))
||
TREE_CODE
(
type
)
==
ARRAY_TYPE
)
error
(
"ambiguous conversion for array subscript"
);
return
build_array_ref
(
index_exp
,
array_expr
);
/* The expression E1[E2] is identical (by definition) to *((E1)+(E2)). */
if
(
p1
&&
i2
)
return
build_indirect_ref
(
build_binary_op
(
PLUS_EXPR
,
array_expr
,
array_expr
=
p1
,
index_exp
=
i2
;
index_exp
,
1
),
else
if
(
i1
&&
p2
)
"array indexing"
);
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
/* Given the cast expression EXP, checking out its validity. Either return
...
@@ -2487,8 +2498,8 @@ import_export_vtable (decl, type, final)
...
@@ -2487,8 +2498,8 @@ import_export_vtable (decl, type, final)
}
}
else
else
{
{
/* We can only
do this optimization if we have real non-inline
/* We can only
wait to decide if we have real non-inline virtual
virtual
functions in our class, or if we come from a template. */
functions in our class, or if we come from a template. */
int
found
=
CLASSTYPE_TEMPLATE_INSTANTIATION
(
type
);
int
found
=
CLASSTYPE_TEMPLATE_INSTANTIATION
(
type
);
...
@@ -2543,7 +2554,8 @@ finish_prevtable_vardecl (prev, vars)
...
@@ -2543,7 +2554,8 @@ finish_prevtable_vardecl (prev, vars)
tree
ctype
=
DECL_CONTEXT
(
vars
);
tree
ctype
=
DECL_CONTEXT
(
vars
);
import_export_template
(
ctype
);
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
;
tree
method
;
for
(
method
=
CLASSTYPE_METHODS
(
ctype
);
method
!=
NULL_TREE
;
for
(
method
=
CLASSTYPE_METHODS
(
ctype
);
method
!=
NULL_TREE
;
...
@@ -2562,19 +2574,11 @@ finish_prevtable_vardecl (prev, vars)
...
@@ -2562,19 +2574,11 @@ finish_prevtable_vardecl (prev, vars)
import_export_vtable
(
vars
,
ctype
,
1
);
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
)))
&&
!
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. */
/* Kick out the type descriptor before writing out the vtable. */
if
(
flag_rtti
)
build_t_desc
(
ctype
,
1
);
{
build_t_desc
(
ctype
,
1
);
}
/* Write it out. */
mark_vtable_entries
(
vars
);
}
}
}
}
...
@@ -2582,39 +2586,13 @@ static void
...
@@ -2582,39 +2586,13 @@ static void
finish_vtable_vardecl
(
prev
,
vars
)
finish_vtable_vardecl
(
prev
,
vars
)
tree
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
if
(
write_virtuals
>=
0
&&
!
DECL_EXTERNAL
(
vars
)
&&
(
TREE_PUBLIC
(
vars
)
||
TREE_USED
(
vars
)))
&&
!
DECL_EXTERNAL
(
vars
)
&&
(
TREE_PUBLIC
(
vars
)
||
TREE_USED
(
vars
)))
{
{
extern
tree
the_null_vtable_entry
;
/* Write it out. */
/* Write it out. */
mark_vtable_entries
(
vars
);
mark_vtable_entries
(
vars
);
if
(
TREE_TYPE
(
DECL_INITIAL
(
vars
))
==
0
)
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
#ifdef DWARF_DEBUGGING_INFO
if
(
write_symbols
==
DWARF_DEBUG
)
if
(
write_symbols
==
DWARF_DEBUG
)
...
@@ -2646,8 +2624,18 @@ finish_vtable_vardecl (prev, vars)
...
@@ -2646,8 +2624,18 @@ finish_vtable_vardecl (prev, vars)
rest_of_decl_compilation
(
vars
,
NULL_PTR
,
1
,
1
);
rest_of_decl_compilation
(
vars
,
NULL_PTR
,
1
,
1
);
}
}
else
if
(
TREE_USED
(
vars
))
else
if
(
!
TREE_USED
(
vars
))
assemble_external
(
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. */
/* We know that PREV must be non-zero here. */
TREE_CHAIN
(
prev
)
=
TREE_CHAIN
(
vars
);
TREE_CHAIN
(
prev
)
=
TREE_CHAIN
(
vars
);
}
}
...
@@ -2731,6 +2719,8 @@ import_export_inline (decl)
...
@@ -2731,6 +2719,8 @@ import_export_inline (decl)
if
(
DECL_INTERFACE_KNOWN
(
decl
))
if
(
DECL_INTERFACE_KNOWN
(
decl
))
return
;
return
;
DECL_EXTERNAL
(
decl
)
=
0
;
if
(
DECL_TEMPLATE_INSTANTIATION
(
decl
))
if
(
DECL_TEMPLATE_INSTANTIATION
(
decl
))
{
{
if
(
DECL_IMPLICIT_INSTANTIATION
(
decl
)
&&
flag_implicit_templates
)
if
(
DECL_IMPLICIT_INSTANTIATION
(
decl
)
&&
flag_implicit_templates
)
...
@@ -2773,7 +2763,6 @@ finish_file ()
...
@@ -2773,7 +2763,6 @@ finish_file ()
tree
fnname
;
tree
fnname
;
tree
vars
=
static_aggregates
;
tree
vars
=
static_aggregates
;
int
needs_cleaning
=
0
,
needs_messing_up
=
0
;
int
needs_cleaning
=
0
,
needs_messing_up
=
0
;
int
have_exception_handlers
=
build_exception_table
();
if
(
flag_detailed_statistics
)
if
(
flag_detailed_statistics
)
dump_tree_statistics
();
dump_tree_statistics
();
...
@@ -2788,7 +2777,7 @@ finish_file ()
...
@@ -2788,7 +2777,7 @@ finish_file ()
we'll need here. */
we'll need here. */
push_lang_context
(
lang_name_c
);
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
;
needs_messing_up
=
1
;
if
(
static_dtors
)
if
(
static_dtors
)
needs_cleaning
=
1
;
needs_cleaning
=
1
;
...
@@ -2900,7 +2889,7 @@ finish_file ()
...
@@ -2900,7 +2889,7 @@ finish_file ()
push_momentary
();
push_momentary
();
expand_start_bindings
(
0
);
expand_start_bindings
(
0
);
if
(
have_exception_handlers
)
if
(
might_have_exceptions_p
()
)
register_exception_table
();
register_exception_table
();
while
(
vars
)
while
(
vars
)
...
@@ -2931,6 +2920,7 @@ finish_file ()
...
@@ -2931,6 +2920,7 @@ finish_file ()
/* 9.5p5: The initializer of a static member of a class has
/* 9.5p5: The initializer of a static member of a class has
the same acess rights as a member function. */
the same acess rights as a member function. */
DECL_CLASS_CONTEXT
(
current_function_decl
)
=
DECL_CONTEXT
(
decl
);
DECL_CLASS_CONTEXT
(
current_function_decl
)
=
DECL_CONTEXT
(
decl
);
DECL_STATIC_FUNCTION_P
(
current_function_decl
)
=
1
;
#if 0
#if 0
if (init)
if (init)
...
@@ -3061,30 +3051,9 @@ finish_file ()
...
@@ -3061,30 +3051,9 @@ finish_file ()
pushdecl
(
vars
);
pushdecl
(
vars
);
#endif
#endif
walk_vtables
((
void
(
*
)())
0
,
finish_vtable_vardecl
);
if
(
flag_handle_signatures
)
if
(
flag_handle_signatures
)
walk_sigtables
((
void
(
*
)())
0
,
finish_sigtable_vardecl
);
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
/* Now write out inline functions which had their addresses taken and
which were not declared virtual and which were not declared `extern
which were not declared virtual and which were not declared `extern
inline'. */
inline'. */
...
@@ -3098,10 +3067,23 @@ finish_file ()
...
@@ -3098,10 +3067,23 @@ finish_file ()
tree
place
=
TREE_CHAIN
(
saved_inlines
);
tree
place
=
TREE_CHAIN
(
saved_inlines
);
reconsider
=
0
;
reconsider
=
0
;
walk_vtables
((
void
(
*
)())
0
,
finish_vtable_vardecl
);
for
(;
place
;
place
=
TREE_CHAIN
(
place
))
for
(;
place
;
place
=
TREE_CHAIN
(
place
))
{
{
tree
decl
=
TREE_VALUE
(
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
)
if
(
TREE_ASM_WRITTEN
(
decl
)
||
DECL_SAVED_INSNS
(
decl
)
==
0
)
{
{
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
...
@@ -3114,9 +3096,7 @@ finish_file ()
...
@@ -3114,9 +3096,7 @@ finish_file ()
{
{
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
if
(
DECL_EXTERNAL
(
decl
))
if
(
!
DECL_EXTERNAL
(
decl
))
assemble_external
(
decl
);
else
{
{
reconsider
=
1
;
reconsider
=
1
;
temporary_allocation
();
temporary_allocation
();
...
@@ -3132,6 +3112,21 @@ finish_file ()
...
@@ -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
)
if
(
write_virtuals
==
2
)
{
{
/* Now complain about an virtual function tables promised
/* Now complain about an virtual function tables promised
...
...
gcc/cp/error.c
View file @
b7484fbe
...
@@ -585,7 +585,7 @@ dump_decl (t, v)
...
@@ -585,7 +585,7 @@ dump_decl (t, v)
break
;
break
;
case
VAR_DECL
:
case
VAR_DECL
:
if
(
VTABLE_NAME_P
(
DECL_NAME
(
t
)))
if
(
DECL_NAME
(
t
)
&&
VTABLE_NAME_P
(
DECL_NAME
(
t
)))
{
{
OB_PUTS
(
"vtable for "
);
OB_PUTS
(
"vtable for "
);
dump_type
(
DECL_CONTEXT
(
t
),
v
);
dump_type
(
DECL_CONTEXT
(
t
),
v
);
...
@@ -933,9 +933,16 @@ dump_expr (t, nop)
...
@@ -933,9 +933,16 @@ dump_expr (t, nop)
char
*
p
=
enum_name_string
(
t
,
type
);
char
*
p
=
enum_name_string
(
t
,
type
);
OB_PUTCP
(
p
);
OB_PUTCP
(
p
);
}
}
else
if
(
type
==
char_type_node
else
if
(
type
==
boolean_type_node
)
||
type
==
signed_char_type_node
{
||
type
==
unsigned_char_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
(
'\''
);
OB_PUTC
(
'\''
);
dump_char
(
TREE_INT_CST_LOW
(
t
));
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. */
...
@@ -31,6 +31,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "obstack.h"
#include "obstack.h"
#include "expr.h"
#include "expr.h"
tree
protect_list
;
extern
void
(
*
interim_eh_hook
)
PROTO
((
tree
));
extern
void
(
*
interim_eh_hook
)
PROTO
((
tree
));
/* holds the fndecl for __builtin_return_address () */
/* holds the fndecl for __builtin_return_address () */
...
@@ -53,6 +55,11 @@ tree builtin_return_address_fndecl;
...
@@ -53,6 +55,11 @@ tree builtin_return_address_fndecl;
#define __mips
#define __mips
#endif
#endif
#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)
#if defined(__i386) || defined(__rs6000) || defined(__hppa) || defined(__mc68000) || defined (__mips) || defined (__arm) || defined (__alpha)
#define TRY_NEW_EH
#define TRY_NEW_EH
#endif
#endif
...
@@ -872,11 +879,13 @@ void
...
@@ -872,11 +879,13 @@ void
end_protect
(
finalization
)
end_protect
(
finalization
)
tree
finalization
;
tree
finalization
;
{
{
struct
ehEntry
*
entry
=
pop_eh_entry
(
&
ehstack
)
;
struct
ehEntry
*
entry
;
if
(
!
doing_eh
(
0
))
if
(
!
doing_eh
(
0
))
return
;
return
;
entry
=
pop_eh_entry
(
&
ehstack
);
emit_label
(
entry
->
end_label
);
emit_label
(
entry
->
end_label
);
entry
->
finalization
=
finalization
;
entry
->
finalization
=
finalization
;
...
@@ -1574,11 +1583,29 @@ expand_throw (exp)
...
@@ -1574,11 +1583,29 @@ expand_throw (exp)
/* end of: my-cp-except.c */
/* end of: my-cp-except.c */
#endif
#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.
/* Output the exception table.
Return the number of handlers. */
Return the number of handlers. */
int
void
build
_exception_table
()
emit
_exception_table
()
{
{
int
count
=
0
;
int
count
=
0
;
#ifdef TRY_NEW_EH
#ifdef TRY_NEW_EH
...
@@ -1587,7 +1614,15 @@ build_exception_table ()
...
@@ -1587,7 +1614,15 @@ build_exception_table ()
tree
eh_node_decl
;
tree
eh_node_decl
;
if
(
!
doing_eh
(
0
))
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
))
while
(
entry
=
dequeue_eh_entry
(
&
eh_table_output_queue
))
{
{
...
@@ -1596,32 +1631,18 @@ build_exception_table ()
...
@@ -1596,32 +1631,18 @@ build_exception_table ()
if
(
context
&&
!
TREE_ASM_WRITTEN
(
context
))
if
(
context
&&
!
TREE_ASM_WRITTEN
(
context
))
continue
;
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
++
;
count
++
;
output_exception_table_entry
(
asm_out_file
,
output_exception_table_entry
(
asm_out_file
,
entry
->
start_label
,
entry
->
end_label
,
entry
->
start_label
,
entry
->
end_label
,
entry
->
exception_handler_label
);
entry
->
exception_handler_label
);
}
}
if
(
count
)
/* Ending marker for table. */
{
ASM_OUTPUT_LABEL
(
asm_out_file
,
"__EXCEPTION_END__"
);
/* Ending marker for table. */
output_exception_table_entry
(
asm_out_file
,
ASM_OUTPUT_LABEL
(
asm_out_file
,
"__EXCEPTION_END__"
);
constm1_rtx
,
constm1_rtx
,
constm1_rtx
);
output_exception_table_entry
(
asm_out_file
,
constm1_rtx
,
constm1_rtx
,
constm1_rtx
);
}
#endif
/* TRY_NEW_EH */
#endif
/* TRY_NEW_EH */
return
count
;
}
}
void
void
...
...
gcc/cp/init.c
View file @
b7484fbe
...
@@ -157,8 +157,8 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
...
@@ -157,8 +157,8 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
/* 348 - 351 */
/* 348 - 351 */
/* Subroutine of emit_base_init. */
/* Subroutine of emit_base_init. */
static
void
static
void
perform_member_init
(
member
,
name
,
init
,
explicit
)
perform_member_init
(
member
,
name
,
init
,
explicit
,
protect_list
)
tree
member
,
name
,
init
;
tree
member
,
name
,
init
,
*
protect_list
;
int
explicit
;
int
explicit
;
{
{
tree
decl
;
tree
decl
;
...
@@ -223,27 +223,44 @@ perform_member_init (member, name, init, explicit)
...
@@ -223,27 +223,44 @@ perform_member_init (member, name, init, explicit)
}
}
}
}
expand_cleanups_to
(
NULL_TREE
);
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. */
/* Subroutine of emit_member_init. */
static
tree
static
tree
sort_member_init
(
t
)
sort_member_init
(
t
)
tree
t
;
tree
t
;
{
{
extern
int
warn_reorder
;
tree
x
,
member
,
name
,
field
,
init
;
tree
x
,
member
,
name
,
field
,
init
;
tree
init_list
=
NULL_TREE
;
tree
init_list
=
NULL_TREE
;
tree
fields_to_unmark
=
NULL_TREE
;
tree
fields_to_unmark
=
NULL_TREE
;
int
found
;
int
last_pos
=
0
;
int
last_pos
=
0
;
tree
last_field
;
tree
last_field
;
for
(
member
=
TYPE_FIELDS
(
t
);
member
;
member
=
TREE_CHAIN
(
member
))
for
(
member
=
TYPE_FIELDS
(
t
);
member
;
member
=
TREE_CHAIN
(
member
))
{
{
int
pos
;
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
)
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. */
/* If we cleared this out, then pay no attention to it. */
...
@@ -266,17 +283,9 @@ sort_member_init (t)
...
@@ -266,17 +283,9 @@ sort_member_init (t)
if
(
field
==
member
)
if
(
field
==
member
)
{
{
/* See if we already found an initializer for this field. */
if
(
warn_reorder
)
if
(
found
)
{
if
(
DECL_NAME
(
field
))
cp_error
(
"multiple initializations given for member `%D'"
,
field
);
continue
;
}
else
{
{
if
(
pos
<
last_pos
&&
warn_reorder
)
if
(
pos
<
last_pos
)
{
{
cp_warning_at
(
"member initializers for `%#D'"
,
last_field
);
cp_warning_at
(
"member initializers for `%#D'"
,
last_field
);
cp_warning_at
(
" and `%#D'"
,
field
);
cp_warning_at
(
" and `%#D'"
,
field
);
...
@@ -286,78 +295,193 @@ sort_member_init (t)
...
@@ -286,78 +295,193 @@ sort_member_init (t)
last_field
=
field
;
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. */
/* Make sure we won't try to work on this init again. */
TREE_PURPOSE
(
x
)
=
NULL_TREE
;
TREE_PURPOSE
(
x
)
=
NULL_TREE
;
found
=
1
;
x
=
build_tree_list
(
name
,
TREE_VALUE
(
x
))
;
break
;
goto
got_it
;
}
}
}
}
/* If we didn't find MEMBER in the list, create a dummy entry
/* 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
so the two lists (INIT_LIST and the list of members) will be
symmetrical. */
symmetrical. */
if
(
!
found
)
x
=
build_tree_list
(
NULL_TREE
,
NULL_TREE
);
init_list
=
chainon
(
init_list
,
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
))
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
);
if
(
purpose_member
(
name
,
init_list
))
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
)
{
{
field
=
TREE_VALUE
(
field
);
cp_error
(
"multiple initializations given for member `%D'"
,
if
(
decl_type_context
(
field
)
!=
current_class_type
)
IDENTIFIER_CLASS_VALUE
(
name
));
cp_error
(
"field `%D' not in immediate context"
,
field
)
;
continue
;
}
}
init_list
=
chainon
(
init_list
,
build_tree_list
(
name
,
TREE_VALUE
(
x
)));
TREE_PURPOSE
(
x
)
=
NULL_TREE
;
}
}
#if 0
return
init_list
;
/* 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
static
void
which had this check in it. Theoretically, we've hit
sort_base_init
(
t
,
rbase_ptr
,
vbase_ptr
)
every initialization for the list of members in T, so
tree
t
,
*
rbase_ptr
,
*
vbase_ptr
;
we shouldn't have anything but these left in this list. */
{
my_friendly_assert (DECL_FIELD_CONTEXT (field) != t, 351);
tree
binfos
=
BINFO_BASETYPES
(
TYPE_BINFO
(
t
));
#endif
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
))
case
0
:
error
(
"multiple initializations given for member `%s'"
,
cp_error
(
"`%T' does not have a base class to initialize"
,
IDENTIFIER_POINTER
(
DECL_NAME
(
field
)));
current_class_type
);
continue
;
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
;
/* Virtual base classes are special cases. Their initializers
fields_to_unmark
=
tree_cons
(
NULL_TREE
,
field
,
fields_to_unmark
);
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
);
vbases
=
tree_cons
(
v
,
TREE_VALUE
(
x
),
vbases
);
TREE_PURPOSE
(
x
)
=
NULL_TREE
;
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. */
/* Now walk through our regular bases and make sure they're initialized. */
while
(
fields_to_unmark
)
for
(
i
=
0
;
i
<
n_baseclasses
;
++
i
)
{
{
TREE_HAS_CONSTRUCTOR
(
TREE_VALUE
(
fields_to_unmark
))
=
0
;
tree
base_binfo
=
TREE_VEC_ELT
(
binfos
,
i
);
/* XXX is this a memory leak? */
int
pos
;
fields_to_unmark
=
TREE_CHAIN
(
fields_to_unmark
);
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
/* Perform whatever initializations have yet to be done on the base
...
@@ -385,13 +509,14 @@ emit_base_init (t, immediately)
...
@@ -385,13 +509,14 @@ emit_base_init (t, immediately)
{
{
extern
tree
in_charge_identifier
;
extern
tree
in_charge_identifier
;
tree
member
,
vbases
;
tree
member
,
x
;
tree
init_list
;
tree
mem_
init_list
;
int
pass
,
star
t
;
tree
rbase_init_list
,
vbase_init_lis
t
;
tree
t_binfo
=
TYPE_BINFO
(
t
);
tree
t_binfo
=
TYPE_BINFO
(
t
);
tree
binfos
=
BINFO_BASETYPES
(
t_binfo
);
tree
binfos
=
BINFO_BASETYPES
(
t_binfo
);
int
i
,
n_baseclasses
=
binfos
?
TREE_VEC_LENGTH
(
binfos
)
:
0
;
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
)
if
(
!
immediately
)
{
{
...
@@ -407,172 +532,31 @@ emit_base_init (t, immediately)
...
@@ -407,172 +532,31 @@ emit_base_init (t, immediately)
emit_line_note_force
(
DECL_SOURCE_FILE
(
current_function_decl
),
emit_line_note_force
(
DECL_SOURCE_FILE
(
current_function_decl
),
DECL_SOURCE_LINE
(
current_function_decl
));
DECL_SOURCE_LINE
(
current_function_decl
));
start
=
!
TYPE_USES_VIRTUAL_BASECLASSES
(
t
);
mem_init_list
=
sort_member_init
(
t
);
for
(
pass
=
start
;
pass
<
2
;
pass
++
)
current_member_init_list
=
NULL_TREE
;
{
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
;
member
=
convert_pointer_to
(
binfo
,
current_class_decl
);
sort_base_init
(
t
,
&
rbase_init_list
,
&
vbase_init_list
);
expand_aggr_init_1
(
binfo
,
0
,
current_base_init_list
=
NULL_TREE
;
build_indirect_ref
(
member
,
NULL_PTR
),
init
,
BINFO_OFFSET_ZEROP
(
binfo
),
LOOKUP_NORMAL
);
expand_cleanups_to
(
NULL_TREE
);
}
if
(
pass
==
0
)
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
t
))
{
{
tree
first_arg
=
TREE_CHAIN
(
DECL_ARGUMENTS
(
current_function_decl
));
tree
first_arg
=
TREE_CHAIN
(
DECL_ARGUMENTS
(
current_function_decl
));
tree
vbases
;
if
(
DECL_NAME
(
current_function_decl
)
==
NULL_TREE
expand_start_cond
(
first_arg
,
0
);
&&
TREE_CHAIN
(
first_arg
)
!=
NULL_TREE
)
expand_aggr_vbase_init
(
t_binfo
,
C_C_D
,
current_class_decl
,
{
vbase_init_list
);
/* If there are virtual baseclasses without initialization
expand_end_cond
();
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
();
}
}
}
current_base_init_list
=
NULL_TREE
;
/* Now, perform default initialization of all base classes which
/* Now, perform initialization of non-virtual base classes. */
have not yet been initialized, and unmark baseclasses which
have been initialized. */
for
(
i
=
0
;
i
<
n_baseclasses
;
i
++
)
for
(
i
=
0
;
i
<
n_baseclasses
;
i
++
)
{
{
tree
base
=
current_class_decl
;
tree
base
=
current_class_decl
;
tree
base_binfo
=
TREE_VEC_ELT
(
binfos
,
i
);
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. */
#if 0 /* Once unsharing happens soon enough. */
my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo);
my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo);
...
@@ -580,109 +564,113 @@ emit_base_init (t, immediately)
...
@@ -580,109 +564,113 @@ emit_base_init (t, immediately)
BINFO_INHERITANCE_CHAIN
(
base_binfo
)
=
t_binfo
;
BINFO_INHERITANCE_CHAIN
(
base_binfo
)
=
t_binfo
;
#endif
#endif
if
(
TYPE_NEEDS_CONSTRUCTING
(
BINFO_TYPE
(
base_binfo
)))
if
(
TREE_PURPOSE
(
rbase_init_list
))
{
init
=
TREE_VALUE
(
rbase_init_list
);
if
(
!
TREE_VIA_VIRTUAL
(
base_binfo
)
else
if
(
TYPE_NEEDS_CONSTRUCTING
(
BINFO_TYPE
(
base_binfo
)))
&&
!
BINFO_BASEINIT_MARKED
(
base_binfo
))
init
=
NULL_TREE
;
{
tree
ref
;
if
(
BINFO_OFFSET_ZEROP
(
base_binfo
))
if
(
init
!=
void_list_node
)
base
=
build1
(
NOP_EXPR
,
{
TYPE_POINTER_TO
(
BINFO_TYPE
(
base_binfo
)),
member
=
convert_pointer_to
(
base_binfo
,
current_class_decl
);
current_class_decl
);
expand_aggr_init_1
(
base_binfo
,
0
,
else
build_indirect_ref
(
member
,
NULL_PTR
),
init
,
base
=
build
(
PLUS_EXPR
,
BINFO_OFFSET_ZEROP
(
base_binfo
),
LOOKUP_NORMAL
);
TYPE_POINTER_TO
(
BINFO_TYPE
(
base_binfo
)),
expand_cleanups_to
(
NULL_TREE
);
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
);
}
}
}
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
))
start_protect
();
&&
BINFO_BASETYPES
(
base_binfo
)
!=
NULL_TREE
protect_list
=
tree_cons
(
NULL_TREE
,
&&
TREE_VEC_LENGTH
(
BINFO_BASETYPES
(
base_binfo
))
==
1
)
build_partial_cleanup_for
(
base_binfo
),
{
protect_list
);
/* ?? 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
);
}
}
}
rbase_init_list
=
TREE_CHAIN
(
rbase_init_list
);
}
}
/* Initialize all the virtual function table fields that
/* Initialize all the virtual function table fields that
do come from virtual base classes. */
do come from virtual base classes. */
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
t
))
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
t
))
expand_indirect_vtbls_init
(
t_binfo
,
C_C_D
,
current_class_decl
,
0
);
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
/* Initialize all the virtual function table fields that
do not come from virtual base classes. */
do not come from virtual base classes. */
expand_direct_vtbls_init
(
t_binfo
,
t_binfo
,
1
,
1
,
current_class_decl
);
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
))
for
(
member
=
TYPE_FIELDS
(
t
);
member
;
member
=
TREE_CHAIN
(
member
))
{
{
tree
init
,
name
;
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. */
/* 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
(
mem_init_list
);
{
init
=
TREE_VALUE
(
mem_init_list
);
name
=
TREE_PURPOSE
(
init_list
);
from_init_list
=
1
;
init
=
TREE_VALUE
(
init_list
);
from_init_list
=
1
;
if
(
TREE_STATIC
(
member
))
/* Also see if it's ever a COMPONENT_REF here. If it is, we
{
need to do `expand_assignment (name, init, 0, 0);' and
cp_error
(
"field `%#D' is static; only point of initialization is its declaration"
,
a continue. */
member
);
my_friendly_assert
(
TREE_CODE
(
name
)
!=
COMPONENT_REF
,
349
);
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
);
}
}
else
if
(
!
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
;
name
=
DECL_NAME
(
member
);
name
=
DECL_NAME
(
member
);
init
=
DECL_INITIAL
(
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
)
if
(
!
immediately
)
{
{
...
@@ -750,14 +738,13 @@ static void
...
@@ -750,14 +738,13 @@ static void
expand_aggr_vbase_init_1
(
binfo
,
exp
,
addr
,
init_list
)
expand_aggr_vbase_init_1
(
binfo
,
exp
,
addr
,
init_list
)
tree
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
);
tree
ref
=
build_indirect_ref
(
addr
,
NULL_PTR
);
if
(
init
)
if
(
init
)
init
=
TREE_
PURPOS
E
(
init
);
init
=
TREE_
VALU
E
(
init
);
/* Call constructors, but don't set up vtables. */
/* Call constructors, but don't set up vtables. */
expand_aggr_init_1
(
binfo
,
exp
,
ref
,
init
,
0
,
LOOKUP_COMPLAIN
);
expand_aggr_init_1
(
binfo
,
exp
,
ref
,
init
,
0
,
LOOKUP_COMPLAIN
);
expand_cleanups_to
(
NULL_TREE
);
expand_cleanups_to
(
NULL_TREE
);
CLEAR_BINFO_VBASE_INIT_MARKED
(
binfo
);
}
}
/* Initialize this object's virtual base class pointers. This must be
/* Initialize this object's virtual base class pointers. This must be
...
@@ -781,38 +768,14 @@ expand_aggr_vbase_init (binfo, exp, addr, init_list)
...
@@ -781,38 +768,14 @@ expand_aggr_vbase_init (binfo, exp, addr, init_list)
if
(
result
)
if
(
result
)
expand_expr_stmt
(
build_compound_expr
(
result
));
expand_expr_stmt
(
build_compound_expr
(
result
));
/* Mark everything as having an initializer
for
(
vbases
=
CLASSTYPE_VBASECLASSES
(
type
);
vbases
;
(either explicit or default). */
vbases
=
TREE_CHAIN
(
vbases
))
for
(
vbases
=
CLASSTYPE_VBASECLASSES
(
type
);
{
vbases
;
vbases
=
TREE_CHAIN
(
vbases
))
tree
tmp
=
purpose_member
(
vbases
,
result
);
SET_BINFO_VBASE_INIT_MARKED
(
vbases
);
expand_aggr_vbase_init_1
(
vbases
,
exp
,
TREE_OPERAND
(
TREE_VALUE
(
tmp
),
0
),
/* First, initialize baseclasses which could be baseclasses
init_list
);
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
);
}
}
}
}
}
...
@@ -862,7 +825,7 @@ member_init_ok_or_else (field, type, member_name)
...
@@ -862,7 +825,7 @@ member_init_ok_or_else (field, type, member_name)
if
(
field
==
NULL_TREE
)
if
(
field
==
NULL_TREE
)
{
{
cp_error
(
"class `%T' does not have any field named `%s'"
,
type
,
cp_error
(
"class `%T' does not have any field named `%s'"
,
type
,
member_name
);
member_name
);
return
0
;
return
0
;
}
}
if
(
DECL_CONTEXT
(
field
)
!=
type
if
(
DECL_CONTEXT
(
field
)
!=
type
...
@@ -872,6 +835,13 @@ member_init_ok_or_else (field, type, member_name)
...
@@ -872,6 +835,13 @@ member_init_ok_or_else (field, type, member_name)
field
);
field
);
return
0
;
return
0
;
}
}
if
(
TREE_STATIC
(
field
))
{
cp_error
(
"field `%#D' is static; only point of initialization is its declaration"
,
field
);
return
0
;
}
return
1
;
return
1
;
}
}
...
@@ -1209,7 +1179,8 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
...
@@ -1209,7 +1179,8 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
tree
rval
;
tree
rval
;
tree
parms
;
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
;
parms
=
init
;
if
(
parms
)
if
(
parms
)
...
@@ -2044,6 +2015,12 @@ build_offset_ref (cname, name)
...
@@ -2044,6 +2015,12 @@ build_offset_ref (cname, name)
return
t
;
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. */
/* static class functions too. */
if
(
TREE_CODE
(
t
)
==
FUNCTION_DECL
&&
TREE_CODE
(
TREE_TYPE
(
t
))
==
FUNCTION_TYPE
)
if
(
TREE_CODE
(
t
)
==
FUNCTION_DECL
&&
TREE_CODE
(
TREE_TYPE
(
t
))
==
FUNCTION_TYPE
)
my_friendly_abort
(
53
);
my_friendly_abort
(
53
);
...
@@ -2085,7 +2062,7 @@ get_member_function (exp_addr_ptr, exp, member)
...
@@ -2085,7 +2062,7 @@ get_member_function (exp_addr_ptr, exp, member)
if
(
UNITS_PER_WORD
<=
1
)
if
(
UNITS_PER_WORD
<=
1
)
my_friendly_abort
(
54
);
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
,
e1
=
build_compound_expr
(
tree_cons
(
NULL_TREE
,
exp_addr
,
build_tree_list
(
NULL_TREE
,
e1
)));
build_tree_list
(
NULL_TREE
,
e1
)));
e1
=
save_expr
(
e1
);
e1
=
save_expr
(
e1
);
...
@@ -2240,7 +2217,7 @@ resolve_offset_ref (exp)
...
@@ -2240,7 +2217,7 @@ resolve_offset_ref (exp)
}
}
else
if
(
TYPE_PTRMEMFUNC_P
(
TREE_TYPE
(
member
)))
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
);
my_friendly_abort
(
56
);
/* NOTREACHED */
/* NOTREACHED */
...
@@ -2322,7 +2299,13 @@ is_friend (type, supplicant)
...
@@ -2322,7 +2299,13 @@ is_friend (type, supplicant)
{
{
tree
list
=
DECL_FRIENDLIST
(
TYPE_NAME
(
type
));
tree
list
=
DECL_FRIENDLIST
(
TYPE_NAME
(
type
));
tree
name
=
DECL_NAME
(
supplicant
);
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
))
for
(;
list
;
list
=
TREE_CHAIN
(
list
))
{
{
if
(
name
==
TREE_PURPOSE
(
list
))
if
(
name
==
TREE_PURPOSE
(
list
))
...
@@ -2353,8 +2336,14 @@ is_friend (type, supplicant)
...
@@ -2353,8 +2336,14 @@ is_friend (type, supplicant)
}
}
{
{
tree
context
=
declp
?
DECL_CLASS_CONTEXT
(
supplicant
)
tree
context
;
:
DECL_CONTEXT
(
TYPE_NAME
(
supplicant
));
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
)
if
(
context
)
return
is_friend
(
type
,
context
);
return
is_friend
(
type
,
context
);
...
@@ -2508,7 +2497,7 @@ make_friend_class (type, friend_type)
...
@@ -2508,7 +2497,7 @@ make_friend_class (type, friend_type)
}
}
if
(
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
));
TYPE_NAME_STRING
(
type
));
return
;
return
;
}
}
...
@@ -2803,7 +2792,7 @@ build_new (placement, decl, init, use_global_new)
...
@@ -2803,7 +2792,7 @@ build_new (placement, decl, init, use_global_new)
{
{
tree
type
,
true_type
,
size
,
rval
;
tree
type
,
true_type
,
size
,
rval
;
tree
nelts
;
tree
nelts
;
tree
alloc_expr
;
tree
alloc_expr
,
alloc_temp
;
int
has_array
=
0
;
int
has_array
=
0
;
enum
tree_code
code
=
NEW_EXPR
;
enum
tree_code
code
=
NEW_EXPR
;
...
@@ -2927,6 +2916,12 @@ build_new (placement, decl, init, use_global_new)
...
@@ -2927,6 +2916,12 @@ build_new (placement, decl, init, use_global_new)
type
=
true_type
=
TREE_TYPE
(
type
);
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
/* 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,
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. */
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)
...
@@ -2956,7 +2951,7 @@ build_new (placement, decl, init, use_global_new)
if
(
true_type
==
void_type_node
)
if
(
true_type
==
void_type_node
)
{
{
error
(
"invalid type
for new: `void'
"
);
error
(
"invalid type
`void' for new
"
);
return
error_mark_node
;
return
error_mark_node
;
}
}
...
@@ -3032,12 +3027,19 @@ build_new (placement, decl, init, use_global_new)
...
@@ -3032,12 +3027,19 @@ build_new (placement, decl, init, use_global_new)
TREE_CALLS_NEW
(
rval
)
=
1
;
TREE_CALLS_NEW
(
rval
)
=
1
;
}
}
if
(
flag_check_new
)
if
(
flag_check_new
&&
rval
)
{
{
if
(
rval
)
/* For array new, we need to make sure that the call to new is
rval
=
save_expr
(
rval
);
not expanded as part of the RTL_EXPR for the initialization,
alloc_expr
=
rval
;
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
/* if rval is NULL_TREE I don't have to allocate it, but are we totally
sure we have some extra bytes in that case for the BI_header_size
sure we have some extra bytes in that case for the BI_header_size
...
@@ -3184,10 +3186,17 @@ build_new (placement, decl, init, use_global_new)
...
@@ -3184,10 +3186,17 @@ build_new (placement, decl, init, use_global_new)
done
:
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
);
/* Did we modify the storage? */
rval
=
build_conditional_expr
(
ifexp
,
rval
,
alloc_expr
);
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
))
if
(
rval
&&
TREE_TYPE
(
rval
)
!=
build_pointer_type
(
type
))
...
@@ -3354,7 +3363,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
...
@@ -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
);
iterator
,
integer_zero_node
),
0
);
expand_start_loop_continue_elsewhere
(
1
);
expand_start_loop_continue_elsewhere
(
1
);
...
@@ -3394,7 +3403,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
...
@@ -3394,7 +3403,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
expand_assignment
(
base2
,
expand_assignment
(
base2
,
build
(
PLUS_EXPR
,
TYPE_POINTER_TO
(
type
),
base2
,
size
),
0
,
0
);
build
(
PLUS_EXPR
,
TYPE_POINTER_TO
(
type
),
base2
,
size
),
0
,
0
);
expand_loop_continue_here
();
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
));
build
(
PREDECREMENT_EXPR
,
integer_type_node
,
iterator
,
integer_one_node
),
minus_one
));
if
(
obey_regdecls
)
if
(
obey_regdecls
)
...
@@ -3975,7 +3984,7 @@ build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
...
@@ -3975,7 +3984,7 @@ build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
body
=
tree_cons
(
NULL_TREE
,
body
=
tree_cons
(
NULL_TREE
,
build
(
EXIT_EXPR
,
void_type_node
,
build
(
EXIT_EXPR
,
void_type_node
,
build
(
EQ_EXPR
,
integer
_type_node
,
base
,
tbase
)),
build
(
EQ_EXPR
,
boolean
_type_node
,
base
,
tbase
)),
body
);
body
);
loop
=
build
(
LOOP_EXPR
,
void_type_node
,
build_compound_expr
(
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,
...
@@ -4031,7 +4040,7 @@ build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
/* Outermost wrapper: If pointer is null, punt. */
/* Outermost wrapper: If pointer is null, punt. */
body
=
build
(
COND_EXPR
,
void_type_node
,
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
,
integer_zero_node
);
body
=
build1
(
NOP_EXPR
,
void_type_node
,
body
);
body
=
build1
(
NOP_EXPR
,
void_type_node
,
body
);
...
...
gcc/cp/lex.c
View file @
b7484fbe
...
@@ -4541,8 +4541,6 @@ real_yylex ()
...
@@ -4541,8 +4541,6 @@ real_yylex ()
{
value
=
'}'
;
goto
done
;
}
{
value
=
'}'
;
goto
done
;
}
else
if
(
c
==
'%'
&&
c1
==
':'
)
else
if
(
c
==
'%'
&&
c1
==
':'
)
{
value
=
'#'
;
goto
done
;
}
{
value
=
'#'
;
goto
done
;
}
else
if
(
c
==
':'
&&
c1
==
'>'
)
{
value
=
']'
;
goto
done
;
}
nextchar
=
c1
;
nextchar
=
c1
;
token_buffer
[
1
]
=
0
;
token_buffer
[
1
]
=
0
;
...
@@ -4560,6 +4558,11 @@ real_yylex ()
...
@@ -4560,6 +4558,11 @@ real_yylex ()
value
=
SCOPE
;
value
=
SCOPE
;
yylval
.
itype
=
1
;
yylval
.
itype
=
1
;
}
}
else
if
(
c
==
'>'
)
{
value
=
']'
;
goto
done
;
}
else
else
{
{
nextchar
=
c
;
nextchar
=
c
;
...
...
gcc/cp/method.c
View file @
b7484fbe
...
@@ -2211,12 +2211,14 @@ synthesize_method (fndecl)
...
@@ -2211,12 +2211,14 @@ synthesize_method (fndecl)
int
nested
=
(
current_function_decl
!=
NULL_TREE
);
int
nested
=
(
current_function_decl
!=
NULL_TREE
);
int
toplev
=
(
decl_function_context
(
fndecl
)
==
NULL_TREE
);
int
toplev
=
(
decl_function_context
(
fndecl
)
==
NULL_TREE
);
char
*
f
=
input_filename
;
char
*
f
=
input_filename
;
tree
base
=
DECL_CLASS_CONTEXT
(
fndecl
);
if
(
nested
)
if
(
nested
)
push_cp_function_context
(
toplev
);
push_cp_function_context
(
toplev
);
input_filename
=
DECL_SOURCE_FILE
(
fndecl
);
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
);
start_function
(
NULL_TREE
,
fndecl
,
NULL_TREE
,
1
);
store_parm_decls
();
store_parm_decls
();
...
...
gcc/cp/parse.y
View file @
b7484fbe
...
@@ -1074,8 +1074,10 @@ unary_expr:
...
@@ -1074,8 +1074,10 @@ unary_expr:
{
{
tree t = TREE_VALUE ($2);
tree t = TREE_VALUE ($2);
if (t != NULL_TREE
if (t != NULL_TREE
&& TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
&& ((TREE_TYPE (t)
pedwarn ("ANSI C++ forbids using sizeof() on a function");
&& 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)); }
$$ = c_sizeof (TREE_TYPE ($2)); }
| SIZEOF '(' type_id ')' %prec HYPERUNARY
| SIZEOF '(' type_id ')' %prec HYPERUNARY
...
@@ -1142,7 +1144,7 @@ new_initializer:
...
@@ -1142,7 +1144,7 @@ new_initializer:
syntactically valid but semantically invalid. */
syntactically valid but semantically invalid. */
| '=' init
| '=' init
{
{
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids initialization of new expression with `='");
pedwarn ("ANSI C++ forbids initialization of new expression with `='");
$$ = $2;
$$ = $2;
}
}
...
@@ -1169,7 +1171,7 @@ cast_expr:
...
@@ -1169,7 +1171,7 @@ cast_expr:
{
{
tree init = build_nt (CONSTRUCTOR, NULL_TREE,
tree init = build_nt (CONSTRUCTOR, NULL_TREE,
nreverse ($3));
nreverse ($3));
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids constructor-expressions");
pedwarn ("ANSI C++ forbids constructor-expressions");
/* Indicate that this was a GNU C constructor expression. */
/* Indicate that this was a GNU C constructor expression. */
TREE_HAS_CONSTRUCTOR (init) = 1;
TREE_HAS_CONSTRUCTOR (init) = 1;
...
@@ -1289,7 +1291,6 @@ unqualified_id:
...
@@ -1289,7 +1291,6 @@ unqualified_id:
expr_or_declarator:
expr_or_declarator:
notype_unqualified_id
notype_unqualified_id
| notype_qualified_id
| '*' expr_or_declarator %prec UNARY
| '*' expr_or_declarator %prec UNARY
{ $$ = build_parse_node (INDIRECT_REF, $2); }
{ $$ = build_parse_node (INDIRECT_REF, $2); }
| '&' expr_or_declarator %prec UNARY
| '&' expr_or_declarator %prec UNARY
...
@@ -1301,9 +1302,6 @@ expr_or_declarator:
...
@@ -1301,9 +1302,6 @@ expr_or_declarator:
direct_notype_declarator:
direct_notype_declarator:
complex_direct_notype_declarator
complex_direct_notype_declarator
| notype_unqualified_id
| notype_unqualified_id
| notype_qualified_id
{ push_nested_class (TREE_TYPE (OP0 ($$)), 3);
TREE_COMPLEXITY ($$) = current_class_depth; }
| '(' expr_or_declarator ')'
| '(' expr_or_declarator ')'
{ $$ = finish_decl_parsing ($2); }
{ $$ = finish_decl_parsing ($2); }
;
;
...
@@ -1360,7 +1358,7 @@ primary:
...
@@ -1360,7 +1358,7 @@ primary:
$<ttype>$ = expand_start_stmt_expr (); }
$<ttype>$ = expand_start_stmt_expr (); }
compstmt ')'
compstmt ')'
{ tree rtl_exp;
{ tree rtl_exp;
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids braced-groups within expressions");
pedwarn ("ANSI C++ forbids braced-groups within expressions");
rtl_exp = expand_end_stmt_expr ($<ttype>2);
rtl_exp = expand_end_stmt_expr ($<ttype>2);
/* The statements have side effects, so the group does. */
/* The statements have side effects, so the group does. */
...
@@ -1554,7 +1552,7 @@ primary:
...
@@ -1554,7 +1552,7 @@ primary:
| object unqualified_id %prec UNARY
| object unqualified_id %prec UNARY
{ got_object = NULL_TREE;
{ got_object = NULL_TREE;
$$ = build_component_ref ($$, $2, NULL_TREE, 1); }
$$ = build_component_ref ($$, $2, NULL_TREE, 1); }
| object qualified_id %prec UNARY
| object
over
qualified_id %prec UNARY
{ got_object = NULL_TREE;
{ got_object = NULL_TREE;
$$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
$$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
| object unqualified_id '(' nonnull_exprlist ')'
| object unqualified_id '(' nonnull_exprlist ')'
...
@@ -1589,7 +1587,7 @@ primary:
...
@@ -1589,7 +1587,7 @@ primary:
(LOOKUP_NORMAL|LOOKUP_AGGR));
(LOOKUP_NORMAL|LOOKUP_AGGR));
#endif
#endif
}
}
| object qualified_id '(' nonnull_exprlist ')'
| object
over
qualified_id '(' nonnull_exprlist ')'
{
{
got_object = NULL_TREE;
got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
...
@@ -1601,7 +1599,7 @@ primary:
...
@@ -1601,7 +1599,7 @@ primary:
else
else
$$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4);
$$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4);
}
}
| object qualified_id LEFT_RIGHT
| object
over
qualified_id LEFT_RIGHT
{
{
got_object = NULL_TREE;
got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
...
@@ -1617,8 +1615,9 @@ primary:
...
@@ -1617,8 +1615,9 @@ primary:
| object '~' TYPESPEC LEFT_RIGHT
| object '~' TYPESPEC LEFT_RIGHT
{
{
got_object = NULL_TREE;
got_object = NULL_TREE;
if (TREE_CODE (TREE_TYPE ($1))
if (IDENTIFIER_GLOBAL_VALUE ($3)
!= TREE_CODE (TREE_TYPE (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);
cp_error ("`%E' is not of type `%T'", $1, $3);
$$ = convert (void_type_node, $1);
$$ = convert (void_type_node, $1);
}
}
...
@@ -1654,7 +1653,7 @@ primary_no_id:
...
@@ -1654,7 +1653,7 @@ primary_no_id:
}
}
$<ttype>$ = expand_start_stmt_expr (); }
$<ttype>$ = expand_start_stmt_expr (); }
compstmt ')'
compstmt ')'
{ if (
flag_ansi
)
{ if (
pedantic
)
pedwarn ("ANSI C++ forbids braced-groups within expressions");
pedwarn ("ANSI C++ forbids braced-groups within expressions");
$$ = expand_end_stmt_expr ($<ttype>2); }
$$ = expand_end_stmt_expr ($<ttype>2); }
| primary_no_id '(' nonnull_exprlist ')'
| primary_no_id '(' nonnull_exprlist ')'
...
@@ -1816,6 +1815,8 @@ typed_declspecs1:
...
@@ -1816,6 +1815,8 @@ typed_declspecs1:
{ $$ = decl_tree_cons (NULL_TREE, $2, $$); }
{ $$ = decl_tree_cons (NULL_TREE, $2, $$); }
| typespec reserved_declspecs %prec HYPERUNARY
| typespec reserved_declspecs %prec HYPERUNARY
{ $$ = decl_tree_cons (NULL_TREE, $$, $2); }
{ $$ = decl_tree_cons (NULL_TREE, $$, $2); }
| typespec reserved_typespecquals reserved_declspecs
{ $$ = decl_tree_cons (NULL_TREE, $$, chainon ($2, $3)); }
| declmods typespec reserved_declspecs
| declmods typespec reserved_declspecs
{ $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); }
{ $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); }
| declmods typespec reserved_typespecquals
| declmods typespec reserved_typespecquals
...
@@ -1902,11 +1903,11 @@ typespec: structsp
...
@@ -1902,11 +1903,11 @@ typespec: structsp
| complete_type_name
| complete_type_name
| TYPEOF '(' expr ')'
| TYPEOF '(' expr ')'
{ $$ = TREE_TYPE ($3);
{ $$ = TREE_TYPE ($3);
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids `typeof'"); }
pedwarn ("ANSI C++ forbids `typeof'"); }
| TYPEOF '(' type_id ')'
| TYPEOF '(' type_id ')'
{ $$ = groktypename ($3);
{ $$ = groktypename ($3);
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids `typeof'"); }
pedwarn ("ANSI C++ forbids `typeof'"); }
| SIGOF '(' expr ')'
| SIGOF '(' expr ')'
{ tree type = TREE_TYPE ($3);
{ tree type = TREE_TYPE ($3);
...
@@ -2763,7 +2764,7 @@ new_type_id:
...
@@ -2763,7 +2764,7 @@ new_type_id:
non-constant dimension. */
non-constant dimension. */
| '(' type_id ')' '[' expr ']'
| '(' type_id ')' '[' expr ']'
{
{
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new");
pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new");
$$ = build_parse_node (ARRAY_REF, TREE_VALUE ($2), $5);
$$ = build_parse_node (ARRAY_REF, TREE_VALUE ($2), $5);
$$ = build_decl_list (TREE_PURPOSE ($2), $$);
$$ = build_decl_list (TREE_PURPOSE ($2), $$);
...
@@ -2905,6 +2906,9 @@ complex_direct_notype_declarator:
...
@@ -2905,6 +2906,9 @@ complex_direct_notype_declarator:
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
| direct_notype_declarator '[' ']'
| direct_notype_declarator '[' ']'
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
| notype_qualified_id
{ push_nested_class (TREE_TYPE (OP0 ($$)), 3);
TREE_COMPLEXITY ($$) = current_class_depth; }
;
;
qualified_id:
qualified_id:
...
@@ -3107,7 +3111,7 @@ errstmt: error ';'
...
@@ -3107,7 +3111,7 @@ errstmt: error ';'
maybe_label_decls:
maybe_label_decls:
/* empty */
/* empty */
| label_decls
| label_decls
{ if (
flag_ansi
)
{ if (
pedantic
)
pedwarn ("ANSI C++ forbids label declarations"); }
pedwarn ("ANSI C++ forbids label declarations"); }
;
;
...
@@ -3323,7 +3327,7 @@ simple_stmt:
...
@@ -3323,7 +3327,7 @@ simple_stmt:
register tree label
register tree label
= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
if (
flag_ansi
)
if (
pedantic
)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
pedwarn ("ANSI C++ forbids range expressions in switch statement");
if (value1 != error_mark_node
if (value1 != error_mark_node
&& value2 != error_mark_node)
&& value2 != error_mark_node)
...
...
gcc/cp/pt.c
View file @
b7484fbe
...
@@ -755,6 +755,8 @@ uses_template_parms (t)
...
@@ -755,6 +755,8 @@ uses_template_parms (t)
case
REFERENCE_TYPE
:
case
REFERENCE_TYPE
:
return
uses_template_parms
(
TREE_TYPE
(
t
));
return
uses_template_parms
(
TREE_TYPE
(
t
));
case
RECORD_TYPE
:
case
RECORD_TYPE
:
if
(
TYPE_PTRMEMFUNC_FLAG
(
t
))
return
uses_template_parms
(
TYPE_PTRMEMFUNC_FN_TYPE
(
t
));
case
UNION_TYPE
:
case
UNION_TYPE
:
if
(
!
TYPE_NAME
(
t
))
if
(
!
TYPE_NAME
(
t
))
return
0
;
return
0
;
...
@@ -1153,9 +1155,8 @@ tsubst (t, args, nargs, in_decl)
...
@@ -1153,9 +1155,8 @@ tsubst (t, args, nargs, in_decl)
&&
type
!=
integer_type_node
&&
type
!=
integer_type_node
&&
type
!=
void_type_node
&&
type
!=
void_type_node
&&
type
!=
char_type_node
)
&&
type
!=
char_type_node
)
type
=
cp_build_type_variant
(
tsubst
(
type
,
args
,
nargs
,
in_decl
),
type
=
tsubst
(
type
,
args
,
nargs
,
in_decl
);
TYPE_READONLY
(
type
),
TYPE_VOLATILE
(
type
));
switch
(
TREE_CODE
(
t
))
switch
(
TREE_CODE
(
t
))
{
{
case
RECORD_TYPE
:
case
RECORD_TYPE
:
...
@@ -1679,12 +1680,16 @@ instantiate_template (tmpl, targ_ptr)
...
@@ -1679,12 +1680,16 @@ instantiate_template (tmpl, targ_ptr)
my_friendly_assert
(
TREE_CODE
(
tmpl
)
==
TEMPLATE_DECL
,
283
);
my_friendly_assert
(
TREE_CODE
(
tmpl
)
==
TEMPLATE_DECL
,
283
);
len
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
tmpl
));
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
);
for
(
fndecl
=
DECL_TEMPLATE_INSTANTIATIONS
(
tmpl
);
fndecl
;
fndecl
=
TREE_CHAIN
(
fndecl
))
fndecl
;
fndecl
=
TREE_CHAIN
(
fndecl
))
{
{
tree
*
t1
=
&
TREE_VEC_ELT
(
TREE_PURPOSE
(
fndecl
),
0
);
tree
*
t1
=
&
TREE_VEC_ELT
(
TREE_PURPOSE
(
fndecl
),
0
);
for
(
i
=
len
-
1
;
i
>=
0
;
i
--
)
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
;
goto
no_match
;
/* Here, we have a match. */
/* Here, we have a match. */
...
@@ -2036,6 +2041,15 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
...
@@ -2036,6 +2041,15 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
return
1
;
return
1
;
if
(
arg
==
unknown_type_node
)
if
(
arg
==
unknown_type_node
)
return
1
;
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 0
if (TREE_CODE (arg) == VAR_DECL)
if (TREE_CODE (arg) == VAR_DECL)
arg = TREE_TYPE (arg);
arg = TREE_TYPE (arg);
...
...
gcc/cp/tree.c
View file @
b7484fbe
...
@@ -1740,6 +1740,9 @@ make_deep_copy (t)
...
@@ -1740,6 +1740,9 @@ make_deep_copy (t)
case
ARRAY_TYPE
:
case
ARRAY_TYPE
:
return
build_array_type
(
make_deep_copy
(
TREE_TYPE
(
t
)),
return
build_array_type
(
make_deep_copy
(
TREE_TYPE
(
t
)),
make_deep_copy
(
TYPE_DOMAIN
(
t
)));
make_deep_copy
(
TYPE_DOMAIN
(
t
)));
case
INTEGER_TYPE
:
return
build_index_type
(
make_deep_copy
(
TYPE_MAX_VALUE
(
t
)));
case
OFFSET_TYPE
:
case
OFFSET_TYPE
:
return
build_offset_type
(
make_deep_copy
(
TYPE_OFFSET_BASETYPE
(
t
)),
return
build_offset_type
(
make_deep_copy
(
TYPE_OFFSET_BASETYPE
(
t
)),
make_deep_copy
(
TREE_TYPE
(
t
)));
make_deep_copy
(
TREE_TYPE
(
t
)));
...
@@ -1749,6 +1752,7 @@ make_deep_copy (t)
...
@@ -1749,6 +1752,7 @@ make_deep_copy (t)
build_function_type
build_function_type
(
make_deep_copy
(
TREE_TYPE
(
t
)),
(
make_deep_copy
(
TREE_TYPE
(
t
)),
make_deep_copy
(
TREE_CHAIN
(
TYPE_ARG_TYPES
(
t
)))));
make_deep_copy
(
TREE_CHAIN
(
TYPE_ARG_TYPES
(
t
)))));
case
RECORD_TYPE
:
case
RECORD_TYPE
:
if
(
TYPE_PTRMEMFUNC_P
(
t
))
if
(
TYPE_PTRMEMFUNC_P
(
t
))
return
build_ptrmemfunc_type
return
build_ptrmemfunc_type
...
...
gcc/cp/typeck.c
View file @
b7484fbe
...
@@ -719,7 +719,28 @@ comptypes (type1, type2, strict)
...
@@ -719,7 +719,28 @@ comptypes (type1, type2, strict)
return
1
;
return
1
;
case
UNINSTANTIATED_P_TYPE
:
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
;
return
attrval
==
2
&&
val
==
1
?
2
:
val
;
}
}
...
@@ -1834,26 +1855,6 @@ build_array_ref (array, idx)
...
@@ -1834,26 +1855,6 @@ build_array_ref (array, idx)
return
error_mark_node
;
return
error_mark_node
;
itype
=
TREE_TYPE
(
idx
);
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
if
(
TREE_CODE
(
TREE_TYPE
(
array
))
==
ARRAY_TYPE
&&
TREE_CODE
(
array
)
!=
INDIRECT_REF
)
&&
TREE_CODE
(
array
)
!=
INDIRECT_REF
)
...
@@ -1902,19 +1903,19 @@ build_array_ref (array, idx)
...
@@ -1902,19 +1903,19 @@ build_array_ref (array, idx)
return
error_mark_node
;
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
))
if
(
pedantic
&&
!
lvalue_p
(
array
))
pedwarn
(
"ANSI C++ forbids subscripting non-lvalue 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
;
tree
foo
=
array
;
while
(
TREE_CODE
(
foo
)
==
COMPONENT_REF
)
while
(
TREE_CODE
(
foo
)
==
COMPONENT_REF
)
foo
=
TREE_OPERAND
(
foo
,
0
);
foo
=
TREE_OPERAND
(
foo
,
0
);
if
(
TREE_CODE
(
foo
)
==
VAR_DECL
&&
DECL_REGISTER
(
foo
))
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
)));
type
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
TREE_TYPE
(
array
)));
...
@@ -2122,7 +2123,7 @@ build_x_function_call (function, params, decl)
...
@@ -2122,7 +2123,7 @@ build_x_function_call (function, params, decl)
decl
=
C_C_D
;
decl
=
C_C_D
;
decl_addr
=
build_unary_op
(
ADDR_EXPR
,
decl
,
0
);
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
));
TREE_OPERAND
(
function
,
1
));
params
=
tree_cons
(
NULL_TREE
,
decl_addr
,
params
);
params
=
tree_cons
(
NULL_TREE
,
decl_addr
,
params
);
return
build_function_call
(
function
,
params
);
return
build_function_call
(
function
,
params
);
...
@@ -2184,9 +2185,8 @@ build_x_function_call (function, params, decl)
...
@@ -2184,9 +2185,8 @@ build_x_function_call (function, params, decl)
instance to use, if the member points to a virtual member. */
instance to use, if the member points to a virtual member. */
tree
tree
get_member_function_from_ptrfunc
(
instance_ptrptr
,
instance
,
function
)
get_member_function_from_ptrfunc
(
instance_ptrptr
,
function
)
tree
*
instance_ptrptr
;
tree
*
instance_ptrptr
;
tree
instance
;
tree
function
;
tree
function
;
{
{
if
(
TREE_CODE
(
function
)
==
OFFSET_REF
)
if
(
TREE_CODE
(
function
)
==
OFFSET_REF
)
...
@@ -2200,7 +2200,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
...
@@ -2200,7 +2200,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
tree
index
=
save_expr
(
build_component_ref
(
function
,
tree
index
=
save_expr
(
build_component_ref
(
function
,
index_identifier
,
index_identifier
,
0
,
0
));
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
));
convert
(
delta_type_node
,
integer_zero_node
));
tree
delta
=
convert
(
ptrdiff_type_node
,
tree
delta
=
convert
(
ptrdiff_type_node
,
build_component_ref
(
function
,
delta_identifier
,
0
,
0
));
build_component_ref
(
function
,
delta_identifier
,
0
,
0
));
...
@@ -2209,9 +2209,16 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
...
@@ -2209,9 +2209,16 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
tree
e3
;
tree
e3
;
tree
aref
,
vtbl
;
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. */
/* convert down to the right base, before using the instance. */
instance
=
convert_pointer_to_real
(
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
fntype
)),
instance
build_unary_op
(
ADDR_EXPR
,
instance
,
0
));
=
convert_pointer_to_real
(
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
fntype
)),
instance_ptr
);
if
(
instance
==
error_mark_node
)
if
(
instance
==
error_mark_node
)
return
instance
;
return
instance
;
...
@@ -2238,9 +2245,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
...
@@ -2238,9 +2245,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
delta
,
1
);
delta
,
1
);
}
}
*
instance_ptrptr
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
*
instance_ptrptr
),
*
instance_ptrptr
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
instance_ptr
),
*
instance_ptrptr
,
instance_ptr
,
delta
);
delta
);
if
(
flag_vtable_thunks
)
if
(
flag_vtable_thunks
)
e2
=
aref
;
e2
=
aref
;
else
else
...
@@ -2249,6 +2255,12 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
...
@@ -2249,6 +2255,12 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
e3
=
PFN_FROM_PTRMEMFUNC
(
function
);
e3
=
PFN_FROM_PTRMEMFUNC
(
function
);
TREE_TYPE
(
e2
)
=
TREE_TYPE
(
e3
);
TREE_TYPE
(
e2
)
=
TREE_TYPE
(
e3
);
function
=
build_conditional_expr
(
e1
,
e2
,
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
;
return
function
;
}
}
...
@@ -2325,7 +2337,7 @@ build_function_call_real (function, params, require_complete, flags)
...
@@ -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
);
tree
instance_ptr
=
build_unary_op
(
ADDR_EXPR
,
C_C_D
,
0
);
fntype
=
TYPE_PTRMEMFUNC_FN_TYPE
(
fntype
);
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
is_method
=
(
TREE_CODE
(
fntype
)
==
POINTER_TYPE
...
@@ -2715,7 +2727,6 @@ build_binary_op (code, arg1, arg2, convert_p)
...
@@ -2715,7 +2727,6 @@ build_binary_op (code, arg1, arg2, convert_p)
tree
arg1
,
arg2
;
tree
arg1
,
arg2
;
int
convert_p
;
int
convert_p
;
{
{
tree
type1
,
type2
;
tree
args
[
2
];
tree
args
[
2
];
args
[
0
]
=
arg1
;
args
[
0
]
=
arg1
;
...
@@ -2724,64 +2735,39 @@ build_binary_op (code, arg1, arg2, convert_p)
...
@@ -2724,64 +2735,39 @@ build_binary_op (code, arg1, arg2, convert_p)
if
(
convert_p
)
if
(
convert_p
)
{
{
tree
args_save
[
2
];
tree
args_save
[
2
];
tree
type0
,
type1
;
args
[
0
]
=
args_save
[
0
]
=
default_conversion
(
args
[
0
]);
args
[
0
]
=
args_save
[
0
]
=
default_conversion
(
args
[
0
]);
args
[
1
]
=
args_save
[
1
]
=
default_conversion
(
args
[
1
]);
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
]))
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
]);
args
[
0
]
=
default_conversion
(
args
[
0
]);
}
}
else
if
(
type_unknown_p
(
args
[
1
]))
else
if
(
type_unknown_p
(
args
[
1
]))
{
{
args
[
1
]
=
require_instantiated_type
(
TREE_TYPE
(
args
[
0
]),
args
[
1
]
=
require_instantiated_type
(
type0
,
args
[
1
],
args
[
1
],
error_mark_node
);
error_mark_node
);
args
[
1
]
=
default_conversion
(
args
[
1
]);
args
[
1
]
=
default_conversion
(
args
[
1
]);
}
}
type1
=
TREE_TYPE
(
args
[
0
]);
if
(
IS_AGGR_TYPE
(
type0
)
||
IS_AGGR_TYPE
(
type1
))
type2
=
TREE_TYPE
(
args
[
1
]);
if
(
IS_AGGR_TYPE_2
(
type1
,
type2
))
{
{
/* Try to convert this to something reasonable. */
/* Try to convert this to something reasonable. */
if
(
!
build_default_binary_type_conversion
(
code
,
&
args
[
0
],
&
args
[
1
]))
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
,
cp_error
(
"no match for `%O(%#T, %#T)'"
,
code
,
TREE_TYPE
(
arg1
),
TREE_TYPE
(
arg2
));
TREE_TYPE
(
arg1
),
TREE_TYPE
(
arg2
));
return
error_mark_node
;
return
error_mark_node
;
}
}
if
(
try
==
error_mark_node
)
error
(
"ambiguous pointer conversion"
);
args
[
convert_index
]
=
try
;
}
}
if
(
args
[
0
]
==
args_save
[
0
])
if
(
args
[
0
]
==
args_save
[
0
])
args
[
0
]
=
arg1
;
args
[
0
]
=
arg1
;
if
(
args
[
1
]
==
args_save
[
1
])
if
(
args
[
1
]
==
args_save
[
1
])
...
@@ -3094,7 +3080,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
...
@@ -3094,7 +3080,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
{
{
tree
base
=
common_base_type
(
tt0
,
tt1
);
tree
base
=
common_base_type
(
tt0
,
tt1
);
if
(
base
==
NULL_TREE
)
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
)
else
if
(
base
==
error_mark_node
)
{
{
cp_error
(
"comparison of pointer types `%T' and `%T' requires conversion to ambiguous supertype"
,
type0
,
type1
);
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)
...
@@ -3119,6 +3105,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
if
(
pedantic
&&
TREE_CODE
(
tt1
)
==
FUNCTION_TYPE
if
(
pedantic
&&
TREE_CODE
(
tt1
)
==
FUNCTION_TYPE
&&
tree_int_cst_lt
(
TYPE_SIZE
(
type0
),
TYPE_SIZE
(
type1
)))
&&
tree_int_cst_lt
(
TYPE_SIZE
(
type0
),
TYPE_SIZE
(
type1
)))
pedwarn
(
"ANSI C++ forbids comparison of `void *' with function pointer"
);
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
)
else
if
(
tt1
==
void_type_node
)
{
{
...
@@ -3291,18 +3279,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
...
@@ -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
else
if
(
code0
==
POINTER_TYPE
&&
TREE_CODE
(
op1
)
==
INTEGER_CST
&&
integer_zerop
(
op1
))
&&
integer_zerop
(
op1
))
{
op1
=
null_pointer_node
;
op1
=
null_pointer_node
;
if
(
pedantic
)
pedwarn
(
"ordered comparison of pointer with integer zero"
);
}
else
if
(
code1
==
POINTER_TYPE
&&
TREE_CODE
(
op0
)
==
INTEGER_CST
else
if
(
code1
==
POINTER_TYPE
&&
TREE_CODE
(
op0
)
==
INTEGER_CST
&&
integer_zerop
(
op0
))
&&
integer_zerop
(
op0
))
{
op0
=
null_pointer_node
;
op0
=
null_pointer_node
;
if
(
pedantic
)
pedwarn
(
"ANSI C++ forbids ordered comparison of pointer with integer zero"
);
}
else
if
(
code0
==
POINTER_TYPE
&&
code1
==
INTEGER_TYPE
)
else
if
(
code0
==
POINTER_TYPE
&&
code1
==
INTEGER_TYPE
)
{
{
if
(
pedantic
)
if
(
pedantic
)
...
@@ -3482,14 +3462,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
...
@@ -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
/* Do the checking based on the original operand trees, so that
casts will be considered, but default promotions won't be. */
casts will be considered, but default promotions won't be. */
if
(
TREE_UNSIGNED
(
comp_type
)
if
(
TREE_UNSIGNED
(
comp_type
)
&&
((
op0_signed
&&
((
op0_signed
&&
(
TREE_CODE
(
orig_op0
)
!=
INTEGER_CST
&&
(
TREE_CODE
(
op0
)
!=
INTEGER_CST
||
tree_int_cst_sgn
(
orig_op0
)
==
-
1
))
||
(
TREE_CODE
(
op0
)
==
INTEGER_CST
||
(
op1_signed
&&
(
TREE_CODE
(
orig_op1
)
!=
INTEGER_CST
&&
INT_CST_LT
(
op0
,
integer_zero_node
))))
||
tree_int_cst_sgn
(
orig_op1
)
==
-
1
))))
||
(
op1_signed
&&
(
TREE_CODE
(
op1
)
!=
INTEGER_CST
||
(
TREE_CODE
(
op1
)
==
INTEGER_CST
&&
INT_CST_LT
(
op1
,
integer_zero_node
))))))
warning
(
"comparison between signed and unsigned"
);
warning
(
"comparison between signed and unsigned"
);
/* Warn if two unsigned values are being compared in a size
/* Warn if two unsigned values are being compared in a size
...
@@ -3830,121 +3806,46 @@ build_unary_op (code, xarg, noconvert)
...
@@ -3830,121 +3806,46 @@ build_unary_op (code, xarg, noconvert)
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
register
tree
arg
=
xarg
;
register
tree
arg
=
xarg
;
register
tree
argtype
=
0
;
register
tree
argtype
=
0
;
register
enum
tree_code
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
char
*
errstring
=
NULL
;
char
*
errstring
=
NULL
;
tree
val
;
tree
val
;
int
isaggrtype
;
if
(
typecode
==
ERROR_MARK
)
if
(
arg
==
error_mark_node
)
return
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
)
switch
(
code
)
{
{
case
CONVERT_EXPR
:
case
CONVERT_EXPR
:
/* This is used for unary plus, because a CONVERT_EXPR
/* This is used for unary plus, because a CONVERT_EXPR
is enough to prevent anybody from looking inside for
is enough to prevent anybody from looking inside for
associativity, but won't generate any code. */
associativity, but won't generate any code. */
if
(
!
(
typecode
==
INTEGER_TYPE
||
typecode
==
REAL_TYPE
))
if
(
!
(
arg
=
build_expr_type_conversion
errstring
=
"wrong type argument to unary plus"
;
(
WANT_ARITH
|
WANT_ENUM
|
WANT_POINTER
,
arg
,
1
)))
else
if
(
!
noconvert
)
errstring
=
"wrong type argument to unary plus"
;
arg
=
default_conversion
(
arg
);
else
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
(
!
noconvert
)
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
arg
=
default_conversion
(
arg
);
else
arg
=
build1
(
NON_LVALUE_EXPR
,
TREE_TYPE
(
arg
),
arg
);
{
cp_error
(
"type conversion for type `%T' not allowed"
,
TREE_TYPE
(
arg
));
return
error_mark_node
;
}
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
noconvert
=
1
;
}
}
break
;
if
(
!
(
typecode
==
INTEGER_TYPE
||
typecode
==
REAL_TYPE
))
case
NEGATE_EXPR
:
errstring
=
"wrong type argument to unary minus"
;
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
arg
,
1
)))
errstring
=
"wrong type argument to unary minus"
;
else
if
(
!
noconvert
)
else
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
arg
=
default_conversion
(
arg
);
break
;
break
;
case
BIT_NOT_EXPR
:
case
BIT_NOT_EXPR
:
if
(
typecode
==
OFFSET_TYPE
)
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_INT
|
WANT_ENUM
,
arg
,
1
)))
{
errstring
=
"wrong type argument to bit-complement"
;
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"
;
else
if
(
!
noconvert
)
else
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
arg
=
default_conversion
(
arg
);
break
;
break
;
case
ABS_EXPR
:
case
ABS_EXPR
:
if
(
typecode
==
OFFSET_TYPE
)
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_ENUM
,
arg
,
1
)))
{
errstring
=
"wrong type argument to abs"
;
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"
;
else
if
(
!
noconvert
)
else
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
arg
=
default_conversion
(
arg
);
break
;
break
;
...
@@ -3973,21 +3874,8 @@ build_unary_op (code, xarg, noconvert)
...
@@ -3973,21 +3874,8 @@ build_unary_op (code, xarg, noconvert)
/* Report invalid types. */
/* Report invalid types. */
if
(
typecode
==
OFFSET_TYPE
)
if
(
!
(
arg
=
build_expr_type_conversion
(
WANT_ARITH
|
WANT_POINTER
,
{
arg
,
1
)))
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
(
code
==
PREINCREMENT_EXPR
)
if
(
code
==
PREINCREMENT_EXPR
)
errstring
=
"no pre-increment operator for type"
;
errstring
=
"no pre-increment operator for type"
;
...
@@ -4024,7 +3912,7 @@ build_unary_op (code, xarg, noconvert)
...
@@ -4024,7 +3912,7 @@ build_unary_op (code, xarg, noconvert)
/* Compute the increment. */
/* Compute the increment. */
if
(
typecode
==
POINTER_TYPE
)
if
(
TREE_CODE
(
argtype
)
==
POINTER_TYPE
)
{
{
enum
tree_code
tmp
=
TREE_CODE
(
TREE_TYPE
(
argtype
));
enum
tree_code
tmp
=
TREE_CODE
(
TREE_TYPE
(
argtype
));
if
(
TYPE_SIZE
(
TREE_TYPE
(
argtype
))
==
0
)
if
(
TYPE_SIZE
(
TREE_TYPE
(
argtype
))
==
0
)
...
@@ -4081,7 +3969,37 @@ build_unary_op (code, xarg, noconvert)
...
@@ -4081,7 +3969,37 @@ build_unary_op (code, xarg, noconvert)
?
"increment"
:
"decrement"
)))
?
"increment"
:
"decrement"
)))
return
error_mark_node
;
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
;
TREE_SIDE_EFFECTS
(
val
)
=
1
;
return
convert
(
result_type
,
val
);
return
convert
(
result_type
,
val
);
}
}
...
@@ -4090,7 +4008,8 @@ build_unary_op (code, xarg, noconvert)
...
@@ -4090,7 +4008,8 @@ build_unary_op (code, xarg, noconvert)
/* Note that this operation never does default_conversion
/* Note that this operation never does default_conversion
regardless of NOCONVERT. */
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
);
arg
=
build1
(
CONVERT_EXPR
,
build_pointer_type
(
TREE_TYPE
(
TREE_TYPE
(
arg
))),
arg
);
TREE_REFERENCE_EXPR
(
arg
)
=
1
;
TREE_REFERENCE_EXPR
(
arg
)
=
1
;
...
@@ -4194,13 +4113,12 @@ build_unary_op (code, xarg, noconvert)
...
@@ -4194,13 +4113,12 @@ build_unary_op (code, xarg, noconvert)
;
;
/* Anything not already handled and not a true memory reference
/* Anything not already handled and not a true memory reference
is an error. */
is an error. */
else
if
(
typecode
!=
FUNCTION_TYPE
else
if
(
TREE_CODE
(
argtype
)
!=
FUNCTION_TYPE
&&
typecode
!=
METHOD_TYPE
&&
TREE_CODE
(
argtype
)
!=
METHOD_TYPE
&&
!
lvalue_or_else
(
arg
,
"unary `&'"
))
&&
!
lvalue_or_else
(
arg
,
"unary `&'"
))
return
error_mark_node
;
return
error_mark_node
;
/* Ordinary case; arg is a COMPONENT_REF or a decl. */
/* Ordinary case; arg is a COMPONENT_REF or a decl. */
argtype
=
TREE_TYPE
(
arg
);
/* If the lvalue is const or volatile,
/* If the lvalue is const or volatile,
merge that into the type that the address will point to. */
merge that into the type that the address will point to. */
if
(
TREE_CODE_CLASS
(
TREE_CODE
(
arg
))
==
'd'
if
(
TREE_CODE_CLASS
(
TREE_CODE
(
arg
))
==
'd'
...
@@ -4900,10 +4818,25 @@ build_compound_expr (list)
...
@@ -4900,10 +4818,25 @@ build_compound_expr (list)
rest
=
build_compound_expr
(
TREE_CHAIN
(
list
));
rest
=
build_compound_expr
(
TREE_CHAIN
(
list
));
/* When pedantic, a compound expression can be neither an lvalue
if
(
!
TREE_SIDE_EFFECTS
(
TREE_VALUE
(
list
)))
nor an integer constant expression. */
{
if
(
!
TREE_SIDE_EFFECTS
(
TREE_VALUE
(
list
))
&&
!
pedantic
)
/* the left-hand operand of a comma expression is like an expression
return
rest
;
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
),
return
build
(
COMPOUND_EXPR
,
TREE_TYPE
(
rest
),
break_out_cleanups
(
TREE_VALUE
(
list
)),
rest
);
break_out_cleanups
(
TREE_VALUE
(
list
)),
rest
);
...
@@ -5629,8 +5562,6 @@ build_modify_expr (lhs, modifycode, rhs)
...
@@ -5629,8 +5562,6 @@ build_modify_expr (lhs, modifycode, rhs)
cp_error
(
"`%T' does not define operator="
,
lhstype
);
cp_error
(
"`%T' does not define operator="
,
lhstype
);
else
if
(
!
TYPE_HAS_REAL_ASSIGNMENT
(
lhstype
)
else
if
(
!
TYPE_HAS_REAL_ASSIGNMENT
(
lhstype
)
&&
!
TYPE_HAS_COMPLEX_ASSIGN_REF
(
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
)))
&&
TYPE_MAIN_VARIANT
(
lhstype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
newrhs
)))
/* Do the default thing */
;
/* Do the default thing */
;
else
else
...
@@ -5697,7 +5628,11 @@ build_modify_expr (lhs, modifycode, rhs)
...
@@ -5697,7 +5628,11 @@ build_modify_expr (lhs, modifycode, rhs)
newrhs
=
build_binary_op
(
modifycode
,
lhs
,
rhs_tmp
,
1
);
newrhs
=
build_binary_op
(
modifycode
,
lhs
,
rhs_tmp
,
1
);
}
}
else
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
else
{
{
...
@@ -6008,18 +5943,32 @@ build_modify_expr (lhs, modifycode, rhs)
...
@@ -6008,18 +5943,32 @@ build_modify_expr (lhs, modifycode, rhs)
}
}
else
else
newrhs
=
convert_for_assignment
(
lhstype
,
newrhs
,
"assignment"
,
newrhs
=
convert_for_assignment
(
lhstype
,
newrhs
,
"assignment"
,
NULL_TREE
,
0
);
NULL_TREE
,
0
);
if
(
flag_elide_constructors
==
0
if
(
TREE_CODE
(
newrhs
)
==
CALL_EXPR
&&
TREE_CODE
(
newrhs
)
==
CALL_EXPR
&&
TYPE_NEEDS_CONSTRUCTING
(
lhstype
))
&&
TREE_ADDRESSABLE
(
lhstype
))
newrhs
=
build_cplus_new
(
lhstype
,
newrhs
,
0
);
if
(
TREE_CODE
(
newrhs
)
==
TARGET_EXPR
)
{
{
/* Can't initialized directly from a CALL_EXPR, since
/* Can't initialize directly from a TARGET_EXPR, since that would
we don't know about what doesn't alias what. */
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
);
do_pending_stack_adjust
();
newrhs
=
build
(
COMPOUND_EXPR
,
lhstype
,
start_sequence_for_rtl_expr
(
xval
);
build_modify_expr
(
temp
,
INIT_EXPR
,
newrhs
),
emit_note
(
0
,
-
1
);
temp
);
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)
...
@@ -6172,7 +6121,7 @@ get_delta_difference (from, to, force)
}
}
if
(
TREE_VIA_VIRTUAL
(
binfo
))
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
,
return
build_binary_op
(
MINUS_EXPR
,
integer_zero_node
,
integer_zero_node
,
...
@@ -6180,7 +6129,7 @@ get_delta_difference (from, to, force)
...
@@ -6180,7 +6129,7 @@ get_delta_difference (from, to, force)
}
}
if
(
TREE_VIA_VIRTUAL
(
binfo
))
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
);
return
BINFO_OFFSET
(
binfo
);
}
}
...
@@ -6241,7 +6190,7 @@ build_ptrmemfunc (type, pfn, force)
...
@@ -6241,7 +6190,7 @@ build_ptrmemfunc (type, pfn, force)
force
);
force
);
delta
=
build_binary_op
(
PLUS_EXPR
,
delta
,
ndelta
,
1
);
delta
=
build_binary_op
(
PLUS_EXPR
,
delta
,
ndelta
,
1
);
delta2
=
build_binary_op
(
PLUS_EXPR
,
ndelta2
,
delta2
,
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
(
delta2_identifier
,
delta2
,
NULL_TREE
));
u
=
build_nt
(
CONSTRUCTOR
,
0
,
tree_cons
(
NULL_TREE
,
delta
,
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)
...
@@ -329,7 +329,7 @@ ack (s, v, v2)
silly. So instead, we just do the equivalent of a call to fatal in the
silly. So instead, we just do the equivalent of a call to fatal in the
same situation (call exit). */
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
;
static
int
abortcount
=
0
;
...
@@ -855,6 +855,14 @@ digest_init (type, init, tail)
...
@@ -855,6 +855,14 @@ digest_init (type, init, tail)
}
}
init
=
element
;
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
,
return
convert_for_initialization
(
0
,
type
,
init
,
LOOKUP_NORMAL
,
"initialization"
,
NULL_TREE
,
0
);
"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