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
e1cd6e56
Commit
e1cd6e56
authored
Jan 24, 1995
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
53rd Cygnus<->FSF merge
From-SVN: r8794
parent
43238b97
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1307 additions
and
879 deletions
+1307
-879
gcc/cp/ChangeLog
+369
-6
gcc/cp/call.c
+55
-116
gcc/cp/class.c
+122
-139
gcc/cp/cp-tree.h
+17
-11
gcc/cp/cvt.c
+42
-312
gcc/cp/decl.c
+241
-162
gcc/cp/decl2.c
+48
-20
gcc/cp/except.c
+94
-8
gcc/cp/gxx.gperf
+2
-0
gcc/cp/init.c
+9
-6
gcc/cp/lex.c
+23
-10
gcc/cp/lex.h
+1
-0
gcc/cp/parse.y
+29
-8
gcc/cp/pt.c
+6
-3
gcc/cp/search.c
+118
-19
gcc/cp/spew.c
+5
-1
gcc/cp/tree.c
+21
-3
gcc/cp/typeck.c
+105
-55
No files found.
gcc/cp/ChangeLog
View file @
e1cd6e56
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
TREE_CHAIN, we use it later.
Mon Jan 23 03:33:47 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (convert_for_assignment): Initialize variable before use.
Fri Jan 20 01:17:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* g++.c (main): Link with both libstdc++ and libg++ if called as
something ending with "g++", otherwise only libstdc++. Move -lm to
the end of the line.
Thu Jan 19 15:43:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* call.c (build_method_call): Don't mess with 'this' before calling
compute_conversion_costs.
Wed Jan 18 15:40:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* search.c (get_matching_virtual): Give line number for previous
declaration.
* call.c (convert_harshness): Handle conversions to references
better.
* cvt.c (build_up_reference): OK, handle {MIN,MAX}_EXPR *properly*.
Wed Jan 18 15:21:38 1995 Mike Stump <mrs@cygnus.com>
* class.c (instantiate_type): Use DECL_CHAIN to walk lists instead,
as the TREE_CHAIN for methods will take us to the next differently
named function, DECL_CHAIN won't.
Wed Jan 18 14:26:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* tree.c (lvalue_p): Handle {MIN,MAX}_EXPR.
* decl2.c (lang_decode_option): -Wall implies -Wparentheses.
warn_parentheses defaults to 0.
* decl.c (grokparms): Put back call to require_instantiated_type.
Tue Jan 17 19:56:15 1995 Mike Stump <mrs@cygnus.com>
* except.c (exception_section): Use the data section on the rs6000.
Change calling convention for named_section.
Wed Jan 17 18:20:57 1994 Fergus Henderson <fjh@munta.cs.mu.oz.au>
* cp-tree.h : Make if (x=0) warn with wall
* parse.y : Make if (x=0) warn with wall
Tue Jan 17 14:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
Tue Jan 17 14:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* cvt.c (cp_convert): Just call truthvalue_conversion to convert to
* decl.c (BOOL_TYPE_SIZE): BITS_PER_WORD if SLOW_BYTE_ACCESS,
BITS_PER_UNIT otherwise.
* search.c (get_matching_virtual): Don't check the binfo if the
types are the same.
* cvt.c (cp_convert): Just call truthvalue_conversion to convert to
bool.
bool.
Mon Jan 16 13:28:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
Mon Jan 16 13:28:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* various: Use boolean_type_node, boolean_true_node,
* various: Use boolean_type_node, boolean_true_node,
boolean_false_node.
boolean_false_node.
* search.c (get_matching_virtual): Allow covariant returns that
don't require pointer adjustment.
* typeck.c (build_conditional_expr): Don't call default_conversion
on ifexp.
* cvt.c (build_up_reference): Handle MIN_EXPR and MAX_EXPR.
* decl.c (grokdeclarator): Upgrade warning about &const to pedwarn.
Sun Jan 15 22:17:32 1995 dcb@lovat.fmrco.COM (David Binderman)
* pt.c (do_function_instantiation): Free targs once we're done.
Sun Jan 15 22:17:32 1995 Jason Merrill <jason@phydeaux.cygnus.com>
Sun Jan 15 22:17:32 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (BOOL_TYPE_SIZE): Defaults to BITS_PER_WORD.
* decl.c (BOOL_TYPE_SIZE): Defaults to BITS_PER_WORD.
(init_decl_processing): Use BOOL_TYPE_SIZE instead of CHAR_TYPE_SIZE
(init_decl_processing): Use BOOL_TYPE_SIZE instead of CHAR_TYPE_SIZE
for bool.
for bool.
Sat Jan 14 05:33:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (finish_file): We need to mess up if there are any
variables in the list, not just if there is one with a constructor.
Fri Jan 13 14:42:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (duplicate_decls): Propagate DECL_STATIC_{CON,DE}STRUCTOR.
(finish_function): Handle DECL_STATIC_{CON,DE}STRUCTOR.
(finish_function): Trust rest_of_compilation.
* decl2.c (finish_file): Also call functions designated as static
constructors/destructors.
* decl.c (grokdeclarator): Allow access decls of operator functions.
(grokparms): Only do convert_for_initialization if the initializer
has a type.
(duplicate_decls): Put back push_obstacks_nochange call.
* lex.c (real_yylex): Downgrade complaint about the escape sequence
being too large from pedwarn to warning.
* decl.c (grokdeclarator): Don't complain about long long in system
headers.
* lex.c (real_yylex): Handle digraphs.
Thu Jan 12 12:17:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (init_decl_processing): -f{no-,}strict-prototype only
affects C linkage declarations now.
* typeck.c (comp_target_types): Grok simple contravariant conversions.
(common_type): t1 and t2 are interchangeable.
* various: Test return value of comp_target_types differently in
different places; it now returns -1 for a contravariant conversion
(which is fine in symmetric cases).
(common_type): Prefer long double to double even when
they have the same precision.
* decl.c (grokparms): Call convert_for_initialization to check
default arguments.
* init.c (build_new): void_type_node has a size (of 0).
* decl.c (decls_match): Also check for agreement of TREE_READONLY
and TREE_THIS_VOLATILE.
(push_class_level_binding): Properly handle shadowing of
nested tags by fields.
* search.c (dfs_pushdecls): Ditto.
* decl2.c (finish_file): Don't second-guess self-initialization.
* cvt.c (convert_to_reference): Work with expr directly, rather than
a copy.
* decl.c (push_overloaded_decl): Only shadow artificial TYPE_DECLs.
* init.c (add_friend): Downgrade duplicate friend message from
pedwarn to warning.
* decl.c (duplicate_decls): Push obstacks before calling common_type.
Thu Jan 12 17:15:21 1995 Michael Ben-Gershon <mybg@cs.huji.ac.il>
* except.c (push_eh_entry): set LABEL_PRESERVE_P flag for
exception table labels.
(expand_start_all_catch): Ditto.
(expand_leftover_cleanups): Ditto.
(expand_end_catch_block): Ditto.
* except.c (make_first_label): new function.
(expand_start_all_catch): add a call to make_first_label() before
using a label as a jump destination.
(expand_end_all_catch): Ditto.
(expand_leftover_cleanups): Ditto.
(expand_end_catch_block): Ditto.
(expand_builtin_throw): Ditto.
(expand_throw): Ditto.
* except.c: Add ARM processor support for exception handling.
Thu Jan 12 12:17:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
(complete_array_type): Copy code from C frontend.
* lex.c (real_yylex): Don't multiply the length of a wide string
literal by WCHAR_BYTES.
* decl.c (pushdecl): Check for redeclaration of wchar_t here.
(duplicate_decls): Instead of here.
(define_label): Complain about a label named wchar_t.
(grokdeclarator): Complain about declarations of
operator-function-ids as non-functions.
* typeck.c (unary_complex_lvalue): Also wrap prefix -- and ++ in
COMPOUND_EXPRs.
(build_unary_op): Wrap unary plus in a NON_LVALUE_EXPR.
* lex.c (real_yylex): Don't skip whitespace when reading the next
character after ->.
Wed Jan 11 16:32:49 1995 Mike Stump <mrs@cygnus.com>
* except.c: Allow cc1plus to be built with native compiler on rs6000.
(expand_start_all_catch): Add assemble_external calls for various
routines we call.
(expand_leftover_cleanups): Ditto.
(expand_start_catch_block): Ditto.
(do_unwind): Ditto.
(expand_builtin_throw): Ditto.
Wed Jan 11 01:05:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (pushtag): Only look for a previous decl in the current
binding level. Use explicit global scope in DECL_NESTED_TYPENAME.
* gxx.gperf: Add __signature__ and __sigof__ keywords.
* decl2.c (lang_decode_option): -ansi does not set flag_no_asm. It
does set flag_no_gnu_keywords and flag_operator_names.
* lex.c (init_lex): 'overload' is not a keyword unless -traditional.
Unset extension keywords if -fno-gnu-keywords.
Allow operator names ('bitand') if -foperator-names.
Never unset 'asm'; -fno-asm only affects 'typeof'.
* decl.c (lookup_name_real): The got_object special lookup only
applies to types.
Tue Jan 10 18:07:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* spew.c (yylex): Also use DECL_NESTED_TYPENAME if got_object is set.
* parse.y (primary): Unset got_object after all rules that use the
'object' nonterminal.
(object): Set got_object.
* lex.h: Declare got_object.
* decl.c (lookup_name_real): Also lookup names in the context of an
object specified.
Tue Jan 10 14:30:30 1995 Mike Stump <mrs@cygnus.com>
* typeck.c (get_member_function_from_ptrfunc): Use ptrdiff_type_node
for things that have to be added to pointers, not size_type. Cures
problems with pointer to members on Alphas.
(build_binary_op_nodefault): Ditto.
(get_delta_difference_: Ditto.
(build_ptrmemfunc): Ditto.
Tue Jan 10 01:49:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (pushtag): Stick the new decl in TYPE_NAME before pushing
it.
* typeck.c (build_component_ref): Don't build up a COMPONENT_REF
when dealing with overloaded member functions; just act like
build_offset_ref.
(commonparms): Remove misleading comment.
* decl.c (duplicate_decls): Complain about repeated default
arguments here.
(redeclaration_error_message): Instead of here.
(pushdecl): Complain about missing default arguments here.
(grokparms): Instead of here.
(lookup_name_current_level): Also match on DECL_ASSEMBLER_NAME.
(grok_reference_init): Do not complain about missing initializer if
declared 'extern'.
* search.c (lookup_field): Don't return a TYPE_DECL if there is a
function alternative and want_type is not set.
Mon Jan 9 18:16:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (pushtag): Don't set TYPE_NAME to an identifier. Do push
the decl when the type has no TYPE_NAME.
(lookup_nested_type): Don't assume that type has TYPE_NAME set.
(lookup_name_real): Call lookup_field with want_type =
prefer_type.
* search.c (lookup_field): Handle want_type properly in the presence
of fields with the same name.
* decl.c (set_nested_typename): Set nested name for file-scope types
to include leading ::.
(pushdecl): Set the nested typename if the decl doesn't have one,
rather than if the type's canonical decl doesn't have one.
Mon Jan 9 16:48:16 1995 Steve Chamberlain (sac@jonny.cygnus.com)
* typeck.c (pointer_int_sum): Use offset size when calculating
index expression.
Mon Jan 9 03:44:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (convert_for_assignment): Complain about contravariance
violation here.
(comp_target_types): Instead of here.
(build_unary_op): resolve_offset_ref before checking for a valid
type.
* spew.c (yylex): Decrement looking_for_typename after we see a
_DEFN.
* decl.c (pushdecl): Don't install an artificial TYPE_DECL in
IDENTIFIER_LOCAL_VALUE if we already have a decl with that name.
* typeck.c (convert_for_assignment): Converting pointers to bool
does not need a cast.
Sun Jan 8 18:16:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* class.c (instantiate_type): Initialize nsubsts parm.
* pt.c (do_function_instantiation): Ditto.
Sat Jan 7 14:37:05 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* pt.c (tsubst): Use TREE_STATIC instead of DECL_INLINE &&
DECL_SAVED_INSNS to determine whether or not we've seen a definition
of this function.
(instantiate_template): Ditto.
* call.c (convert_harshness): Allow const reference binding when
called from the overloading code, but not when called from
can_convert (since it isn't a conversion).
(convert_harshness): Put back some disabled code.
Fri Jan 6 14:10:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* call.c (convert_harshness): There is no implicit conversion from
void* to other pointer types (unless the parameter is (void*)0).
(convert_harshness): Non-lvalues do not convert to reference types.
* class.c (finish_struct_methods): Still set
TYPE_HAS_{INT,REAL}_CONVERSION.
* call.c (can_convert): Don't use aggregate initialization.
* cp-tree.h: Declare lookup_conversions.
Thu Jan 5 21:08:00 1995 Mike Stump <mrs@cygnus.com>
* parse.y (simple_stmt): Fix duplicate case value error messages to
be more readable.
Wed Jan 4 16:44:19 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* cvt.c (build_type_conversion): Total rewrite to use
convert_harshness instead of reproducing conversion logic here. Now
much shorter.
* call.c (convert_harshness): Support conversions to bool.
(can_convert): Checks whether a conversion is less harsh
than USER_CODE, for build_type_conversion.
* search.c (add_conversions): Function for passing to dfs_walk which
adds all the type conversion operators in the current type to a list.
(lookup_conversions): Calls dfs_walk with add_conversions and return
the list.
(dfs_walk): Don't require a qfn.
* cp-tree.h: Lose CLASSTYPE_CONVERSIONS hackery.
(CLASSTYPE_FIRST_CONVERSION): Points to elt 1 of CLASSTYPE_METHOD_VEC.
* class.c (finish_struct_bits): Lose CLASSTYPE_CONVERSIONS hackery.
(grow_method): A separate function for building onto the growing
method vector.
(finish_struct_methods): Use it. Put all type conversion operators
right after the constructors. Perhaps we should sort the methods
alphabetically?
Mon Jan 2 14:42:58 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* call.c (build_method_call): Lose another misleading shortcut.
Fri Dec 30 17:57:30 1994 Mike Stump <mrs@cygnus.com>
* gc.c (build_bltn_desc): Handle bool as a built-in type.
Fri Dec 30 14:20:21 1994 Mike Stump <mrs@cygnus.com>
* tree.c (layout_vbasetypes): Ensure that we don't loose alignment
on the complete type because of small virtual bases.
Fri Dec 30 12:22:29 1994 Mike Stump <mrs@cygnus.com>
Fri Dec 30 12:22:29 1994 Mike Stump <mrs@cygnus.com>
...
...
gcc/cp/call.c
View file @
e1cd6e56
...
@@ -47,6 +47,7 @@ extern tree unary_complex_lvalue ();
...
@@ -47,6 +47,7 @@ extern tree unary_complex_lvalue ();
static
struct
harshness_code
convert_harshness
();
static
struct
harshness_code
convert_harshness
();
#define EVIL_RETURN(ARG) ((ARG).code = EVIL_CODE, (ARG))
#define EVIL_RETURN(ARG) ((ARG).code = EVIL_CODE, (ARG))
#define STD_RETURN(ARG) ((ARG).code = STD_CODE, (ARG))
#define QUAL_RETURN(ARG) ((ARG).code = QUAL_CODE, (ARG))
#define QUAL_RETURN(ARG) ((ARG).code = QUAL_CODE, (ARG))
#define TRIVIAL_RETURN(ARG) ((ARG).code = TRIVIAL_CODE, (ARG))
#define TRIVIAL_RETURN(ARG) ((ARG).code = TRIVIAL_CODE, (ARG))
#define ZERO_RETURN(ARG) ((ARG).code = 0, (ARG))
#define ZERO_RETURN(ARG) ((ARG).code = 0, (ARG))
...
@@ -117,6 +118,7 @@ convert_harshness (type, parmtype, parm)
...
@@ -117,6 +118,7 @@ convert_harshness (type, parmtype, parm)
struct
harshness_code
h
;
struct
harshness_code
h
;
register
enum
tree_code
codel
;
register
enum
tree_code
codel
;
register
enum
tree_code
coder
;
register
enum
tree_code
coder
;
int
lvalue
;
h
.
code
=
0
;
h
.
code
=
0
;
h
.
distance
=
0
;
h
.
distance
=
0
;
...
@@ -136,7 +138,12 @@ convert_harshness (type, parmtype, parm)
...
@@ -136,7 +138,12 @@ convert_harshness (type, parmtype, parm)
if
(
parm
)
if
(
parm
)
parm
=
convert_from_reference
(
parm
);
parm
=
convert_from_reference
(
parm
);
parmtype
=
TREE_TYPE
(
parmtype
);
parmtype
=
TREE_TYPE
(
parmtype
);
lvalue
=
1
;
}
}
else
if
(
parm
)
lvalue
=
lvalue_p
(
parm
);
else
lvalue
=
0
;
codel
=
TREE_CODE
(
type
);
codel
=
TREE_CODE
(
type
);
coder
=
TREE_CODE
(
parmtype
);
coder
=
TREE_CODE
(
parmtype
);
...
@@ -300,6 +307,14 @@ convert_harshness (type, parmtype, parm)
...
@@ -300,6 +307,14 @@ convert_harshness (type, parmtype, parm)
if
(
coder
==
VOID_TYPE
)
if
(
coder
==
VOID_TYPE
)
return
EVIL_RETURN
(
h
);
return
EVIL_RETURN
(
h
);
if
(
codel
==
BOOLEAN_TYPE
)
{
if
(
INTEGRAL_CODE_P
(
coder
)
||
coder
==
REAL_TYPE
||
coder
==
POINTER_TYPE
||
coder
==
OFFSET_TYPE
)
return
STD_RETURN
(
h
);
return
EVIL_RETURN
(
h
);
}
if
(
INTEGRAL_CODE_P
(
codel
))
if
(
INTEGRAL_CODE_P
(
codel
))
{
{
/* Control equivalence of ints an enums. */
/* Control equivalence of ints an enums. */
...
@@ -375,11 +390,10 @@ convert_harshness (type, parmtype, parm)
...
@@ -375,11 +390,10 @@ convert_harshness (type, parmtype, parm)
register
tree
ttr
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
parmtype
));
register
tree
ttr
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
parmtype
));
int
penalty
=
4
*
(
ttl
!=
ttr
);
int
penalty
=
4
*
(
ttl
!=
ttr
);
/* Anything converts to void *. void * converts to anything.
/* Anything converts to void *. Since this may be `const void *'
Since these may be `const void *' (etc.) use VOID_TYPE
(etc.) use VOID_TYPE instead of void_type_node. Otherwise, the
instead of void_type_node. Otherwise, the targets must be the same,
targets must be the same, except that we do allow (at some cost)
except that we do allow (at some cost) conversion between signed and
conversion between signed and unsigned pointer types. */
unsigned pointer types. */
if
((
TREE_CODE
(
ttl
)
==
METHOD_TYPE
if
((
TREE_CODE
(
ttl
)
==
METHOD_TYPE
||
TREE_CODE
(
ttl
)
==
FUNCTION_TYPE
)
||
TREE_CODE
(
ttl
)
==
FUNCTION_TYPE
)
...
@@ -396,7 +410,8 @@ convert_harshness (type, parmtype, parm)
...
@@ -396,7 +410,8 @@ convert_harshness (type, parmtype, parm)
}
}
#if 1
#if 1
if
(
TREE_CODE
(
ttl
)
!=
VOID_TYPE
&&
TREE_CODE
(
ttr
)
!=
VOID_TYPE
)
if
(
TREE_CODE
(
ttl
)
!=
VOID_TYPE
&&
(
TREE_CODE
(
ttr
)
!=
VOID_TYPE
||
!
parm
||
!
integer_zerop
(
parm
)))
{
{
if
(
TREE_UNSIGNED
(
ttl
)
!=
TREE_UNSIGNED
(
ttr
))
if
(
TREE_UNSIGNED
(
ttl
)
!=
TREE_UNSIGNED
(
ttr
))
{
{
...
@@ -404,7 +419,7 @@ convert_harshness (type, parmtype, parm)
...
@@ -404,7 +419,7 @@ convert_harshness (type, parmtype, parm)
ttr
=
unsigned_type
(
ttr
);
ttr
=
unsigned_type
(
ttr
);
penalty
=
10
;
penalty
=
10
;
}
}
if
(
!
comp_target_types
(
ttl
,
ttr
,
0
)
)
if
(
comp_target_types
(
ttl
,
ttr
,
0
)
<=
0
)
return
EVIL_RETURN
(
h
);
return
EVIL_RETURN
(
h
);
}
}
#else
#else
...
@@ -414,7 +429,7 @@ convert_harshness (type, parmtype, parm)
...
@@ -414,7 +429,7 @@ convert_harshness (type, parmtype, parm)
&&
(
ttl
=
unsigned_type
(
ttl
),
&&
(
ttl
=
unsigned_type
(
ttl
),
ttr
=
unsigned_type
(
ttr
),
ttr
=
unsigned_type
(
ttr
),
penalty
=
10
,
0
))
penalty
=
10
,
0
))
||
(
comp_target_types
(
ttl
,
ttr
,
0
))))
||
(
comp_target_types
(
ttl
,
ttr
,
0
)
>
0
)))
return
EVIL_RETURN
(
h
);
return
EVIL_RETURN
(
h
);
#endif
#endif
...
@@ -503,14 +518,21 @@ convert_harshness (type, parmtype, parm)
...
@@ -503,14 +518,21 @@ convert_harshness (type, parmtype, parm)
ttl
=
TREE_TYPE
(
type
);
ttl
=
TREE_TYPE
(
type
);
/* When passing a non-const argument into a const reference (or vice
/* Only allow const reference binding if we were given a parm to deal
versa), dig it a little, so a non-const reference is preferred
with, since it isn't really a conversion. This is a hack to
over this one. (mrs) */
prevent build_type_conversion from finding this conversion, but
if
(
TYPE_READONLY
(
ttl
)
!=
constp
still allow overloading to find it. */
||
TYPE_VOLATILE
(
ttl
)
!=
volatilep
)
if
(
!
lvalue
&&
!
(
parm
&&
TYPE_READONLY
(
ttl
)))
penalty
=
2
;
return
EVIL_RETURN
(
h
);
else
penalty
=
0
;
if
(
TYPE_READONLY
(
ttl
)
<
constp
||
TYPE_VOLATILE
(
ttl
)
<
volatilep
)
return
EVIL_RETURN
(
h
);
/* When passing a non-const argument into a const reference, dig it a
little, so a non-const reference is preferred over this one. */
penalty
=
((
TYPE_READONLY
(
ttl
)
>
constp
)
+
(
TYPE_VOLATILE
(
ttl
)
>
volatilep
));
ttl
=
TYPE_MAIN_VARIANT
(
ttl
);
ttl
=
TYPE_MAIN_VARIANT
(
ttl
);
...
@@ -520,98 +542,17 @@ convert_harshness (type, parmtype, parm)
...
@@ -520,98 +542,17 @@ convert_harshness (type, parmtype, parm)
form
=
TREE_CODE
(
intype
);
form
=
TREE_CODE
(
intype
);
}
}
if
(
ttl
==
intype
&&
penalty
==
0
)
return
ZERO_RETURN
(
h
);
else
penalty
=
2
;
ttr
=
intype
;
ttr
=
intype
;
/* If the initializer is not an lvalue, then it does not
/* Maybe handle conversion to base here? */
matter if we make life easier for the programmer
by creating a temporary variable with which to
hold the result. */
if
(
parm
&&
(
INTEGRAL_CODE_P
(
coder
)
||
coder
==
REAL_TYPE
)
&&
!
lvalue_p
(
parm
))
{
h
=
convert_harshness
(
ttl
,
ttr
,
NULL_TREE
);
if
(
penalty
>
2
||
h
.
code
!=
0
)
h
.
code
|=
STD_CODE
;
else
h
.
code
|=
TRIVIAL_CODE
;
h
.
distance
=
0
;
return
h
;
}
if
(
TREE_UNSIGNED
(
ttl
)
^
TREE_UNSIGNED
(
intype
))
{
ttl
=
unsigned_type
(
ttl
);
ttr
=
intype
=
unsigned_type
(
intype
);
penalty
+=
2
;
}
if
(
ttl
==
ttr
)
{
if
(
penalty
>
2
)
{
h
.
code
=
STD_CODE
;
h
.
distance
=
0
;
}
else
{
h
.
code
=
TRIVIAL_CODE
;
/* We set this here so that build_overload_call_real will be
able to see the penalty we found, rather than just looking
at a TRIVIAL_CODE with no other information. */
h
.
int_penalty
=
penalty
;
}
return
h
;
}
/* Pointers to voids always convert for pointers. But
h
=
convert_harshness
(
ttl
,
ttr
,
NULL_TREE
);
make them less natural than more specific matches. */
if
(
penalty
&&
h
.
code
==
0
)
if
(
TREE_CODE
(
ttl
)
==
POINTER_TYPE
&&
TREE_CODE
(
ttr
)
==
POINTER_TYPE
)
{
{
if
(
TREE_TYPE
(
ttl
)
==
void_type_node
h
.
code
=
QUAL_CODE
;
||
TREE_TYPE
(
ttr
)
==
void_type_node
)
h
.
int_penalty
=
penalty
;
{
h
.
code
=
STD_CODE
;
h
.
distance
=
0
;
return
h
;
}
}
/* Here it does matter. If this conversion is from derived to base,
allow it. Otherwise, types must be compatible in the strong sense. */
if
(
TREE_CODE
(
ttl
)
==
RECORD_TYPE
&&
TREE_CODE
(
ttr
)
==
RECORD_TYPE
)
{
int
b_or_d
=
get_base_distance
(
ttl
,
ttr
,
0
,
0
);
if
(
b_or_d
<
0
)
{
b_or_d
=
get_base_distance
(
ttr
,
ttl
,
0
,
0
);
if
(
b_or_d
<
0
)
return
EVIL_RETURN
(
h
);
h
.
distance
=
-
b_or_d
;
}
/* Say that this conversion is relatively painless.
If it turns out that there is a user-defined X(X&)
constructor, then that will be invoked, but that's
preferable to dealing with other user-defined conversions
that may produce surprising results. */
else
h
.
distance
=
b_or_d
;
h
.
code
=
STD_CODE
;
return
h
;
}
if
(
comp_target_types
(
ttl
,
intype
,
1
))
{
if
(
penalty
)
h
.
code
=
STD_CODE
;
h
.
distance
=
0
;
return
h
;
}
}
return
h
;
}
}
if
(
codel
==
RECORD_TYPE
&&
coder
==
RECORD_TYPE
)
if
(
codel
==
RECORD_TYPE
&&
coder
==
RECORD_TYPE
)
{
{
...
@@ -631,6 +572,15 @@ convert_harshness (type, parmtype, parm)
...
@@ -631,6 +572,15 @@ convert_harshness (type, parmtype, parm)
return
EVIL_RETURN
(
h
);
return
EVIL_RETURN
(
h
);
}
}
int
can_convert
(
to
,
from
)
tree
to
,
from
;
{
struct
harshness_code
h
;
h
=
convert_harshness
(
to
,
from
,
NULL_TREE
);
return
h
.
code
<
USER_CODE
;
}
#ifdef DEBUG_MATCHING
#ifdef DEBUG_MATCHING
static
char
*
static
char
*
print_harshness
(
h
)
print_harshness
(
h
)
...
@@ -2134,6 +2084,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
...
@@ -2134,6 +2084,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype_path
=
TREE_VALUE
(
basetype_path
);
basetype_path
=
TREE_VALUE
(
basetype_path
);
basetype
=
BINFO_TYPE
(
basetype_path
);
basetype
=
BINFO_TYPE
(
basetype_path
);
#if 0
/* Cast the instance variable if necessary. */
/* Cast the instance variable if necessary. */
if (basetype != TYPE_MAIN_VARIANT
if (basetype != TYPE_MAIN_VARIANT
(TREE_TYPE (TREE_TYPE (TREE_VALUE (parms)))))
(TREE_TYPE (TREE_TYPE (TREE_VALUE (parms)))))
...
@@ -2152,6 +2103,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
...
@@ -2152,6 +2103,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
the access-control rewrite will make this change more cleanly. */
the access-control rewrite will make this change more cleanly. */
if (TREE_VALUE (parms) == error_mark_node)
if (TREE_VALUE (parms) == error_mark_node)
return error_mark_node;
return error_mark_node;
#endif
if
(
DESTRUCTOR_NAME_P
(
DECL_ASSEMBLER_NAME
(
function
)))
if
(
DESTRUCTOR_NAME_P
(
DECL_ASSEMBLER_NAME
(
function
)))
function
=
DECL_CHAIN
(
function
);
function
=
DECL_CHAIN
(
function
);
...
@@ -2208,19 +2160,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
...
@@ -2208,19 +2160,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
&&
(
cp
->
h
.
code
&
USER_CODE
))
&&
(
cp
->
h
.
code
&
USER_CODE
))
continue
;
continue
;
/* If we used default parameters, we must
check to see whether anyone else might
use them also, and report a possible
ambiguity. */
if
(
!
TYPE_USES_MULTIPLE_INHERITANCE
(
save_basetype
)
&&
cp
->
harshness
[
len
].
distance
==
0
&&
cp
->
h
.
code
<
best
)
{
if
(
!
DECL_STATIC_FUNCTION_P
(
function
))
TREE_VALUE
(
parms
)
=
cp
->
arg
;
if
(
best
==
1
)
goto
found_and_maybe_warn
;
}
cp
++
;
cp
++
;
}
}
}
}
...
...
gcc/cp/class.c
View file @
e1cd6e56
...
@@ -1687,63 +1687,6 @@ finish_struct_bits (t, max_has_virtual)
...
@@ -1687,63 +1687,6 @@ finish_struct_bits (t, max_has_virtual)
}
}
}
}
/* Need to test METHOD_VEC here in case all methods
(conversions and otherwise) are inherited. */
if
(
TYPE_HAS_CONVERSION
(
t
)
&&
method_vec
!=
NULL_TREE
)
{
tree
first_conversions
[
last_conversion_type
];
tree
last_conversions
[
last_conversion_type
];
enum
conversion_type
conv_index
;
tree
*
tmp
;
int
i
;
bzero
((
char
*
)
first_conversions
,
sizeof
(
first_conversions
));
bzero
((
char
*
)
last_conversions
,
sizeof
(
last_conversions
));
for
(
tmp
=
&
TREE_VEC_ELT
(
method_vec
,
1
);
tmp
!=
TREE_VEC_END
(
method_vec
);
tmp
+=
1
)
{
/* ??? This should compare DECL_NAME (*tmp) == ansi_opname[TYPE_EXPR]. */
if
(
IDENTIFIER_TYPENAME_P
(
DECL_ASSEMBLER_NAME
(
*
tmp
)))
{
tree
fntype
=
TREE_TYPE
(
*
tmp
);
tree
return_type
=
TREE_TYPE
(
fntype
);
my_friendly_assert
(
TREE_CODE
(
fntype
)
==
METHOD_TYPE
,
171
);
if
(
typecode_p
(
return_type
,
POINTER_TYPE
))
{
if
(
TYPE_READONLY
(
TREE_TYPE
(
return_type
)))
conv_index
=
constptr_conv
;
else
conv_index
=
ptr_conv
;
}
else
if
(
typecode_p
(
return_type
,
INTEGER_TYPE
)
||
typecode_p
(
return_type
,
BOOLEAN_TYPE
)
||
typecode_p
(
return_type
,
ENUMERAL_TYPE
))
{
TYPE_HAS_INT_CONVERSION
(
t
)
=
1
;
conv_index
=
int_conv
;
}
else
if
(
typecode_p
(
return_type
,
REAL_TYPE
))
{
TYPE_HAS_REAL_CONVERSION
(
t
)
=
1
;
conv_index
=
real_conv
;
}
else
continue
;
if
(
first_conversions
[(
int
)
conv_index
]
==
NULL_TREE
)
first_conversions
[(
int
)
conv_index
]
=
*
tmp
;
last_conversions
[(
int
)
conv_index
]
=
*
tmp
;
}
}
for
(
i
=
0
;
i
<
(
int
)
last_conversion_type
;
i
++
)
if
(
first_conversions
[
i
]
!=
last_conversions
[
i
])
CLASSTYPE_CONVERSION
(
t
,
i
)
=
error_mark_node
;
else
CLASSTYPE_CONVERSION
(
t
,
i
)
=
first_conversions
[
i
];
}
/* If this type has constructors, force its mode to be BLKmode,
/* If this type has constructors, force its mode to be BLKmode,
and force its TREE_ADDRESSABLE bit to be nonzero. */
and force its TREE_ADDRESSABLE bit to be nonzero. */
if
(
TYPE_NEEDS_CONSTRUCTING
(
t
)
||
TYPE_NEEDS_DESTRUCTOR
(
t
))
if
(
TYPE_NEEDS_CONSTRUCTING
(
t
)
||
TYPE_NEEDS_DESTRUCTOR
(
t
))
...
@@ -1761,6 +1704,57 @@ finish_struct_bits (t, max_has_virtual)
...
@@ -1761,6 +1704,57 @@ finish_struct_bits (t, max_has_virtual)
}
}
}
}
/* Add FN to the method_vec growing on the class_obstack. Used by
finish_struct_methods. */
static
void
grow_method
(
fn
)
tree
fn
;
{
tree
method_vec
=
(
tree
)
obstack_base
(
&
class_obstack
);
tree
*
testp
=
&
TREE_VEC_ELT
(
method_vec
,
0
);
if
(
*
testp
==
NULL_TREE
)
testp
++
;
while
(((
HOST_WIDE_INT
)
testp
<
(
HOST_WIDE_INT
)
obstack_next_free
(
&
class_obstack
))
&&
DECL_NAME
(
*
testp
)
!=
DECL_NAME
(
fn
))
testp
++
;
if
((
HOST_WIDE_INT
)
testp
<
(
HOST_WIDE_INT
)
obstack_next_free
(
&
class_obstack
))
{
tree
x
,
prev_x
;
for
(
x
=
*
testp
;
x
;
x
=
DECL_CHAIN
(
x
))
{
if
(
DECL_NAME
(
fn
)
==
ansi_opname
[(
int
)
DELETE_EXPR
]
||
DECL_NAME
(
fn
)
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])
{
/* ANSI C++ June 5 1992 WP 12.5.5.1 */
cp_error_at
(
"`%D' overloaded"
,
fn
);
cp_error_at
(
"previous declaration as `%D' here"
,
x
);
}
if
(
DECL_ASSEMBLER_NAME
(
fn
)
==
DECL_ASSEMBLER_NAME
(
x
))
{
/* We complain about multiple destructors on sight,
so we do not repeat the warning here. Friend-friend
ambiguities are warned about outside this loop. */
if
(
!
DESTRUCTOR_NAME_P
(
DECL_ASSEMBLER_NAME
(
fn
)))
cp_error_at
(
"ambiguous method `%#D' in structure"
,
fn
);
break
;
}
prev_x
=
x
;
}
if
(
x
==
0
)
{
if
(
*
testp
)
DECL_CHAIN
(
prev_x
)
=
fn
;
else
*
testp
=
fn
;
}
}
else
obstack_ptr_grow
(
&
class_obstack
,
fn
);
}
/* Warn about duplicate methods in fn_fields. Also compact method
/* Warn about duplicate methods in fn_fields. Also compact method
lists so that lookup can be made faster.
lists so that lookup can be made faster.
...
@@ -1769,10 +1763,12 @@ finish_struct_bits (t, max_has_virtual)
...
@@ -1769,10 +1763,12 @@ finish_struct_bits (t, max_has_virtual)
Data Structure: List of method lists. The outer list is a
Data Structure: List of method lists. The outer list is a
TREE_LIST, whose TREE_PURPOSE field is the field name and the
TREE_LIST, whose TREE_PURPOSE field is the field name and the
TREE_VALUE is the TREE_CHAIN of the FUNCTION_DECLs. Friends are
TREE_VALUE is the DECL_CHAIN of the FUNCTION_DECLs. TREE_CHAIN
chained in the same way as member functions, but they live in the
links the entire list of methods for TYPE_METHODS. Friends are
TREE_TYPE field of the outer list. That allows them to be quickly
chained in the same way as member functions (? TREE_CHAIN or
deleted, and requires no extra storage.
DECL_CHAIN), but they live in the TREE_TYPE field of the outer
list. That allows them to be quickly deleted, and requires no
extra storage.
If there are any constructors/destructors, they are moved to the
If there are any constructors/destructors, they are moved to the
front of the list. This makes pushclass more efficient.
front of the list. This makes pushclass more efficient.
...
@@ -1789,6 +1785,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
...
@@ -1789,6 +1785,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
int
nonprivate_method
;
int
nonprivate_method
;
{
{
tree
method_vec
;
tree
method_vec
;
tree
save_fn_fields
=
tree_cons
(
NULL_TREE
,
NULL_TREE
,
fn_fields
);
tree
lastp
;
tree
name
=
constructor_name
(
t
);
tree
name
=
constructor_name
(
t
);
int
i
,
n_baseclasses
=
CLASSTYPE_N_BASECLASSES
(
t
);
int
i
,
n_baseclasses
=
CLASSTYPE_N_BASECLASSES
(
t
);
...
@@ -1802,17 +1800,15 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
...
@@ -1802,17 +1800,15 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
obstack_free
(
&
class_obstack
,
method_vec
);
obstack_free
(
&
class_obstack
,
method_vec
);
obstack_blank
(
&
class_obstack
,
sizeof
(
struct
tree_vec
));
obstack_blank
(
&
class_obstack
,
sizeof
(
struct
tree_vec
));
while
(
fn_fields
)
/* First fill in entry 0 with the constructors, and the next few with
type conversion operators (if any). */
for
(
lastp
=
save_fn_fields
;
fn_fields
;
fn_fields
=
TREE_CHAIN
(
lastp
))
{
{
/* NEXT Pointer, TEST Pointer, and BASE Pointer. */
tree
nextp
,
*
testp
;
tree
fn_name
=
DECL_NAME
(
fn_fields
);
tree
fn_name
=
DECL_NAME
(
fn_fields
);
if
(
fn_name
==
NULL_TREE
)
if
(
fn_name
==
NULL_TREE
)
fn_name
=
name
;
fn_name
=
name
;
nextp
=
TREE_CHAIN
(
fn_fields
);
TREE_CHAIN
(
fn_fields
)
=
NULL_TREE
;
/* Clear out this flag.
/* Clear out this flag.
@@ Doug may figure out how to break
@@ Doug may figure out how to break
...
@@ -1840,8 +1836,45 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
...
@@ -1840,8 +1836,45 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
TYPE_HAS_NONPUBLIC_CTOR
(
t
)
=
2
;
TYPE_HAS_NONPUBLIC_CTOR
(
t
)
=
2
;
}
}
}
}
/* Constructors are handled easily in search routines. */
DECL_CHAIN
(
fn_fields
)
=
TREE_VEC_ELT
(
method_vec
,
0
);
TREE_VEC_ELT
(
method_vec
,
0
)
=
fn_fields
;
}
}
else
if
(
fn_name
==
ansi_opname
[(
int
)
MODIFY_EXPR
])
else
if
(
IDENTIFIER_TYPENAME_P
(
fn_name
))
{
tree
return_type
=
TREE_TYPE
(
TREE_TYPE
(
fn_fields
));
if
(
typecode_p
(
return_type
,
INTEGER_TYPE
)
||
typecode_p
(
return_type
,
BOOLEAN_TYPE
)
||
typecode_p
(
return_type
,
ENUMERAL_TYPE
))
TYPE_HAS_INT_CONVERSION
(
t
)
=
1
;
else
if
(
typecode_p
(
return_type
,
REAL_TYPE
))
TYPE_HAS_REAL_CONVERSION
(
t
)
=
1
;
grow_method
(
fn_fields
);
}
else
{
lastp
=
fn_fields
;
continue
;
}
TREE_CHAIN
(
lastp
)
=
TREE_CHAIN
(
fn_fields
);
TREE_CHAIN
(
fn_fields
)
=
NULL_TREE
;
}
fn_fields
=
TREE_CHAIN
(
save_fn_fields
);
while
(
fn_fields
)
{
tree
nextp
;
tree
fn_name
=
DECL_NAME
(
fn_fields
);
if
(
fn_name
==
NULL_TREE
)
fn_name
=
name
;
nextp
=
TREE_CHAIN
(
fn_fields
);
TREE_CHAIN
(
fn_fields
)
=
NULL_TREE
;
if
(
fn_name
==
ansi_opname
[(
int
)
MODIFY_EXPR
])
{
{
tree
parmtype
=
TREE_VALUE
(
FUNCTION_ARG_CHAIN
(
fn_fields
));
tree
parmtype
=
TREE_VALUE
(
FUNCTION_ARG_CHAIN
(
fn_fields
));
...
@@ -1854,65 +1887,12 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
...
@@ -1854,65 +1887,12 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
}
}
}
}
/* Constructors are handled easily in search routines. */
grow_method
(
fn_fields
);
if
(
fn_name
==
name
)
{
DECL_CHAIN
(
fn_fields
)
=
TREE_VEC_ELT
(
method_vec
,
0
);
TREE_VEC_ELT
(
method_vec
,
0
)
=
fn_fields
;
}
else
{
testp
=
&
TREE_VEC_ELT
(
method_vec
,
0
);
if
(
*
testp
==
NULL_TREE
)
testp
++
;
while
(((
HOST_WIDE_INT
)
testp
<
(
HOST_WIDE_INT
)
obstack_next_free
(
&
class_obstack
))
&&
DECL_NAME
(
*
testp
)
!=
fn_name
)
testp
++
;
if
((
HOST_WIDE_INT
)
testp
<
(
HOST_WIDE_INT
)
obstack_next_free
(
&
class_obstack
))
{
tree
x
,
prev_x
;
for
(
x
=
*
testp
;
x
;
x
=
DECL_CHAIN
(
x
))
{
if
(
DECL_NAME
(
fn_fields
)
==
ansi_opname
[(
int
)
DELETE_EXPR
]
||
DECL_NAME
(
fn_fields
)
==
ansi_opname
[(
int
)
VEC_DELETE_EXPR
])
{
/* ANSI C++ June 5 1992 WP 12.5.5.1 */
cp_error_at
(
"`%D' overloaded"
,
fn_fields
);
cp_error_at
(
"previous declaration as `%D' here"
,
x
);
}
if
(
DECL_ASSEMBLER_NAME
(
fn_fields
)
==
DECL_ASSEMBLER_NAME
(
x
))
{
/* We complain about multiple destructors on sight,
so we do not repeat the warning here. Friend-friend
ambiguities are warned about outside this loop. */
if
(
!
DESTRUCTOR_NAME_P
(
DECL_ASSEMBLER_NAME
(
fn_fields
)))
cp_error_at
(
"ambiguous method `%#D' in structure"
,
fn_fields
);
break
;
}
prev_x
=
x
;
}
if
(
x
==
0
)
{
if
(
*
testp
)
DECL_CHAIN
(
prev_x
)
=
fn_fields
;
else
*
testp
=
fn_fields
;
}
}
else
{
obstack_ptr_grow
(
&
class_obstack
,
fn_fields
);
method_vec
=
(
tree
)
obstack_base
(
&
class_obstack
);
}
}
fn_fields
=
nextp
;
fn_fields
=
nextp
;
}
}
/* Update in case method_vec has moved. */
method_vec
=
(
tree
)
obstack_base
(
&
class_obstack
);
TREE_VEC_LENGTH
(
method_vec
)
=
(
tree
*
)
obstack_next_free
(
&
class_obstack
)
TREE_VEC_LENGTH
(
method_vec
)
=
(
tree
*
)
obstack_next_free
(
&
class_obstack
)
-
(
&
TREE_VEC_ELT
(
method_vec
,
0
));
-
(
&
TREE_VEC_ELT
(
method_vec
,
0
));
obstack_finish
(
&
class_obstack
);
obstack_finish
(
&
class_obstack
);
...
@@ -4737,7 +4717,7 @@ instantiate_type (lhstype, rhs, complain)
...
@@ -4737,7 +4717,7 @@ instantiate_type (lhstype, rhs, complain)
/* First look for an exact match */
/* First look for an exact match */
while
(
field
&&
TREE_TYPE
(
field
)
!=
lhstype
)
while
(
field
&&
TREE_TYPE
(
field
)
!=
lhstype
)
field
=
TREE
_CHAIN
(
field
);
field
=
DECL
_CHAIN
(
field
);
if
(
field
)
if
(
field
)
{
{
TREE_OPERAND
(
rhs
,
1
)
=
field
;
TREE_OPERAND
(
rhs
,
1
)
=
field
;
...
@@ -4747,13 +4727,13 @@ instantiate_type (lhstype, rhs, complain)
...
@@ -4747,13 +4727,13 @@ instantiate_type (lhstype, rhs, complain)
/* No exact match found, look for a compatible function. */
/* No exact match found, look for a compatible function. */
field
=
TREE_OPERAND
(
rhs
,
1
);
field
=
TREE_OPERAND
(
rhs
,
1
);
while
(
field
&&
!
comptypes
(
lhstype
,
TREE_TYPE
(
field
),
0
))
while
(
field
&&
!
comptypes
(
lhstype
,
TREE_TYPE
(
field
),
0
))
field
=
TREE
_CHAIN
(
field
);
field
=
DECL
_CHAIN
(
field
);
if
(
field
)
if
(
field
)
{
{
TREE_OPERAND
(
rhs
,
1
)
=
field
;
TREE_OPERAND
(
rhs
,
1
)
=
field
;
field
=
TREE
_CHAIN
(
field
);
field
=
DECL
_CHAIN
(
field
);
while
(
field
&&
!
comptypes
(
lhstype
,
TREE_TYPE
(
field
),
0
))
while
(
field
&&
!
comptypes
(
lhstype
,
TREE_TYPE
(
field
),
0
))
field
=
TREE
_CHAIN
(
field
);
field
=
DECL
_CHAIN
(
field
);
if
(
field
)
if
(
field
)
{
{
if
(
complain
)
if
(
complain
)
...
@@ -4821,7 +4801,7 @@ instantiate_type (lhstype, rhs, complain)
...
@@ -4821,7 +4801,7 @@ instantiate_type (lhstype, rhs, complain)
{
{
int
n
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
elem
));
int
n
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
elem
));
tree
*
t
=
(
tree
*
)
alloca
(
sizeof
(
tree
)
*
n
);
tree
*
t
=
(
tree
*
)
alloca
(
sizeof
(
tree
)
*
n
);
int
i
,
d
;
int
i
,
d
=
0
;
i
=
type_unification
(
DECL_TEMPLATE_PARMS
(
elem
),
t
,
i
=
type_unification
(
DECL_TEMPLATE_PARMS
(
elem
),
t
,
TYPE_ARG_TYPES
(
TREE_TYPE
(
elem
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
elem
)),
TYPE_ARG_TYPES
(
lhstype
),
&
d
,
0
);
TYPE_ARG_TYPES
(
lhstype
),
&
d
,
0
);
...
@@ -4845,14 +4825,15 @@ instantiate_type (lhstype, rhs, complain)
...
@@ -4845,14 +4825,15 @@ instantiate_type (lhstype, rhs, complain)
/* No match found, look for a compatible function. */
/* No match found, look for a compatible function. */
elem
=
get_first_fn
(
rhs
);
elem
=
get_first_fn
(
rhs
);
while
(
elem
&&
!
comp_target_types
(
lhstype
,
TREE_TYPE
(
elem
),
1
))
while
(
elem
&&
comp_target_types
(
lhstype
,
TREE_TYPE
(
elem
),
1
)
<=
0
)
elem
=
DECL_CHAIN
(
elem
);
elem
=
DECL_CHAIN
(
elem
);
if
(
elem
)
if
(
elem
)
{
{
tree
save_elem
=
elem
;
tree
save_elem
=
elem
;
elem
=
DECL_CHAIN
(
elem
);
elem
=
DECL_CHAIN
(
elem
);
while
(
elem
&&
!
comp_target_types
(
lhstype
,
TREE_TYPE
(
elem
)
,
while
(
elem
&&
comp_target_types
(
lhstype
,
0
)
)
TREE_TYPE
(
elem
),
0
)
<=
0
)
elem
=
DECL_CHAIN
(
elem
);
elem
=
DECL_CHAIN
(
elem
);
if
(
elem
)
if
(
elem
)
{
{
...
@@ -4900,7 +4881,7 @@ instantiate_type (lhstype, rhs, complain)
...
@@ -4900,7 +4881,7 @@ instantiate_type (lhstype, rhs, complain)
if
(
comptypes
(
lhstype
,
TREE_TYPE
(
elem
),
1
))
if
(
comptypes
(
lhstype
,
TREE_TYPE
(
elem
),
1
))
return
elem
;
return
elem
;
else
else
elem
=
TREE
_CHAIN
(
elem
);
elem
=
DECL
_CHAIN
(
elem
);
}
}
/* No exact match found, look for a compatible method. */
/* No exact match found, look for a compatible method. */
...
@@ -4908,14 +4889,16 @@ instantiate_type (lhstype, rhs, complain)
...
@@ -4908,14 +4889,16 @@ instantiate_type (lhstype, rhs, complain)
baselink
=
next_baselink
(
baselink
))
baselink
=
next_baselink
(
baselink
))
{
{
elem
=
TREE_VALUE
(
baselink
);
elem
=
TREE_VALUE
(
baselink
);
while
(
elem
&&
!
comp_target_types
(
lhstype
,
TREE_TYPE
(
elem
),
1
))
while
(
elem
&&
comp_target_types
(
lhstype
,
elem
=
TREE_CHAIN
(
elem
);
TREE_TYPE
(
elem
),
1
)
<=
0
)
elem
=
DECL_CHAIN
(
elem
);
if
(
elem
)
if
(
elem
)
{
{
tree
save_elem
=
elem
;
tree
save_elem
=
elem
;
elem
=
TREE_CHAIN
(
elem
);
elem
=
DECL_CHAIN
(
elem
);
while
(
elem
&&
!
comp_target_types
(
lhstype
,
TREE_TYPE
(
elem
),
0
))
while
(
elem
&&
comp_target_types
(
lhstype
,
elem
=
TREE_CHAIN
(
elem
);
TREE_TYPE
(
elem
),
0
)
<=
0
)
elem
=
DECL_CHAIN
(
elem
);
if
(
elem
)
if
(
elem
)
{
{
if
(
complain
)
if
(
complain
)
...
@@ -4940,7 +4923,7 @@ instantiate_type (lhstype, rhs, complain)
...
@@ -4940,7 +4923,7 @@ instantiate_type (lhstype, rhs, complain)
#endif
#endif
}
}
if
(
complain
)
if
(
complain
)
error
(
"no
static
member functions named `%s'"
,
error
(
"no
compatible
member functions named `%s'"
,
IDENTIFIER_POINTER
(
name
));
IDENTIFIER_POINTER
(
name
));
return
error_mark_node
;
return
error_mark_node
;
}
}
...
...
gcc/cp/cp-tree.h
View file @
e1cd6e56
...
@@ -114,6 +114,14 @@ extern int pedantic;
...
@@ -114,6 +114,14 @@ extern int pedantic;
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
#define C_TYPE_FIELDS_READONLY(type) TYPE_LANG_FLAG_0 (type)
#define C_TYPE_FIELDS_READONLY(type) TYPE_LANG_FLAG_0 (type)
/* Record in each node resulting from a binary operator
what operator was specified for it. */
#define C_EXP_ORIGINAL_CODE(exp) ((enum tree_code) TREE_COMPLEXITY (exp))
/* Store a value in that field. */
#define C_SET_EXP_ORIGINAL_CODE(exp, code) \
(TREE_COMPLEXITY (exp) = (int)(code))
/* If non-zero, a VAR_DECL whose cleanup will cause a throw to the
/* If non-zero, a VAR_DECL whose cleanup will cause a throw to the
next exception handler. */
next exception handler. */
...
@@ -271,7 +279,8 @@ extern int interface_only, interface_unknown;
...
@@ -271,7 +279,8 @@ extern int interface_only, interface_unknown;
extern
int
flag_elide_constructors
;
extern
int
flag_elide_constructors
;
/* Nonzero means handle things in ANSI, instead of GNU fashion. */
/* Nonzero means enable obscure ANSI features and disable GNU extensions
that might cause ANSI-compliant code to be miscompiled. */
extern
int
flag_ansi
;
extern
int
flag_ansi
;
...
@@ -369,9 +378,6 @@ enum languages { lang_c, lang_cplusplus };
...
@@ -369,9 +378,6 @@ enum languages { lang_c, lang_cplusplus };
#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0)
#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0)
#define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1)
#define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1)
enum
conversion_type
{
ptr_conv
,
constptr_conv
,
int_conv
,
real_conv
,
last_conversion_type
};
/* Statistics show that while the GNU C++ compiler may generate
/* Statistics show that while the GNU C++ compiler may generate
thousands of different types during a compilation run, it
thousands of different types during a compilation run, it
generates relatively few (tens) of classtypes. Because of this,
generates relatively few (tens) of classtypes. Because of this,
...
@@ -492,7 +498,6 @@ struct lang_type
...
@@ -492,7 +498,6 @@ struct lang_type
union
tree_node
*
friend_classes
;
union
tree_node
*
friend_classes
;
char
*
mi_matrix
;
char
*
mi_matrix
;
union
tree_node
*
conversions
[
last_conversion_type
];
union
tree_node
*
rtti
;
union
tree_node
*
rtti
;
...
@@ -657,6 +662,12 @@ struct lang_type
...
@@ -657,6 +662,12 @@ struct lang_type
/* List of lists of member functions defined in this class. */
/* List of lists of member functions defined in this class. */
#define CLASSTYPE_METHOD_VEC(NODE) TYPE_METHODS(NODE)
#define CLASSTYPE_METHOD_VEC(NODE) TYPE_METHODS(NODE)
/* The first type conversion operator in the class (the others can be
searched with TREE_CHAIN), or the first non-constructor function if
there are no type conversion operators. */
#define CLASSTYPE_FIRST_CONVERSION(NODE) \
TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 1)
/* Pointer from any member function to the head of the list of
/* Pointer from any member function to the head of the list of
member functions of the type that member function belongs to. */
member functions of the type that member function belongs to. */
#define CLASSTYPE_BASELINK_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->baselink_vec)
#define CLASSTYPE_BASELINK_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->baselink_vec)
...
@@ -807,12 +818,6 @@ struct lang_type
...
@@ -807,12 +818,6 @@ struct lang_type
a type is derived from another or not. */
a type is derived from another or not. */
#define CLASSTYPE_MI_MATRIX(NODE) (TYPE_LANG_SPECIFIC(NODE)->mi_matrix)
#define CLASSTYPE_MI_MATRIX(NODE) (TYPE_LANG_SPECIFIC(NODE)->mi_matrix)
/* If there is exactly one conversion to a non-void, non-const pointer type,
remember that here. If there are more than one, put
`error_mark_node' here. If there are none, this holds NULL_TREE. */
#define CLASSTYPE_CONVERSION(NODE,KIND) \
(TYPE_LANG_SPECIFIC(NODE)->conversions[(int) KIND])
/* Say whether this node was declared as a "class" or a "struct". */
/* Say whether this node was declared as a "class" or a "struct". */
#define CLASSTYPE_DECLARED_CLASS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_class)
#define CLASSTYPE_DECLARED_CLASS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_class)
/* whether this can be globalized. */
/* whether this can be globalized. */
...
@@ -2243,6 +2248,7 @@ extern void print_search_statistics PROTO((void));
...
@@ -2243,6 +2248,7 @@ extern void print_search_statistics PROTO((void));
extern
void
init_search_processing
PROTO
((
void
));
extern
void
init_search_processing
PROTO
((
void
));
extern
void
reinit_search_statistics
PROTO
((
void
));
extern
void
reinit_search_statistics
PROTO
((
void
));
extern
tree
current_scope
PROTO
((
void
));
extern
tree
current_scope
PROTO
((
void
));
extern
tree
lookup_conversions
PROTO
((
tree
));
/* in sig.c */
/* in sig.c */
extern
tree
build_signature_pointer_type
PROTO
((
tree
,
int
,
int
));
extern
tree
build_signature_pointer_type
PROTO
((
tree
,
int
,
int
));
...
...
gcc/cp/cvt.c
View file @
e1cd6e56
...
@@ -518,6 +518,18 @@ build_up_reference (type, arg, flags, checkconst)
...
@@ -518,6 +518,18 @@ build_up_reference (type, arg, flags, checkconst)
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
2
),
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
2
),
LOOKUP_PROTECT
,
checkconst
));
LOOKUP_PROTECT
,
checkconst
));
/* Undo the folding... */
case
MIN_EXPR
:
case
MAX_EXPR
:
return
build
(
COND_EXPR
,
type
,
build
(
TREE_CODE
(
targ
)
==
MIN_EXPR
?
LT_EXPR
:
GT_EXPR
,
boolean_type_node
,
TREE_OPERAND
(
targ
,
0
),
TREE_OPERAND
(
targ
,
1
)),
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
0
),
LOOKUP_PROTECT
,
checkconst
),
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
1
),
LOOKUP_PROTECT
,
checkconst
));
case
WITH_CLEANUP_EXPR
:
case
WITH_CLEANUP_EXPR
:
return
build
(
WITH_CLEANUP_EXPR
,
type
,
return
build
(
WITH_CLEANUP_EXPR
,
type
,
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
0
),
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
0
),
...
@@ -666,11 +678,10 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
...
@@ -666,11 +678,10 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if
(
form
==
REFERENCE_TYPE
)
if
(
form
==
REFERENCE_TYPE
)
{
{
tree
type
=
TREE_TYPE
(
expr
);
tree
type
=
TREE_TYPE
(
expr
);
tree
tmp
=
copy_node
(
expr
);
TREE_TYPE
(
expr
)
=
build_pointer_type
(
TREE_TYPE
(
type
));
TREE_TYPE
(
tmp
)
=
build_pointer_type
(
TREE_TYPE
(
TREE_TYPE
(
expr
)));
rval
=
cp_convert
(
build_pointer_type
(
TREE_TYPE
(
reftype
)),
expr
,
rval
=
cp_convert
(
build_pointer_type
(
TREE_TYPE
(
reftype
)),
tmp
,
convtype
,
flags
);
convtype
,
flags
);
TREE_TYPE
(
tmp
)
=
type
;
TREE_TYPE
(
expr
)
=
type
;
TREE_TYPE
(
rval
)
=
reftype
;
TREE_TYPE
(
rval
)
=
reftype
;
return
rval
;
return
rval
;
}
}
...
@@ -1487,14 +1498,8 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
...
@@ -1487,14 +1498,8 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
If (FOR_SURE & 1) is non-zero, then we allow this type conversion
If (FOR_SURE & 1) is non-zero, then we allow this type conversion
to take place immediately. Otherwise, we build a SAVE_EXPR
to take place immediately. Otherwise, we build a SAVE_EXPR
which can be evaluated if the results are ever needed.
which can be evaluated if the results are ever needed.
*/
If FOR_SURE >= 2, then we only look for exact conversions.
TYPE may be a reference type, in which case we first look
for something that will convert to a reference type. If
that fails, we will try to look for something of the
reference's target type, and then return a reference to that. */
tree
tree
build_type_conversion
(
code
,
xtype
,
expr
,
for_sure
)
build_type_conversion
(
code
,
xtype
,
expr
,
for_sure
)
enum
tree_code
code
;
enum
tree_code
code
;
...
@@ -1502,14 +1507,10 @@ build_type_conversion (code, xtype, expr, for_sure)
...
@@ -1502,14 +1507,10 @@ build_type_conversion (code, xtype, expr, for_sure)
int
for_sure
;
int
for_sure
;
{
{
/* C++: check to see if we can convert this aggregate type
/* C++: check to see if we can convert this aggregate type
into the required scalar type. */
into the required type. */
tree
type
,
type_default
;
tree
basetype
;
tree
typename
=
build_typename_overload
(
xtype
),
*
typenames
;
tree
conv
;
int
n_variants
=
0
;
tree
winner
=
NULL_TREE
;
tree
basetype
,
save_basetype
;
tree
rval
;
int
exact_conversion
=
for_sure
>=
2
;
for_sure
&=
1
;
if
(
expr
==
error_mark_node
)
if
(
expr
==
error_mark_node
)
return
error_mark_node
;
return
error_mark_node
;
...
@@ -1518,313 +1519,42 @@ build_type_conversion (code, xtype, expr, for_sure)
...
@@ -1518,313 +1519,42 @@ build_type_conversion (code, xtype, expr, for_sure)
if
(
TREE_CODE
(
basetype
)
==
REFERENCE_TYPE
)
if
(
TREE_CODE
(
basetype
)
==
REFERENCE_TYPE
)
basetype
=
TREE_TYPE
(
basetype
);
basetype
=
TREE_TYPE
(
basetype
);
if
(
TYPE_PTRMEMFUNC_P
(
basetype
)
&&
TREE_CODE
(
xtype
)
==
BOOLEAN_TYPE
)
{
/* We convert a pointer to member function into a boolean,
by just checking the index value, for == 0, we want false, for
!= 0, we want true. */
return
convert
(
xtype
,
build_component_ref
(
expr
,
index_identifier
,
0
,
0
));
}
basetype
=
TYPE_MAIN_VARIANT
(
basetype
);
basetype
=
TYPE_MAIN_VARIANT
(
basetype
);
if
(
!
TYPE_LANG_SPECIFIC
(
basetype
)
||
!
TYPE_HAS_CONVERSION
(
basetype
))
if
(
!
TYPE_LANG_SPECIFIC
(
basetype
)
||
!
TYPE_HAS_CONVERSION
(
basetype
))
return
NULL_TREE
;
return
NULL_TREE
;
if
(
TREE_CODE
(
xtype
)
==
POINTER_TYPE
/* Do we have an exact match? */
||
TREE_CODE
(
xtype
)
==
REFERENCE_TYPE
)
{
{
tree
typename
=
build_typename_overload
(
xtype
);
/* Prepare to match a variant of this type. */
if
(
lookup_fnfields
(
TYPE_BINFO
(
basetype
),
typename
,
0
))
type
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
xtype
));
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for
(
n_variants
=
0
;
type
;
type
=
TYPE_NEXT_VARIANT
(
type
))
for_sure
);
n_variants
++
;
}
typenames
=
(
tree
*
)
alloca
(
n_variants
*
sizeof
(
tree
));
for
(
n_variants
=
0
,
type
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
xtype
));
type
;
n_variants
++
,
type
=
TYPE_NEXT_VARIANT
(
type
))
{
if
(
type
==
TREE_TYPE
(
xtype
))
typenames
[
n_variants
]
=
typename
;
else
if
(
TREE_CODE
(
xtype
)
==
POINTER_TYPE
)
typenames
[
n_variants
]
=
build_typename_overload
(
build_pointer_type
(
type
));
else
typenames
[
n_variants
]
=
build_typename_overload
(
build_reference_type
(
type
));
}
}
save_basetype
=
basetype
;
type
=
xtype
;
while
(
TYPE_HAS_CONVERSION
(
basetype
))
{
int
i
;
if
(
lookup_fnfields
(
TYPE_BINFO
(
basetype
),
typename
,
0
))
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for_sure
);
for
(
i
=
0
;
i
<
n_variants
;
i
++
)
if
(
typenames
[
i
]
!=
typename
&&
lookup_fnfields
(
TYPE_BINFO
(
basetype
),
typenames
[
i
],
0
))
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typenames
[
i
],
for_sure
);
if
(
TYPE_BINFO_BASETYPES
(
basetype
))
basetype
=
TYPE_BINFO_BASETYPE
(
basetype
,
0
);
else
break
;
}
if
(
TREE_CODE
(
type
)
==
REFERENCE_TYPE
)
{
#if 0
/* Only reference variable initializations can use a temporary; this
must be handled elsewhere (like convert_to_reference and
compute_conversion_costs). */
type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
typename = build_typename_overload (type);
basetype = save_basetype;
/* May need to build a temporary for this. */
while (TYPE_HAS_CONVERSION (basetype))
{
if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))
{
int flags;
if (for_sure == 0)
flags = LOOKUP_PROTECT|LOOKUP_ONLYCONVERTING;
else
flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
rval = build_method_call (expr,
constructor_name_full (typename),
NULL_TREE, NULL_TREE, flags);
if (rval == error_mark_node)
{
if (for_sure == 0)
return NULL_TREE;
return error_mark_node;
}
return convert (xtype, rval);
}
if (TYPE_BINFO_BASETYPES (basetype))
basetype = TYPE_BINFO_BASETYPE (basetype, 0);
else
break;
}
#endif
/* No free conversions for reference types, right?. */
return
NULL_TREE
;
}
if
(
exact_conversion
)
return
NULL_TREE
;
if
(
TREE_CODE
(
type
)
==
BOOLEAN_TYPE
)
{
tree
as_int
=
build_type_conversion
(
code
,
long_long_unsigned_type_node
,
expr
,
0
);
tree
as_ptr
=
build_type_conversion
(
code
,
ptr_type_node
,
expr
,
0
);
/* We are missing the conversion to pointer to member type. */
/* We are missing the conversion to floating type. */
if
(
as_int
&&
as_ptr
&&
for_sure
)
{
cp_error
(
"ambiguous conversion from `%T' to `bool', can convert to integral type or pointer"
,
TREE_TYPE
(
expr
));
return
error_mark_node
;
}
if
(
as_int
)
{
as_int
=
build_type_conversion
(
code
,
long_long_unsigned_type_node
,
expr
,
for_sure
+
exact_conversion
*
2
);
return
convert
(
xtype
,
as_int
);
}
if
(
as_ptr
)
{
as_ptr
=
build_type_conversion
(
code
,
ptr_type_node
,
expr
,
for_sure
+
exact_conversion
*
2
);
return
convert
(
xtype
,
as_ptr
);
}
return
NULL_TREE
;
}
/* No perfect match found, try default. */
#if 0 /* This is wrong; there is no standard conversion from void* to
anything. -jason */
if (code == CONVERT_EXPR && TREE_CODE (type) == POINTER_TYPE)
type_default = ptr_type_node;
else
#endif
if
(
type
==
void_type_node
)
return
NULL_TREE
;
else
{
tree
tmp
=
default_conversion
(
build1
(
NOP_EXPR
,
type
,
integer_zero_node
));
if
(
tmp
==
error_mark_node
)
return
NULL_TREE
;
type_default
=
TREE_TYPE
(
tmp
);
}
basetype
=
save_basetype
;
if
(
type_default
!=
type
)
{
type
=
type_default
;
typename
=
build_typename_overload
(
type
);
while
(
TYPE_HAS_CONVERSION
(
basetype
))
{
if
(
lookup_fnfields
(
TYPE_BINFO
(
basetype
),
typename
,
0
))
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for_sure
);
if
(
TYPE_BINFO_BASETYPES
(
basetype
))
basetype
=
TYPE_BINFO_BASETYPE
(
basetype
,
0
);
else
break
;
}
}
if
(
TREE_CODE
(
type
)
==
POINTER_TYPE
&&
TYPE_READONLY
(
TREE_TYPE
(
type
)))
{
/* Try converting to some other const pointer type and then using
standard conversions. */
while
(
TYPE_HAS_CONVERSION
(
basetype
))
{
if
(
CLASSTYPE_CONVERSION
(
basetype
,
constptr_conv
)
!=
0
)
{
if
(
CLASSTYPE_CONVERSION
(
basetype
,
constptr_conv
)
==
error_mark_node
)
return
error_mark_node
;
typename
=
DECL_NAME
(
CLASSTYPE_CONVERSION
(
basetype
,
constptr_conv
));
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for_sure
);
}
if
(
TYPE_BINFO_BASETYPES
(
basetype
))
basetype
=
TYPE_BINFO_BASETYPE
(
basetype
,
0
);
else
break
;
}
}
if
(
TREE_CODE
(
type
)
==
POINTER_TYPE
)
{
/* Try converting to some other pointer type and then using standard
conversions. */
while
(
TYPE_HAS_CONVERSION
(
basetype
))
{
if
(
CLASSTYPE_CONVERSION
(
basetype
,
ptr_conv
)
!=
0
)
{
if
(
CLASSTYPE_CONVERSION
(
basetype
,
ptr_conv
)
==
error_mark_node
)
return
error_mark_node
;
typename
=
DECL_NAME
(
CLASSTYPE_CONVERSION
(
basetype
,
ptr_conv
));
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for_sure
);
}
if
(
TYPE_BINFO_BASETYPES
(
basetype
))
basetype
=
TYPE_BINFO_BASETYPE
(
basetype
,
0
);
else
break
;
}
}
/* Use the longer or shorter conversion that is appropriate. Have
to check against 0 because the conversion may come from a baseclass. */
if
(
TREE_CODE
(
type
)
==
INTEGER_TYPE
&&
TYPE_HAS_INT_CONVERSION
(
basetype
)
&&
CLASSTYPE_CONVERSION
(
basetype
,
int_conv
)
!=
0
&&
CLASSTYPE_CONVERSION
(
basetype
,
int_conv
)
!=
error_mark_node
)
{
typename
=
DECL_NAME
(
CLASSTYPE_CONVERSION
(
basetype
,
int_conv
));
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for_sure
);
}
if
(
TREE_CODE
(
type
)
==
REAL_TYPE
/* Nope; try looking for others. */
&&
TYPE_HAS_REAL_CONVERSION
(
basetype
)
for
(
conv
=
lookup_conversions
(
basetype
);
conv
;
conv
=
TREE_CHAIN
(
conv
))
&&
CLASSTYPE_CONVERSION
(
basetype
,
real_conv
)
!=
0
&&
CLASSTYPE_CONVERSION
(
basetype
,
real_conv
)
!=
error_mark_node
)
{
{
/* Only accept using an operator double() if there isn't a conflicting
if
(
winner
&&
TREE_PURPOSE
(
winner
)
==
TREE_PURPOSE
(
conv
))
operator int(). */
continue
;
if
(
TYPE_HAS_INT_CONVERSION
(
basetype
))
{
if
(
for_sure
)
{
cp_error
(
"two possible conversions for type `%T'"
,
type
);
return
error_mark_node
;
}
else
return
NULL_TREE
;
}
typename
=
DECL_NAME
(
CLASSTYPE_CONVERSION
(
basetype
,
real_conv
));
if
(
can_convert
(
xtype
,
TREE_VALUE
(
conv
)))
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for_sure
);
}
/* THESE ARE TOTAL KLUDGES. */
/* Default promotion yields no new alternatives, try
conversions which are anti-default, such as
double -> float or int -> unsigned or unsigned -> long
*/
if
(
type_default
==
type
&&
(
INTEGRAL_TYPE_P
(
type
)
||
TREE_CODE
(
type
)
==
REAL_TYPE
))
{
int
not_again
=
0
;
if
(
type
==
double_type_node
)
typename
=
build_typename_overload
(
float_type_node
);
else
if
(
type
==
integer_type_node
)
typename
=
build_typename_overload
(
unsigned_type_node
);
else
if
(
type
==
unsigned_type_node
)
typename
=
build_typename_overload
(
long_integer_type_node
);
again
:
basetype
=
save_basetype
;
while
(
TYPE_HAS_CONVERSION
(
basetype
))
{
if
(
lookup_fnfields
(
TYPE_BINFO
(
basetype
),
typename
,
0
))
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for_sure
);
if
(
TYPE_BINFO_BASETYPES
(
basetype
))
basetype
=
TYPE_BINFO_BASETYPE
(
basetype
,
0
);
else
break
;
}
if
(
!
not_again
)
{
{
if
(
type
==
integer_type_node
)
if
(
winner
)
{
{
typename
=
build_typename_overload
(
long_integer_type_node
);
cp_error
(
"ambiguous conversion from `%T' to `%T'"
,
basetype
,
not_again
=
1
;
xtype
);
goto
again
;
cp_error
(
" candidate conversion functions include `%T' and `%T'"
,
TREE_VALUE
(
winner
),
TREE_VALUE
(
conv
));
return
NULL_TREE
;
}
}
else
else
{
winner
=
conv
;
typename
=
build_typename_overload
(
integer_type_node
);
not_again
=
1
;
goto
again
;
}
}
}
}
}
/* Now, try C promotions...
if
(
winner
)
return
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
float -> int
TREE_PURPOSE
(
winner
),
for_sure
);
int -> float */
basetype
=
save_basetype
;
if
(
TREE_CODE
(
type
)
==
REAL_TYPE
)
type
=
integer_type_node
;
else
if
(
TREE_CODE
(
type
)
==
INTEGER_TYPE
)
if
(
TYPE_HAS_REAL_CONVERSION
(
basetype
))
type
=
double_type_node
;
else
return
NULL_TREE
;
else
return
NULL_TREE
;
typename
=
build_typename_overload
(
type
);
while
(
TYPE_HAS_CONVERSION
(
basetype
))
{
if
(
lookup_fnfields
(
TYPE_BINFO
(
basetype
),
typename
,
0
))
{
rval
=
build_type_conversion_1
(
xtype
,
basetype
,
expr
,
typename
,
for_sure
);
return
rval
;
}
if
(
TYPE_BINFO_BASETYPES
(
basetype
))
basetype
=
TYPE_BINFO_BASETYPE
(
basetype
,
0
);
else
break
;
}
return
NULL_TREE
;
return
NULL_TREE
;
}
}
...
...
gcc/cp/decl.c
View file @
e1cd6e56
...
@@ -49,6 +49,8 @@ extern int current_class_depth;
...
@@ -49,6 +49,8 @@ extern int current_class_depth;
extern
tree
cleanups_this_call
;
extern
tree
cleanups_this_call
;
extern
tree
static_ctors
,
static_dtors
;
/* Stack of places to restore the search obstack back to. */
/* Stack of places to restore the search obstack back to. */
/* Obstack used for remembering local class declarations (like
/* Obstack used for remembering local class declarations (like
...
@@ -94,7 +96,11 @@ static struct stack_level *decl_stack;
...
@@ -94,7 +96,11 @@ static struct stack_level *decl_stack;
#endif
#endif
#ifndef BOOL_TYPE_SIZE
#ifndef BOOL_TYPE_SIZE
#ifdef SLOW_BYTE_ACCESS
#define BOOL_TYPE_SIZE BITS_PER_WORD
#define BOOL_TYPE_SIZE BITS_PER_WORD
#else
#define BOOL_TYPE_SIZE BITS_PER_UNIT
#endif
#endif
#endif
/* We let tm.h override the types used here, to handle trivial differences
/* We let tm.h override the types used here, to handle trivial differences
...
@@ -428,7 +434,8 @@ extern int flag_no_builtin;
...
@@ -428,7 +434,8 @@ extern int flag_no_builtin;
extern
int
flag_no_nonansi_builtin
;
extern
int
flag_no_nonansi_builtin
;
/* Nonzero means disable GNU extensions. */
/* Nonzero means enable obscure ANSI features and disable GNU extensions
that might cause ANSI-compliant code to be miscompiled. */
extern
int
flag_ansi
;
extern
int
flag_ansi
;
...
@@ -1638,27 +1645,25 @@ static void
...
@@ -1638,27 +1645,25 @@ static void
set_nested_typename
(
decl
,
classname
,
name
,
type
)
set_nested_typename
(
decl
,
classname
,
name
,
type
)
tree
decl
,
classname
,
name
,
type
;
tree
decl
,
classname
,
name
,
type
;
{
{
char
*
buf
;
my_friendly_assert
(
TREE_CODE
(
decl
)
==
TYPE_DECL
,
136
);
my_friendly_assert
(
TREE_CODE
(
decl
)
==
TYPE_DECL
,
136
);
if
(
classname
!=
NULL_TREE
)
if
(
classname
==
NULL_TREE
)
{
classname
=
get_identifier
(
""
);
char
*
buf
;
my_friendly_assert
(
TREE_CODE
(
classname
)
==
IDENTIFIER_NODE
,
137
);
my_friendly_assert
(
TREE_CODE
(
classname
)
==
IDENTIFIER_NODE
,
137
);
my_friendly_assert
(
TREE_CODE
(
name
)
==
IDENTIFIER_NODE
,
138
);
my_friendly_assert
(
TREE_CODE
(
name
)
==
IDENTIFIER_NODE
,
138
);
buf
=
(
char
*
)
alloca
(
4
+
IDENTIFIER_LENGTH
(
classname
)
buf
=
(
char
*
)
alloca
(
4
+
IDENTIFIER_LENGTH
(
classname
)
+
IDENTIFIER_LENGTH
(
name
));
+
IDENTIFIER_LENGTH
(
name
));
sprintf
(
buf
,
"%s::%s"
,
IDENTIFIER_POINTER
(
classname
),
sprintf
(
buf
,
"%s::%s"
,
IDENTIFIER_POINTER
(
classname
),
IDENTIFIER_POINTER
(
name
));
IDENTIFIER_POINTER
(
name
));
DECL_NESTED_TYPENAME
(
decl
)
=
get_identifier
(
buf
);
DECL_NESTED_TYPENAME
(
decl
)
=
get_identifier
(
buf
);
TREE_MANGLED
(
DECL_NESTED_TYPENAME
(
decl
))
=
1
;
TREE_MANGLED
(
DECL_NESTED_TYPENAME
(
decl
))
=
1
;
/* This is a special usage of IDENTIFIER_TYPE_VALUE which have no
/* This is a special usage of IDENTIFIER_TYPE_VALUE which have no
correspondence in any binding_level. This is ok since the
correspondence in any binding_level. This is ok since the
DECL_NESTED_TYPENAME is just a convenience identifier whose
DECL_NESTED_TYPENAME is just a convenience identifier whose
IDENTIFIER_TYPE_VALUE will remain constant from now on. */
IDENTIFIER_TYPE_VALUE will remain constant from now on. */
SET_IDENTIFIER_TYPE_VALUE
(
DECL_NESTED_TYPENAME
(
decl
),
type
);
SET_IDENTIFIER_TYPE_VALUE
(
DECL_NESTED_TYPENAME
(
decl
),
type
);
}
else
DECL_NESTED_TYPENAME
(
decl
)
=
name
;
}
}
/* Pop off extraneous binding levels left over due to syntax errors. */
/* Pop off extraneous binding levels left over due to syntax errors. */
...
@@ -1743,11 +1748,13 @@ pushtag (name, type, globalize)
...
@@ -1743,11 +1748,13 @@ pushtag (name, type, globalize)
context
=
current_scope
();
context
=
current_scope
();
if
(
context
)
if
(
context
)
c_decl
=
TREE_CODE
(
context
)
==
FUNCTION_DECL
c_decl
=
TREE_CODE
(
context
)
==
FUNCTION_DECL
?
context
:
TYPE_
NAME
(
context
);
?
context
:
TYPE_
MAIN_DECL
(
context
);
#if 0
/* Record the identifier as the type's name if it has none. */
/* Record the identifier as the type's name if it has none. */
if (TYPE_NAME (type) == NULL_TREE)
if (TYPE_NAME (type) == NULL_TREE)
TYPE_NAME (type) = name;
TYPE_NAME (type) = name;
#endif
/* Do C++ gratuitous typedefing. */
/* Do C++ gratuitous typedefing. */
if
(
IDENTIFIER_TYPE_VALUE
(
name
)
!=
type
)
if
(
IDENTIFIER_TYPE_VALUE
(
name
)
!=
type
)
...
@@ -1784,14 +1791,11 @@ pushtag (name, type, globalize)
...
@@ -1784,14 +1791,11 @@ pushtag (name, type, globalize)
else
else
d
=
TYPE_NAME
(
d
);
d
=
TYPE_NAME
(
d
);
TYPE_NAME
(
type
)
=
d
;
/* If it is anonymous, then we are called from pushdecl,
/* If it is anonymous, then we are called from pushdecl,
and we don't want to infinitely recurse. Also, if the
and we don't want to infinitely recurse. */
name is already in scope, we don't want to push it
if
(
!
ANON_AGGRNAME_P
(
name
))
again--pushdecl is only for pushing new decls. */
if
(
!
ANON_AGGRNAME_P
(
name
)
&&
TYPE_NAME
(
type
)
&&
(
TREE_CODE
(
TYPE_NAME
(
type
))
!=
TYPE_DECL
||
lookup_name
(
name
,
1
)
!=
TYPE_NAME
(
type
)))
{
{
if
(
b
->
parm_flag
==
2
)
if
(
b
->
parm_flag
==
2
)
d
=
pushdecl_class_level
(
d
);
d
=
pushdecl_class_level
(
d
);
...
@@ -1815,6 +1819,9 @@ pushtag (name, type, globalize)
...
@@ -1815,6 +1819,9 @@ pushtag (name, type, globalize)
DECL_IGNORED_P
(
d
)
=
1
;
DECL_IGNORED_P
(
d
)
=
1
;
}
}
#endif
/* DWARF_DEBUGGING_INFO */
#endif
/* DWARF_DEBUGGING_INFO */
TYPE_NAME
(
type
)
=
d
;
/* Make sure we're in this type's scope when we push the
/* Make sure we're in this type's scope when we push the
decl for a template, otherwise class_binding_level will
decl for a template, otherwise class_binding_level will
be NULL and we'll end up dying inside of
be NULL and we'll end up dying inside of
...
@@ -1830,11 +1837,10 @@ pushtag (name, type, globalize)
...
@@ -1830,11 +1837,10 @@ pushtag (name, type, globalize)
if
(
ANON_AGGRNAME_P
(
name
))
if
(
ANON_AGGRNAME_P
(
name
))
DECL_IGNORED_P
(
d
)
=
1
;
DECL_IGNORED_P
(
d
)
=
1
;
}
}
TYPE_NAME
(
type
)
=
d
;
if
(
context
==
NULL_TREE
)
if
(
context
==
NULL_TREE
)
/* Non-nested class. */
/* Non-nested class. */
DECL_NESTED_TYPENAME
(
d
)
=
name
;
set_nested_typename
(
d
,
NULL_TREE
,
name
,
type
)
;
else
if
(
context
&&
TREE_CODE
(
context
)
==
FUNCTION_DECL
)
else
if
(
context
&&
TREE_CODE
(
context
)
==
FUNCTION_DECL
)
{
{
/* Function-nested class. */
/* Function-nested class. */
...
@@ -2036,7 +2042,9 @@ decls_match (newdecl, olddecl)
...
@@ -2036,7 +2042,9 @@ decls_match (newdecl, olddecl)
else
if
(
TREE_TYPE
(
newdecl
)
==
NULL_TREE
)
else
if
(
TREE_TYPE
(
newdecl
)
==
NULL_TREE
)
types_match
=
0
;
types_match
=
0
;
else
else
types_match
=
comptypes
(
TREE_TYPE
(
newdecl
),
TREE_TYPE
(
olddecl
),
1
);
types_match
=
(
comptypes
(
TREE_TYPE
(
newdecl
),
TREE_TYPE
(
olddecl
),
1
)
&&
TREE_READONLY
(
newdecl
)
==
TREE_READONLY
(
olddecl
)
&&
TREE_THIS_VOLATILE
(
newdecl
)
==
TREE_THIS_VOLATILE
(
olddecl
));
}
}
return
types_match
;
return
types_match
;
...
@@ -2226,16 +2234,6 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2226,16 +2234,6 @@ duplicate_decls (newdecl, olddecl)
return
0
;
return
0
;
}
}
if
(
olddecl
==
wchar_decl_node
)
{
if
(
pedantic
&&
!
DECL_IN_SYSTEM_HEADER
(
newdecl
))
cp_pedwarn
(
"redeclaration of wchar_t as `%T'"
,
TREE_TYPE
(
newdecl
));
/* Throw away the redeclaration. */
return
1
;
}
/* Already complained about this, so don't do so again. */
/* Already complained about this, so don't do so again. */
else
if
(
current_class_type
==
NULL_TREE
else
if
(
current_class_type
==
NULL_TREE
||
IDENTIFIER_ERROR_LOCUS
(
DECL_ASSEMBLER_NAME
(
newdecl
))
!=
current_class_type
)
||
IDENTIFIER_ERROR_LOCUS
(
DECL_ASSEMBLER_NAME
(
newdecl
))
!=
current_class_type
)
...
@@ -2281,6 +2279,39 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2281,6 +2279,39 @@ duplicate_decls (newdecl, olddecl)
DECL_LANGUAGE
(
newdecl
));
DECL_LANGUAGE
(
newdecl
));
}
}
}
}
if
(
TREE_CODE
(
olddecl
)
==
FUNCTION_DECL
)
{
tree
t1
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
olddecl
));
tree
t2
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
newdecl
));
int
i
=
1
;
if
(
TREE_CODE
(
TREE_TYPE
(
newdecl
))
==
METHOD_TYPE
)
t1
=
TREE_CHAIN
(
t1
),
t2
=
TREE_CHAIN
(
t2
);
for
(;
t1
&&
t1
!=
void_list_node
;
t1
=
TREE_CHAIN
(
t1
),
t2
=
TREE_CHAIN
(
t2
),
i
++
)
if
(
TREE_PURPOSE
(
t1
)
&&
TREE_PURPOSE
(
t2
))
{
if
(
simple_cst_equal
(
TREE_PURPOSE
(
t1
),
TREE_PURPOSE
(
t2
)))
{
if
(
pedantic
)
{
cp_pedwarn
(
"default argument given for parameter %d of `%#D'"
,
i
,
newdecl
);
cp_pedwarn_at
(
"after previous specification in `%#D'"
,
olddecl
);
}
}
else
{
cp_error
(
"default argument given for parameter %d of `%#D'"
,
i
,
newdecl
);
cp_error_at
(
"conflicts with previous specification in `%#D'"
,
olddecl
);
}
}
}
}
}
/* If new decl is `static' and an `extern' was seen previously,
/* If new decl is `static' and an `extern' was seen previously,
...
@@ -2306,6 +2337,8 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2306,6 +2337,8 @@ duplicate_decls (newdecl, olddecl)
DECL_NEXT_METHOD
(
newdecl
)
=
DECL_NEXT_METHOD
(
olddecl
);
DECL_NEXT_METHOD
(
newdecl
)
=
DECL_NEXT_METHOD
(
olddecl
);
if
(
DECL_PENDING_INLINE_INFO
(
newdecl
)
==
(
struct
pending_inline
*
)
0
)
if
(
DECL_PENDING_INLINE_INFO
(
newdecl
)
==
(
struct
pending_inline
*
)
0
)
DECL_PENDING_INLINE_INFO
(
newdecl
)
=
DECL_PENDING_INLINE_INFO
(
olddecl
);
DECL_PENDING_INLINE_INFO
(
newdecl
)
=
DECL_PENDING_INLINE_INFO
(
olddecl
);
DECL_STATIC_CONSTRUCTOR
(
newdecl
)
|=
DECL_STATIC_CONSTRUCTOR
(
olddecl
);
DECL_STATIC_DESTRUCTOR
(
newdecl
)
|=
DECL_STATIC_DESTRUCTOR
(
olddecl
);
}
}
/* Deal with C++: must preserve virtual function table size. */
/* Deal with C++: must preserve virtual function table size. */
...
@@ -2358,13 +2391,10 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2358,13 +2391,10 @@ duplicate_decls (newdecl, olddecl)
{
{
/* Automatically handles default parameters. */
/* Automatically handles default parameters. */
tree
oldtype
=
TREE_TYPE
(
olddecl
);
tree
oldtype
=
TREE_TYPE
(
olddecl
);
/* Merge the data types specified in the two decls. */
tree
newtype
;
tree
newtype
=
common_type
(
TREE_TYPE
(
newdecl
),
TREE_TYPE
(
olddecl
));
/* Make sure we put the new type in the same obstack as the old ones.
/* Make sure we put the new type in the same obstack as the old one. */
If the old types are not both in the same obstack, use the permanent
if
(
oldtype
)
one. */
if
(
oldtype
&&
TYPE_OBSTACK
(
oldtype
)
==
TYPE_OBSTACK
(
newtype
))
push_obstacks
(
TYPE_OBSTACK
(
oldtype
),
TYPE_OBSTACK
(
oldtype
));
push_obstacks
(
TYPE_OBSTACK
(
oldtype
),
TYPE_OBSTACK
(
oldtype
));
else
else
{
{
...
@@ -2372,6 +2402,9 @@ duplicate_decls (newdecl, olddecl)
...
@@ -2372,6 +2402,9 @@ duplicate_decls (newdecl, olddecl)
end_temporary_allocation
();
end_temporary_allocation
();
}
}
/* Merge the data types specified in the two decls. */
newtype
=
common_type
(
TREE_TYPE
(
newdecl
),
TREE_TYPE
(
olddecl
));
if
(
TREE_CODE
(
newdecl
)
==
VAR_DECL
)
if
(
TREE_CODE
(
newdecl
)
==
VAR_DECL
)
DECL_THIS_EXTERN
(
newdecl
)
|=
DECL_THIS_EXTERN
(
olddecl
);
DECL_THIS_EXTERN
(
newdecl
)
|=
DECL_THIS_EXTERN
(
olddecl
);
/* Do this after calling `common_type' so that default
/* Do this after calling `common_type' so that default
...
@@ -2703,6 +2736,14 @@ pushdecl (x)
...
@@ -2703,6 +2736,14 @@ pushdecl (x)
&&
!
DECL_TEMPLATE_IS_CLASS
(
x
)))
&&
!
DECL_TEMPLATE_IS_CLASS
(
x
)))
&&
is_overloaded_fn
(
t
))
&&
is_overloaded_fn
(
t
))
/* don't do anything just yet */
;
/* don't do anything just yet */
;
else
if
(
t
==
wchar_decl_node
)
{
if
(
pedantic
&&
!
DECL_IN_SYSTEM_HEADER
(
x
))
cp_pedwarn
(
"redeclaration of wchar_t as `%T'"
,
TREE_TYPE
(
x
));
/* Throw away the redeclaration. */
return
t
;
}
else
if
(
TREE_CODE
(
t
)
!=
TREE_CODE
(
x
))
else
if
(
TREE_CODE
(
t
)
!=
TREE_CODE
(
x
))
{
{
if
((
TREE_CODE
(
t
)
==
TYPE_DECL
&&
DECL_ARTIFICIAL
(
t
))
if
((
TREE_CODE
(
t
)
==
TYPE_DECL
&&
DECL_ARTIFICIAL
(
t
))
...
@@ -2796,9 +2837,8 @@ pushdecl (x)
...
@@ -2796,9 +2837,8 @@ pushdecl (x)
}
}
my_friendly_assert
(
TREE_CODE
(
name
)
==
TYPE_DECL
,
140
);
my_friendly_assert
(
TREE_CODE
(
name
)
==
TYPE_DECL
,
140
);
if
(
DECL_NAME
(
name
)
&&
!
DECL_NESTED_TYPENAME
(
name
))
if
(
!
DECL_NESTED_TYPENAME
(
x
))
set_nested_typename
(
x
,
current_class_name
,
set_nested_typename
(
x
,
current_class_name
,
DECL_NAME
(
x
),
type
);
DECL_NAME
(
name
),
type
);
if
(
type
!=
error_mark_node
if
(
type
!=
error_mark_node
&&
TYPE_NAME
(
type
)
&&
TYPE_NAME
(
type
)
...
@@ -2856,11 +2896,11 @@ pushdecl (x)
...
@@ -2856,11 +2896,11 @@ pushdecl (x)
if
(
IDENTIFIER_GLOBAL_VALUE
(
name
)
==
NULL_TREE
&&
DECL_PUBLIC
(
x
))
if
(
IDENTIFIER_GLOBAL_VALUE
(
name
)
==
NULL_TREE
&&
DECL_PUBLIC
(
x
))
TREE_PUBLIC
(
name
)
=
1
;
TREE_PUBLIC
(
name
)
=
1
;
/* Don't install a
TYPE_DECL if we already have another
/* Don't install a
n artificial TYPE_DECL if we already have
sort of
_DECL with that name. */
another
_DECL with that name. */
if
(
TREE_CODE
(
x
)
!=
TYPE_DECL
if
(
TREE_CODE
(
x
)
!=
TYPE_DECL
||
t
==
NULL_TREE
||
t
==
NULL_TREE
||
TREE_CODE
(
t
)
==
TYPE_DECL
)
||
!
DECL_ARTIFICIAL
(
x
)
)
IDENTIFIER_GLOBAL_VALUE
(
name
)
=
x
;
IDENTIFIER_GLOBAL_VALUE
(
name
)
=
x
;
/* Don't forget if the function was used via an implicit decl. */
/* Don't forget if the function was used via an implicit decl. */
...
@@ -2892,8 +2932,15 @@ pushdecl (x)
...
@@ -2892,8 +2932,15 @@ pushdecl (x)
tree
oldlocal
=
IDENTIFIER_LOCAL_VALUE
(
name
);
tree
oldlocal
=
IDENTIFIER_LOCAL_VALUE
(
name
);
tree
oldglobal
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
tree
oldglobal
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
b
->
shadowed
=
tree_cons
(
name
,
oldlocal
,
b
->
shadowed
);
/* Don't install an artificial TYPE_DECL if we already have
IDENTIFIER_LOCAL_VALUE
(
name
)
=
x
;
another _DECL with that name. */
if
(
TREE_CODE
(
x
)
!=
TYPE_DECL
||
t
==
NULL_TREE
||
!
DECL_ARTIFICIAL
(
x
))
{
b
->
shadowed
=
tree_cons
(
name
,
oldlocal
,
b
->
shadowed
);
IDENTIFIER_LOCAL_VALUE
(
name
)
=
x
;
}
/* If this is a TYPE_DECL, push it into the type value slot. */
/* If this is a TYPE_DECL, push it into the type value slot. */
if
(
TREE_CODE
(
x
)
==
TYPE_DECL
)
if
(
TREE_CODE
(
x
)
==
TYPE_DECL
)
...
@@ -2968,11 +3015,25 @@ pushdecl (x)
...
@@ -2968,11 +3015,25 @@ pushdecl (x)
if
(
warnstring
)
if
(
warnstring
)
warning
(
warnstring
,
IDENTIFIER_POINTER
(
name
));
warning
(
warnstring
,
IDENTIFIER_POINTER
(
name
));
}
}
}
/* If storing a local value, there may already be one (inherited).
if
(
TREE_CODE
(
x
)
==
FUNCTION_DECL
)
If so, record it for restoration when this binding level ends. */
{
if
(
oldlocal
!=
NULL_TREE
)
/* This is probably the wrong place to check this, but it has to
b
->
shadowed
=
tree_cons
(
name
,
oldlocal
,
b
->
shadowed
);
come after the call to duplicate_decls. */
tree
arg
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
x
));
int
saw_def
=
0
,
i
=
1
;
for
(;
arg
&&
arg
!=
void_list_node
;
arg
=
TREE_CHAIN
(
arg
),
++
i
)
{
if
(
TREE_PURPOSE
(
arg
))
saw_def
=
1
;
else
if
(
saw_def
)
{
cp_error
(
"default argument missing for parameter %d of `%#D'"
,
i
,
x
);
break
;
}
}
}
}
/* Keep count of variables in this level with incomplete type. */
/* Keep count of variables in this level with incomplete type. */
...
@@ -3168,6 +3229,10 @@ push_class_level_binding (name, x)
...
@@ -3168,6 +3229,10 @@ push_class_level_binding (name, x)
tree
name
;
tree
name
;
tree
x
;
tree
x
;
{
{
if
(
TREE_CODE
(
x
)
==
TYPE_DECL
&&
DECL_ARTIFICIAL
(
x
)
&&
purpose_member
(
name
,
class_binding_level
->
class_shadowed
))
return
;
maybe_push_cache_obstack
();
maybe_push_cache_obstack
();
class_binding_level
->
class_shadowed
class_binding_level
->
class_shadowed
=
tree_cons
(
name
,
IDENTIFIER_CLASS_VALUE
(
name
),
=
tree_cons
(
name
,
IDENTIFIER_CLASS_VALUE
(
name
),
...
@@ -3251,13 +3316,7 @@ push_overloaded_decl (decl, forgettable)
...
@@ -3251,13 +3316,7 @@ push_overloaded_decl (decl, forgettable)
old = TREE_OPERAND (old, 0);
old = TREE_OPERAND (old, 0);
else
else
#endif
#endif
if
(
TREE_CODE
(
old
)
==
VAR_DECL
)
if
(
TREE_CODE
(
old
)
==
TYPE_DECL
&&
DECL_ARTIFICIAL
(
old
))
{
cp_error_at
(
"previous non-function declaration `%#D'"
,
old
);
cp_error
(
"conflicts with function declaration `%#D'"
,
decl
);
return
error_mark_node
;
}
else
if
(
TREE_CODE
(
old
)
==
TYPE_DECL
)
{
{
tree
t
=
TREE_TYPE
(
old
);
tree
t
=
TREE_TYPE
(
old
);
if
(
IS_AGGR_TYPE
(
t
)
&&
warn_shadow
)
if
(
IS_AGGR_TYPE
(
t
)
&&
warn_shadow
)
...
@@ -3272,6 +3331,12 @@ push_overloaded_decl (decl, forgettable)
...
@@ -3272,6 +3331,12 @@ push_overloaded_decl (decl, forgettable)
if
(
decl
==
tmp
||
duplicate_decls
(
decl
,
tmp
))
if
(
decl
==
tmp
||
duplicate_decls
(
decl
,
tmp
))
return
tmp
;
return
tmp
;
}
}
else
{
cp_error_at
(
"previous non-function declaration `%#D'"
,
old
);
cp_error
(
"conflicts with function declaration `%#D'"
,
decl
);
return
error_mark_node
;
}
}
}
if
(
old
||
TREE_CODE
(
decl
)
==
TEMPLATE_DECL
)
if
(
old
||
TREE_CODE
(
decl
)
==
TEMPLATE_DECL
)
...
@@ -3386,18 +3451,6 @@ redeclaration_error_message (newdecl, olddecl)
...
@@ -3386,18 +3451,6 @@ redeclaration_error_message (newdecl, olddecl)
else
else
return
"redefinition of `%#D'"
;
return
"redefinition of `%#D'"
;
}
}
{
tree
t1
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
olddecl
));
tree
t2
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
newdecl
));
if
(
TREE_CODE
(
TREE_TYPE
(
newdecl
))
==
METHOD_TYPE
)
t1
=
TREE_CHAIN
(
t1
),
t2
=
TREE_CHAIN
(
t2
);
for
(;
t1
;
t1
=
TREE_CHAIN
(
t1
),
t2
=
TREE_CHAIN
(
t2
))
if
(
TREE_PURPOSE
(
t1
)
&&
TREE_PURPOSE
(
t2
))
return
"duplicate default arguments given for `%#D'"
;
}
return
0
;
return
0
;
}
}
else
if
(
TREE_CODE
(
newdecl
)
==
TEMPLATE_DECL
)
else
if
(
TREE_CODE
(
newdecl
)
==
TEMPLATE_DECL
)
...
@@ -3535,6 +3588,9 @@ define_label (filename, line, name)
...
@@ -3535,6 +3588,9 @@ define_label (filename, line, name)
decl
=
lookup_label
(
name
);
decl
=
lookup_label
(
name
);
}
}
if
(
name
==
get_identifier
(
"wchar_t"
))
cp_pedwarn
(
"label named wchar_t"
);
if
(
DECL_INITIAL
(
decl
)
!=
NULL_TREE
)
if
(
DECL_INITIAL
(
decl
)
!=
NULL_TREE
)
{
{
cp_error
(
"duplicate label `%D'"
,
decl
);
cp_error
(
"duplicate label `%D'"
,
decl
);
...
@@ -3866,9 +3922,9 @@ lookup_nested_type (type, context)
...
@@ -3866,9 +3922,9 @@ lookup_nested_type (type, context)
}
}
break
;
break
;
case
FUNCTION_DECL
:
case
FUNCTION_DECL
:
return
TYPE_IDENTIFIER
(
type
)
?
if
(
TYPE_NAME
(
type
)
&&
TYPE_IDENTIFIER
(
type
))
lookup_name
(
TYPE_IDENTIFIER
(
type
),
1
)
:
NULL_TREE
;
return
lookup_name
(
TYPE_IDENTIFIER
(
type
),
1
)
;
break
;
return
NULL_TREE
;
default
:
default
:
my_friendly_abort
(
12
);
my_friendly_abort
(
12
);
}
}
...
@@ -3893,43 +3949,50 @@ lookup_name_real (name, prefer_type, nonclass)
...
@@ -3893,43 +3949,50 @@ lookup_name_real (name, prefer_type, nonclass)
{
{
register
tree
val
;
register
tree
val
;
int
yylex
=
0
;
int
yylex
=
0
;
tree
from_obj
=
NULL_TREE
;
if
(
prefer_type
==
-
2
)
if
(
prefer_type
==
-
2
)
{
{
extern
int
looking_for_typename
;
extern
int
looking_for_typename
;
tree
type
;
yylex
=
1
;
yylex
=
1
;
prefer_type
=
looking_for_typename
;
prefer_type
=
looking_for_typename
;
if
(
got_scope
)
type
=
got_scope
;
else
type
=
got_object
;
if
(
got_scope
!=
NULL_TREE
)
if
(
type
)
{
{
if
(
got_sco
pe
==
error_mark_node
)
if
(
ty
pe
==
error_mark_node
)
return
error_mark_node
;
return
error_mark_node
;
else
if
(
got_sco
pe
==
void_type_node
)
else
if
(
ty
pe
==
void_type_node
)
val
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
val
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
else
if
(
TREE_CODE
(
got_sco
pe
)
==
TEMPLATE_TYPE_PARM
else
if
(
TREE_CODE
(
ty
pe
)
==
TEMPLATE_TYPE_PARM
/* TFIXME -- don't do this for UPTs in new model. */
/* TFIXME -- don't do this for UPTs in new model. */
||
TREE_CODE
(
got_sco
pe
)
==
UNINSTANTIATED_P_TYPE
)
||
TREE_CODE
(
ty
pe
)
==
UNINSTANTIATED_P_TYPE
)
{
{
if
(
prefer_type
>
0
)
if
(
prefer_type
>
0
)
val
=
create_nested_upt
(
got_sco
pe
,
name
);
val
=
create_nested_upt
(
ty
pe
,
name
);
else
else
val
=
NULL_TREE
;
val
=
NULL_TREE
;
}
}
else
if
(
!
IS_AGGR_TYPE
(
got_sco
pe
))
else
if
(
!
IS_AGGR_TYPE
(
ty
pe
))
/* Someone else will give an error about this if needed. */
/* Someone else will give an error about this if needed. */
val
=
NULL_TREE
;
val
=
NULL_TREE
;
else
if
(
TYPE_BEING_DEFINED
(
got_sco
pe
))
else
if
(
TYPE_BEING_DEFINED
(
ty
pe
))
{
{
val
=
IDENTIFIER_CLASS_VALUE
(
name
);
val
=
IDENTIFIER_CLASS_VALUE
(
name
);
if
(
val
&&
DECL_CONTEXT
(
val
)
!=
got_sco
pe
)
if
(
val
&&
DECL_CONTEXT
(
val
)
!=
ty
pe
)
{
{
struct
binding_level
*
b
=
class_binding_level
;
struct
binding_level
*
b
=
class_binding_level
;
for
(
val
=
NULL_TREE
;
b
;
b
=
b
->
level_chain
)
for
(
val
=
NULL_TREE
;
b
;
b
=
b
->
level_chain
)
{
{
tree
t
=
purpose_member
(
name
,
b
->
class_shadowed
);
tree
t
=
purpose_member
(
name
,
b
->
class_shadowed
);
if
(
t
&&
TREE_VALUE
(
t
)
if
(
t
&&
TREE_VALUE
(
t
)
&&
DECL_CONTEXT
(
TREE_VALUE
(
t
))
==
got_sco
pe
)
&&
DECL_CONTEXT
(
TREE_VALUE
(
t
))
==
ty
pe
)
{
{
val
=
TREE_VALUE
(
t
);
val
=
TREE_VALUE
(
t
);
break
;
break
;
...
@@ -3937,16 +4000,23 @@ lookup_name_real (name, prefer_type, nonclass)
...
@@ -3937,16 +4000,23 @@ lookup_name_real (name, prefer_type, nonclass)
}
}
}
}
if
(
val
==
NULL_TREE
if
(
val
==
NULL_TREE
&&
CLASSTYPE_LOCAL_TYPEDECLS
(
got_sco
pe
))
&&
CLASSTYPE_LOCAL_TYPEDECLS
(
ty
pe
))
val
=
lookup_field
(
got_sco
pe
,
name
,
0
,
1
);
val
=
lookup_field
(
ty
pe
,
name
,
0
,
1
);
}
}
else
if
(
got_sco
pe
==
current_class_type
)
else
if
(
ty
pe
==
current_class_type
)
val
=
IDENTIFIER_CLASS_VALUE
(
name
);
val
=
IDENTIFIER_CLASS_VALUE
(
name
);
else
else
val
=
lookup_field
(
got_scope
,
name
,
0
,
0
);
val
=
lookup_field
(
type
,
name
,
0
,
prefer_type
);
goto
done
;
}
}
else
val
=
NULL_TREE
;
if
(
got_scope
)
goto
done
;
/* This special lookup only applies to types. */
else
if
(
got_object
&&
val
&&
TREE_CODE
(
val
)
==
TYPE_DECL
)
from_obj
=
val
;
}
}
if
(
current_binding_level
!=
global_binding_level
if
(
current_binding_level
!=
global_binding_level
...
@@ -3980,16 +4050,20 @@ lookup_name_real (name, prefer_type, nonclass)
...
@@ -3980,16 +4050,20 @@ lookup_name_real (name, prefer_type, nonclass)
done
:
done
:
if
(
val
)
if
(
val
)
{
{
if
(
from_obj
&&
from_obj
!=
val
)
cp_error
(
"lookup in the scope of `%#T' does not match lookup in the current scope"
,
got_object
);
if
((
TREE_CODE
(
val
)
==
TEMPLATE_DECL
&&
looking_for_template
)
if
((
TREE_CODE
(
val
)
==
TEMPLATE_DECL
&&
looking_for_template
)
||
TREE_CODE
(
val
)
==
TYPE_DECL
||
prefer_type
<=
0
)
||
TREE_CODE
(
val
)
==
TYPE_DECL
||
prefer_type
<=
0
)
return
val
;
;
else
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
if
(
IDENTIFIER_HAS_TYPE_VALUE
(
name
))
val
=
TYPE_NAME
(
IDENTIFIER_TYPE_VALUE
(
name
));
return
TYPE_NAME
(
IDENTIFIER_TYPE_VALUE
(
name
));
else
if
(
TREE_TYPE
(
val
)
==
error_mark_node
)
val
=
error_mark_node
;
if
(
TREE_TYPE
(
val
)
==
error_mark_node
)
return
error_mark_node
;
}
}
else
if
(
from_obj
)
val
=
from_obj
;
return
val
;
return
val
;
}
}
...
@@ -4031,7 +4105,7 @@ lookup_name_current_level (name)
...
@@ -4031,7 +4105,7 @@ lookup_name_current_level (name)
while
(
1
)
while
(
1
)
{
{
for
(
t
=
b
->
names
;
t
;
t
=
TREE_CHAIN
(
t
))
for
(
t
=
b
->
names
;
t
;
t
=
TREE_CHAIN
(
t
))
if
(
DECL_NAME
(
t
)
==
name
)
if
(
DECL_NAME
(
t
)
==
name
||
DECL_ASSEMBLER_NAME
(
t
)
==
name
)
goto
out
;
goto
out
;
if
(
b
->
keep
==
2
)
if
(
b
->
keep
==
2
)
b
=
b
->
level_chain
;
b
=
b
->
level_chain
;
...
@@ -4207,13 +4281,19 @@ init_decl_processing ()
...
@@ -4207,13 +4281,19 @@ init_decl_processing ()
int
wchar_type_size
;
int
wchar_type_size
;
tree
temp
;
tree
temp
;
tree
array_domain_type
;
tree
array_domain_type
;
extern
int
flag_strict_prototype
;
/* Have to make these distinct before we try using them. */
/* Have to make these distinct before we try using them. */
lang_name_cplusplus
=
get_identifier
(
"C++"
);
lang_name_cplusplus
=
get_identifier
(
"C++"
);
lang_name_c
=
get_identifier
(
"C"
);
lang_name_c
=
get_identifier
(
"C"
);
if
(
flag_ansi
||
pedantic
)
if
(
flag_strict_prototype
==
2
)
strict_prototypes_lang_c
=
strict_prototypes_lang_cplusplus
;
{
if
(
pedantic
)
strict_prototypes_lang_c
=
strict_prototypes_lang_cplusplus
;
}
else
strict_prototypes_lang_c
=
flag_strict_prototype
;
/* Initially, C. */
/* Initially, C. */
current_lang_name
=
lang_name_c
;
current_lang_name
=
lang_name_c
;
...
@@ -5629,8 +5709,9 @@ grok_reference_init (decl, type, init, cleanupp)
...
@@ -5629,8 +5709,9 @@ grok_reference_init (decl, type, init, cleanupp)
if
(
init
==
NULL_TREE
)
if
(
init
==
NULL_TREE
)
{
{
if
(
DECL_LANG_SPECIFIC
(
decl
)
==
0
if
((
DECL_LANG_SPECIFIC
(
decl
)
==
0
||
DECL_IN_AGGR_P
(
decl
)
==
0
)
||
DECL_IN_AGGR_P
(
decl
)
==
0
)
&&
!
DECL_THIS_EXTERN
(
decl
))
{
{
cp_error
(
"`%D' declared as reference but not initialized"
,
decl
);
cp_error
(
"`%D' declared as reference but not initialized"
,
decl
);
if
(
TREE_CODE
(
decl
)
==
VAR_DECL
)
if
(
TREE_CODE
(
decl
)
==
VAR_DECL
)
...
@@ -6530,12 +6611,24 @@ complete_array_type (type, initial_value, do_default)
...
@@ -6530,12 +6611,24 @@ complete_array_type (type, initial_value, do_default)
/* Note MAXINDEX is really the maximum index,
/* Note MAXINDEX is really the maximum index,
one less than the size. */
one less than the size. */
if
(
TREE_CODE
(
initial_value
)
==
STRING_CST
)
if
(
TREE_CODE
(
initial_value
)
==
STRING_CST
)
maxindex
=
build_int_2
(
TREE_STRING_LENGTH
(
initial_value
)
-
1
,
0
);
{
int
eltsize
=
int_size_in_bytes
(
TREE_TYPE
(
TREE_TYPE
(
initial_value
)));
maxindex
=
build_int_2
((
TREE_STRING_LENGTH
(
initial_value
)
/
eltsize
)
-
1
,
0
);
}
else
if
(
TREE_CODE
(
initial_value
)
==
CONSTRUCTOR
)
else
if
(
TREE_CODE
(
initial_value
)
==
CONSTRUCTOR
)
{
{
register
int
nelts
tree
elts
=
CONSTRUCTOR_ELTS
(
initial_value
);
=
list_length
(
CONSTRUCTOR_ELTS
(
initial_value
));
maxindex
=
size_binop
(
MINUS_EXPR
,
integer_zero_node
,
size_one_node
);
maxindex
=
build_int_2
(
nelts
-
1
,
-
(
nelts
==
0
));
for
(;
elts
;
elts
=
TREE_CHAIN
(
elts
))
{
if
(
TREE_PURPOSE
(
elts
))
maxindex
=
TREE_PURPOSE
(
elts
);
else
maxindex
=
size_binop
(
PLUS_EXPR
,
maxindex
,
size_one_node
);
}
maxindex
=
copy_node
(
maxindex
);
}
}
else
else
{
{
...
@@ -7281,6 +7374,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7281,6 +7374,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
funcdef_flag
&&
innermost_code
!=
CALL_EXPR
)
if
(
funcdef_flag
&&
innermost_code
!=
CALL_EXPR
)
return
0
;
return
0
;
if
(((
dname
&&
IDENTIFIER_OPNAME_P
(
dname
))
||
flags
==
TYPENAME_FLAG
)
&&
innermost_code
!=
CALL_EXPR
&&
!
(
ctype
&&
declspecs
==
NULL_TREE
))
{
cp_error
(
"declaration of `%D' as non-function"
,
dname
);
return
void_type_node
;
}
/* Anything declared one level down from the top level
/* Anything declared one level down from the top level
must be one of the parameters of a function
must be one of the parameters of a function
(because the body is at least two levels down). */
(because the body is at least two levels down). */
...
@@ -7361,8 +7462,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7361,8 +7462,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
{
{
if
(
i
==
(
int
)
RID_LONG
&&
RIDBIT_SETP
(
i
,
specbits
))
if
(
i
==
(
int
)
RID_LONG
&&
RIDBIT_SETP
(
i
,
specbits
))
{
{
if
(
pedantic
&&
flag_ansi
)
if
(
pedantic
&&
!
in_system_header
)
pedwarn
(
"
duplicate `
long'"
);
pedwarn
(
"
ANSI C++ does not support `long
long'"
);
else
if
(
longlong
)
else
if
(
longlong
)
error
(
"`long long long' is too long for GCC"
);
error
(
"`long long long' is too long for GCC"
);
else
else
...
@@ -7468,7 +7569,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -7468,7 +7569,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
}
else
if
(
return_type
==
return_conversion
)
else
if
(
return_type
==
return_conversion
)
{
{
if
(
comp
_target_
types
(
type
,
ctor_return_type
,
1
)
==
0
)
if
(
comptypes
(
type
,
ctor_return_type
,
1
)
==
0
)
cp_error
(
"operator `%T' declared to return `%T'"
,
cp_error
(
"operator `%T' declared to return `%T'"
,
ctor_return_type
,
type
);
ctor_return_type
,
type
);
else
else
...
@@ -8022,7 +8123,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8022,7 +8123,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
}
if
(
TREE_READONLY_DECL_P
(
size
))
if
(
TREE_READONLY_DECL_P
(
size
))
size
=
decl_constant_value
(
size
);
size
=
decl_constant_value
(
size
);
if
(
flag_ansi
&&
integer_zerop
(
size
))
if
(
pedantic
&&
integer_zerop
(
size
))
cp_pedwarn
(
"ANSI C++ forbids zero-size array `%D'"
,
dname
);
cp_pedwarn
(
"ANSI C++ forbids zero-size array `%D'"
,
dname
);
if
(
TREE_CONSTANT
(
size
))
if
(
TREE_CONSTANT
(
size
))
{
{
...
@@ -8037,7 +8138,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8037,7 +8138,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
}
else
else
{
{
if
(
flag_ansi
)
if
(
pedantic
)
{
{
if
(
dname
)
if
(
dname
)
cp_pedwarn
(
"ANSI C++ forbids variable-size array `%D'"
,
cp_pedwarn
(
"ANSI C++ forbids variable-size array `%D'"
,
...
@@ -8384,9 +8485,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8384,9 +8485,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
&&
(
constp
||
volatilep
))
&&
(
constp
||
volatilep
))
{
{
if
(
constp
)
if
(
constp
)
warning
(
"discarding `const' applied to a reference"
);
pedwarn
(
"discarding `const' applied to a reference"
);
if
(
volatilep
)
if
(
volatilep
)
warning
(
"discarding `volatile' applied to a reference"
);
pedwarn
(
"discarding `volatile' applied to a reference"
);
constp
=
volatilep
=
0
;
constp
=
volatilep
=
0
;
}
}
}
}
...
@@ -8956,7 +9057,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -8956,7 +9057,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
initialize the named nonstatic member.... This (or an
initialize the named nonstatic member.... This (or an
initializer list) is the only way to initialize
initializer list) is the only way to initialize
nonstatic const and reference members. */
nonstatic const and reference members. */
else
if
(
flag_ansi
||
!
constp
)
else
if
(
pedantic
||
!
constp
)
cp_pedwarn
(
"ANSI C++ forbids initialization of %s `%D'"
,
cp_pedwarn
(
"ANSI C++ forbids initialization of %s `%D'"
,
constp
?
"const member"
:
"member"
,
declarator
);
constp
?
"const member"
:
"member"
,
declarator
);
}
}
...
@@ -9103,7 +9204,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
...
@@ -9103,7 +9204,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
RIDBIT_SETP
(
RID_EXTERN
,
specbits
))
if
(
RIDBIT_SETP
(
RID_EXTERN
,
specbits
))
{
{
current_extern_inline
=
1
;
current_extern_inline
=
1
;
if
(
flag_ansi
)
if
(
pedantic
)
pedwarn
(
"ANSI C++ does not permit `extern inline'"
);
pedwarn
(
"ANSI C++ does not permit `extern inline'"
);
}
}
}
}
...
@@ -9450,12 +9551,19 @@ grokparms (first_parm, funcdef_flag)
...
@@ -9450,12 +9551,19 @@ grokparms (first_parm, funcdef_flag)
}
}
else
else
init
=
require_instantiated_type
(
type
,
init
,
integer_zero_node
);
init
=
require_instantiated_type
(
type
,
init
,
integer_zero_node
);
init
=
convert_for_initialization
(
NULL_TREE
,
type
,
init
,
LOOKUP_NORMAL
,
"argument passing"
,
0
,
0
);
}
}
#if 0 /* This is too early to check; trailing parms might be merged in by
duplicate_decls. */
else if (any_init)
else if (any_init)
{
{
error ("all trailing parameters must have default arguments");
error ("all trailing parameters must have default arguments");
any_error = 1;
any_error = 1;
}
}
#endif
}
}
else
else
init
=
NULL_TREE
;
init
=
NULL_TREE
;
...
@@ -11042,7 +11150,7 @@ store_return_init (return_id, init)
...
@@ -11042,7 +11150,7 @@ store_return_init (return_id, init)
{
{
tree
decl
=
DECL_RESULT
(
current_function_decl
);
tree
decl
=
DECL_RESULT
(
current_function_decl
);
if
(
flag_ansi
)
if
(
pedantic
)
/* Give this error as many times as there are occurrences,
/* Give this error as many times as there are occurrences,
so that users can use Emacs compilation buffers to find
so that users can use Emacs compilation buffers to find
and fix all such places. */
and fix all such places. */
...
@@ -11539,45 +11647,11 @@ finish_function (lineno, call_poplevel, nested)
...
@@ -11539,45 +11647,11 @@ finish_function (lineno, call_poplevel, nested)
/* So we can tell if jump_optimize sets it to 1. */
/* So we can tell if jump_optimize sets it to 1. */
can_reach_end
=
0
;
can_reach_end
=
0
;
if
(
DECL_EXTERNAL
(
fndecl
)
/* Run the optimizers and output the assembler code for this function. */
/* This function is just along for the ride. If we can make
rest_of_compilation
(
fndecl
);
it inline, that's great. Otherwise, just punt it. */
&&
(
DECL_INLINE
(
fndecl
)
==
0
||
flag_no_inline
||
function_cannot_inline_p
(
fndecl
)
/* ??? Compensate for Sun brain damage in dealing with
data segments of PIC code. */
||
(
flag_pic
&&
(
DECL_CONSTRUCTOR_P
(
fndecl
)
||
DESTRUCTOR_NAME_P
(
DECL_ASSEMBLER_NAME
(
fndecl
)))
&&
CLASSTYPE_NEEDS_VIRTUAL_REINIT
(
TYPE_METHOD_BASETYPE
(
fntype
)))))
{
extern
int
rtl_dump_and_exit
;
int
old_rtl_dump_and_exit
=
rtl_dump_and_exit
;
int
inline_spec
=
DECL_INLINE
(
fndecl
);
/* This throws away the code for FNDECL. */
rtl_dump_and_exit
=
1
;
/* This throws away the memory of the code for FNDECL. */
if
(
flag_no_inline
)
DECL_INLINE
(
fndecl
)
=
0
;
rest_of_compilation
(
fndecl
);
rtl_dump_and_exit
=
old_rtl_dump_and_exit
;
DECL_INLINE
(
fndecl
)
=
inline_spec
;
}
else
{
/* Run the optimizers and output the assembler code for this
function. */
rest_of_compilation
(
fndecl
);
}
if
(
DECL_INLINE
(
fndecl
)
&&
!
TREE_ASM_WRITTEN
(
fndecl
)
if
(
DECL_DEFER_OUTPUT
(
fndecl
))
&&
DECL_DEFER_OUTPUT
(
fndecl
))
mark_inline_for_output
(
fndecl
);
{
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
);
...
@@ -11628,6 +11702,11 @@ finish_function (lineno, call_poplevel, nested)
...
@@ -11628,6 +11702,11 @@ finish_function (lineno, call_poplevel, nested)
DECL_ARGUMENTS
(
fndecl
)
=
NULL_TREE
;
DECL_ARGUMENTS
(
fndecl
)
=
NULL_TREE
;
}
}
if
(
DECL_STATIC_CONSTRUCTOR
(
fndecl
))
static_ctors
=
perm_tree_cons
(
NULL_TREE
,
fndecl
,
static_ctors
);
if
(
DECL_STATIC_DESTRUCTOR
(
fndecl
))
static_dtors
=
perm_tree_cons
(
NULL_TREE
,
fndecl
,
static_dtors
);
/* Let the error reporting routines know that we're outside a function. */
/* Let the error reporting routines know that we're outside a function. */
current_function_decl
=
NULL_TREE
;
current_function_decl
=
NULL_TREE
;
named_label_uses
=
NULL_TREE
;
named_label_uses
=
NULL_TREE
;
...
...
gcc/cp/decl2.c
View file @
e1cd6e56
...
@@ -64,6 +64,10 @@ static int global_temp_name_counter;
...
@@ -64,6 +64,10 @@ static int global_temp_name_counter;
/* Flag used when debugging spew.c */
/* Flag used when debugging spew.c */
extern
int
spew_debug
;
extern
int
spew_debug
;
/* Functions called along with real static constructors and destructors. */
tree
static_ctors
,
static_dtors
;
/* C (and C++) language-specific option variables. */
/* C (and C++) language-specific option variables. */
...
@@ -80,6 +84,10 @@ int flag_short_double;
...
@@ -80,6 +84,10 @@ int flag_short_double;
int
flag_no_asm
;
int
flag_no_asm
;
/* Nonzero means don't recognize any extension keywords. */
int
flag_no_gnu_keywords
;
/* Nonzero means don't recognize the non-ANSI builtin functions. */
/* Nonzero means don't recognize the non-ANSI builtin functions. */
int
flag_no_builtin
;
int
flag_no_builtin
;
...
@@ -99,11 +107,12 @@ int flag_signed_bitfields = 1;
...
@@ -99,11 +107,12 @@ int flag_signed_bitfields = 1;
/* Nonzero means handle `#ident' directives. 0 means ignore them. */
/* Nonzero means handle `#ident' directives. 0 means ignore them. */
int
flag_no_ident
=
0
;
int
flag_no_ident
;
/* Nonzero means disable GNU extensions. */
/* Nonzero means enable obscure ANSI features and disable GNU extensions
that might cause ANSI-compliant code to be miscompiled. */
int
flag_ansi
=
0
;
int
flag_ansi
;
/* Nonzero means do emit exported implementations of functions even if
/* Nonzero means do emit exported implementations of functions even if
they can be inlined. */
they can be inlined. */
...
@@ -113,13 +122,13 @@ int flag_implement_inlines = 1;
...
@@ -113,13 +122,13 @@ int flag_implement_inlines = 1;
/* Nonzero means do emit exported implementations of templates, instead of
/* Nonzero means do emit exported implementations of templates, instead of
multiple static copies in each file that needs a definition. */
multiple static copies in each file that needs a definition. */
int
flag_external_templates
=
0
;
int
flag_external_templates
;
/* Nonzero means that the decision to emit or not emit the implementation of a
/* Nonzero means that the decision to emit or not emit the implementation of a
template depends on where the template is instantiated, rather than where
template depends on where the template is instantiated, rather than where
it is defined. */
it is defined. */
int
flag_alt_external_templates
=
0
;
int
flag_alt_external_templates
;
/* Nonzero means that implicit instantiations will be emitted if needed. */
/* Nonzero means that implicit instantiations will be emitted if needed. */
...
@@ -139,7 +148,7 @@ int warn_ctor_dtor_privacy = 1;
...
@@ -139,7 +148,7 @@ int warn_ctor_dtor_privacy = 1;
Also causes output of vtables to be controlled by whether
Also causes output of vtables to be controlled by whether
we seen the class's first non-inline virtual function. */
we seen the class's first non-inline virtual function. */
int
flag_vtable_thunks
=
0
;
int
flag_vtable_thunks
;
/* Nonzero means give string constants the type `const char *'
/* Nonzero means give string constants the type `const char *'
to get extra warnings from them. These warnings will be too numerous
to get extra warnings from them. These warnings will be too numerous
...
@@ -198,7 +207,7 @@ int warn_conversion;
...
@@ -198,7 +207,7 @@ int warn_conversion;
/* Warn if adding () is suggested. */
/* Warn if adding () is suggested. */
int
warn_parentheses
=
1
;
int
warn_parentheses
;
/* Non-zero means warn in function declared in derived class has the
/* Non-zero means warn in function declared in derived class has the
same name as a virtual in the base class, but fails to match the
same name as a virtual in the base class, but fails to match the
...
@@ -229,6 +238,7 @@ int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
...
@@ -229,6 +238,7 @@ int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
/* Nonzero for -fno-strict-prototype switch: do not consider empty
/* Nonzero for -fno-strict-prototype switch: do not consider empty
argument prototype to mean function takes no arguments. */
argument prototype to mean function takes no arguments. */
int
flag_strict_prototype
=
2
;
int
strict_prototype
=
1
;
int
strict_prototype
=
1
;
int
strict_prototypes_lang_c
,
strict_prototypes_lang_cplusplus
=
1
;
int
strict_prototypes_lang_c
,
strict_prototypes_lang_cplusplus
=
1
;
...
@@ -303,7 +313,7 @@ int flag_gc;
...
@@ -303,7 +313,7 @@ int flag_gc;
/* Controls whether compiler generates 'type descriptor' that give
/* Controls whether compiler generates 'type descriptor' that give
run-time type information. */
run-time type information. */
int
flag_rtti
=
0
;
int
flag_rtti
;
/* Nonzero if we wish to output cross-referencing information
/* Nonzero if we wish to output cross-referencing information
for the GNU class browser. */
for the GNU class browser. */
...
@@ -319,21 +329,28 @@ extern int flag_gnu_xref;
...
@@ -319,21 +329,28 @@ extern int flag_gnu_xref;
In general, it is `reasonable' to assume that for many programs,
In general, it is `reasonable' to assume that for many programs,
and better code can be generated in that case. */
and better code can be generated in that case. */
int
flag_assume_nonnull_objects
;
int
flag_assume_nonnull_objects
=
1
;
/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
objects. */
objects. */
int
flag_huge_objects
;
int
flag_huge_objects
;
/* Nonzero if we want to conserve space in the .o files. We do this
/* Nonzero if we want to conserve space in the .o files. We do this
by putting uninitialized data and runtime initialized data into
by putting uninitialized data and runtime initialized data into
.common instead of .data at the expense of not flaging multiple
.common instead of .data at the expense of not flaging multiple
definitions. */
definitions. */
int
flag_conserve_space
;
int
flag_conserve_space
;
/* Nonzero if we want to obey access control semantics. */
/* Nonzero if we want to obey access control semantics. */
int
flag_access_control
=
1
;
int
flag_access_control
=
1
;
/* Nonzero if we want to understand the operator names, i.e. 'bitand'. */
int
flag_operator_names
;
/* Table of language-dependent -f options.
/* Table of language-dependent -f options.
STRING is the option name. VARIABLE is the address of the variable.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
ON_VALUE is the value to store in VARIABLE
...
@@ -355,7 +372,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
...
@@ -355,7 +372,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{
"labels-ok"
,
&
flag_labels_ok
,
1
},
{
"labels-ok"
,
&
flag_labels_ok
,
1
},
{
"stats"
,
&
flag_detailed_statistics
,
1
},
{
"stats"
,
&
flag_detailed_statistics
,
1
},
{
"this-is-variable"
,
&
flag_this_is_variable
,
1
},
{
"this-is-variable"
,
&
flag_this_is_variable
,
1
},
{
"strict-prototype"
,
&
strict_prototypes_lang_cplusplus
,
1
},
{
"strict-prototype"
,
&
flag_strict_prototype
,
1
},
{
"all-virtual"
,
&
flag_all_virtual
,
1
},
{
"all-virtual"
,
&
flag_all_virtual
,
1
},
{
"memoize-lookups"
,
&
flag_memoize_lookups
,
1
},
{
"memoize-lookups"
,
&
flag_memoize_lookups
,
1
},
{
"elide-constructors"
,
&
flag_elide_constructors
,
1
},
{
"elide-constructors"
,
&
flag_elide_constructors
,
1
},
...
@@ -376,7 +393,9 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
...
@@ -376,7 +393,9 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{
"vtable-thunks"
,
&
flag_vtable_thunks
,
1
},
{
"vtable-thunks"
,
&
flag_vtable_thunks
,
1
},
{
"short-temps"
,
&
flag_short_temps
,
1
},
{
"short-temps"
,
&
flag_short_temps
,
1
},
{
"access-control"
,
&
flag_access_control
,
1
},
{
"access-control"
,
&
flag_access_control
,
1
},
{
"nonansi-builtins"
,
&
flag_no_nonansi_builtin
,
0
}
{
"nonansi-builtins"
,
&
flag_no_nonansi_builtin
,
0
},
{
"gnu-keywords"
,
&
flag_no_gnu_keywords
,
0
},
{
"operator-names"
,
&
flag_operator_names
,
1
}
};
};
/* Decode the string P as a language-specific option.
/* Decode the string P as a language-specific option.
...
@@ -552,6 +571,7 @@ lang_decode_option (p)
...
@@ -552,6 +571,7 @@ lang_decode_option (p)
warn_ctor_dtor_privacy
=
setting
;
warn_ctor_dtor_privacy
=
setting
;
warn_switch
=
setting
;
warn_switch
=
setting
;
warn_format
=
setting
;
warn_format
=
setting
;
warn_parentheses
=
setting
;
warn_missing_braces
=
setting
;
warn_missing_braces
=
setting
;
warn_extern_inline
=
setting
;
warn_extern_inline
=
setting
;
warn_nonvdtor
=
setting
;
warn_nonvdtor
=
setting
;
...
@@ -569,8 +589,8 @@ lang_decode_option (p)
...
@@ -569,8 +589,8 @@ lang_decode_option (p)
else
return
0
;
else
return
0
;
}
}
else
if
(
!
strcmp
(
p
,
"-ansi"
))
else
if
(
!
strcmp
(
p
,
"-ansi"
))
flag_no_asm
=
1
,
dollars_in_ident
=
0
,
flag_no_nonansi_builtin
=
1
,
dollars_in_ident
=
0
,
flag_no_nonansi_builtin
=
1
,
flag_ansi
=
1
,
flag_
ansi
=
1
;
flag_
no_gnu_keywords
=
1
,
flag_operator_names
=
1
;
#ifdef SPEW_DEBUG
#ifdef SPEW_DEBUG
/* Undocumented, only ever used when you're invoking cc1plus by hand, since
/* Undocumented, only ever used when you're invoking cc1plus by hand, since
it's probably safe to assume no sane person would ever want to use this
it's probably safe to assume no sane person would ever want to use this
...
@@ -2674,10 +2694,10 @@ finish_file ()
...
@@ -2674,10 +2694,10 @@ finish_file ()
we'll need here. */
we'll need here. */
push_lang_context
(
lang_name_c
);
push_lang_context
(
lang_name_c
);
/* Set up the name of the file-level functions we may need. */
if
(
static_ctors
||
vars
||
have_exception_handlers
)
/* Use a global object (which is already required to be unique over
needs_messing_up
=
1
;
the program) rather than the file name (which imposes extra
if
(
static_dtors
)
constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */
needs_cleaning
=
1
;
/* See if we really need the hassle. */
/* See if we really need the hassle. */
while
(
vars
&&
needs_cleaning
==
0
)
while
(
vars
&&
needs_cleaning
==
0
)
...
@@ -2740,6 +2760,10 @@ finish_file ()
...
@@ -2740,6 +2760,10 @@ finish_file ()
vars
=
TREE_CHAIN
(
vars
);
vars
=
TREE_CHAIN
(
vars
);
}
}
for
(;
static_dtors
;
static_dtors
=
TREE_CHAIN
(
static_dtors
))
expand_expr_stmt
(
build_function_call
(
TREE_VALUE
(
static_dtors
),
NULL_TREE
));
expand_end_bindings
(
getdecls
(),
1
,
0
);
expand_end_bindings
(
getdecls
(),
1
,
0
);
poplevel
(
1
,
0
,
0
);
poplevel
(
1
,
0
,
0
);
pop_momentary
();
pop_momentary
();
...
@@ -2753,7 +2777,7 @@ finish_file ()
...
@@ -2753,7 +2777,7 @@ finish_file ()
mess_up:
mess_up:
/* Must do this while we think we are at the top level. */
/* Must do this while we think we are at the top level. */
vars
=
nreverse
(
static_aggregates
);
vars
=
nreverse
(
static_aggregates
);
if
(
vars
!=
NULL_TREE
||
have_exception_handlers
)
if
(
needs_messing_up
)
{
{
fnname
=
get_file_function_name
(
'I'
);
fnname
=
get_file_function_name
(
'I'
);
start_function
(
void_list_node
,
build_parse_node
(
CALL_EXPR
,
fnname
,
void_list_node
,
NULL_TREE
),
0
,
0
);
start_function
(
void_list_node
,
build_parse_node
(
CALL_EXPR
,
fnname
,
void_list_node
,
NULL_TREE
),
0
,
0
);
...
@@ -2797,6 +2821,7 @@ finish_file ()
...
@@ -2797,6 +2821,7 @@ finish_file ()
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
);
#if 0
if (init)
if (init)
{
{
if (TREE_CODE (init) == VAR_DECL)
if (TREE_CODE (init) == VAR_DECL)
...
@@ -2815,7 +2840,6 @@ finish_file ()
...
@@ -2815,7 +2840,6 @@ finish_file ()
&& CONSTRUCTOR_ELTS (init) == NULL_TREE)
&& CONSTRUCTOR_ELTS (init) == NULL_TREE)
init = NULL_TREE;
init = NULL_TREE;
}
}
#if 0
else if (TREE_TYPE (decl) == TREE_TYPE (init))
else if (TREE_TYPE (decl) == TREE_TYPE (init))
{
{
#if 1
#if 1
...
@@ -2828,9 +2852,9 @@ finish_file ()
...
@@ -2828,9 +2852,9 @@ finish_file ()
init = DECL_INITIAL (init);
init = DECL_INITIAL (init);
#endif /* 1 */
#endif /* 1 */
}
}
#endif
/* 0 */
}
}
}
}
#endif
/* 0 */
if
(
IS_AGGR_TYPE
(
TREE_TYPE
(
decl
))
if
(
IS_AGGR_TYPE
(
TREE_TYPE
(
decl
))
||
TREE_CODE
(
TREE_TYPE
(
decl
))
==
ARRAY_TYPE
)
||
TREE_CODE
(
TREE_TYPE
(
decl
))
==
ARRAY_TYPE
)
expand_aggr_init
(
decl
,
init
,
0
,
0
);
expand_aggr_init
(
decl
,
init
,
0
,
0
);
...
@@ -2865,6 +2889,10 @@ finish_file ()
...
@@ -2865,6 +2889,10 @@ finish_file ()
expand_cleanups_to
(
old_cleanups
);
expand_cleanups_to
(
old_cleanups
);
}
}
for
(;
static_ctors
;
static_ctors
=
TREE_CHAIN
(
static_ctors
))
expand_expr_stmt
(
build_function_call
(
TREE_VALUE
(
static_ctors
),
NULL_TREE
));
expand_end_bindings
(
getdecls
(),
1
,
0
);
expand_end_bindings
(
getdecls
(),
1
,
0
);
poplevel
(
1
,
0
,
0
);
poplevel
(
1
,
0
,
0
);
pop_momentary
();
pop_momentary
();
...
...
gcc/cp/except.c
View file @
e1cd6e56
...
@@ -43,7 +43,12 @@ tree builtin_return_address_fndecl;
...
@@ -43,7 +43,12 @@ tree builtin_return_address_fndecl;
#define TRY_NEW_EH
#define TRY_NEW_EH
#endif
#endif
#endif
#endif
#if defined(__i386) || defined(__rs6000) || defined(__hppa) || defined(__mc68000) || defined (__mips)
#ifdef _IBMR2
#ifndef __rs6000
#define __rs6000
#endif
#endif
#if defined(__i386) || defined(__rs6000) || defined(__hppa) || defined(__mc68000) || defined (__mips) || defined (__arm)
#define TRY_NEW_EH
#define TRY_NEW_EH
#endif
#endif
#endif
#endif
...
@@ -123,6 +128,16 @@ expand_throw (exp)
...
@@ -123,6 +128,16 @@ expand_throw (exp)
#else
#else
/* Make 'label' the first numbered label of the current function */
void
make_first_label
(
label
)
rtx
label
;
{
if
(
CODE_LABEL_NUMBER
(
label
)
<
get_first_label_num
())
set_new_first_and_last_label_num
(
CODE_LABEL_NUMBER
(
label
),
max_label_num
());
}
static
int
static
int
doing_eh
(
do_warn
)
doing_eh
(
do_warn
)
int
do_warn
;
int
do_warn
;
...
@@ -236,9 +251,16 @@ void
...
@@ -236,9 +251,16 @@ void
exception_section
()
exception_section
()
{
{
#ifdef ASM_OUTPUT_SECTION_NAME
#ifdef ASM_OUTPUT_SECTION_NAME
named_section
(
".gcc_except_table"
);
named_section
(
NULL_TREE
,
".gcc_except_table"
);
#else
if
(
flag_pic
)
data_section
();
else
#if defined(__rs6000)
data_section
();
#else
#else
text_section
();
readonly_data_section
();
#endif
#endif
#endif
}
}
...
@@ -576,6 +598,10 @@ push_eh_entry (stack)
...
@@ -576,6 +598,10 @@ push_eh_entry (stack)
entry
->
exception_handler_label
=
gen_label_rtx
();
entry
->
exception_handler_label
=
gen_label_rtx
();
pop_rtl_from_perm
();
pop_rtl_from_perm
();
LABEL_PRESERVE_P
(
entry
->
start_label
)
=
1
;
LABEL_PRESERVE_P
(
entry
->
end_label
)
=
1
;
LABEL_PRESERVE_P
(
entry
->
exception_handler_label
)
=
1
;
entry
->
finalization
=
NULL_TREE
;
entry
->
finalization
=
NULL_TREE
;
node
->
entry
=
entry
;
node
->
entry
=
entry
;
...
@@ -794,9 +820,9 @@ init_exception_processing ()
...
@@ -794,9 +820,9 @@ init_exception_processing ()
saved_throw_value
=
gen_rtx
(
REG
,
Pmode
,
5
);
saved_throw_value
=
gen_rtx
(
REG
,
Pmode
,
5
);
#endif
#endif
#ifdef __rs6000
#ifdef __rs6000
saved_pc
=
gen_rtx
(
REG
,
Pmode
,
1
2
);
saved_pc
=
gen_rtx
(
REG
,
Pmode
,
1
3
);
saved_throw_type
=
gen_rtx
(
REG
,
Pmode
,
1
3
);
saved_throw_type
=
gen_rtx
(
REG
,
Pmode
,
1
4
);
saved_throw_value
=
gen_rtx
(
REG
,
Pmode
,
1
4
);
saved_throw_value
=
gen_rtx
(
REG
,
Pmode
,
1
5
);
#endif
#endif
#ifdef __hppa
#ifdef __hppa
saved_pc
=
gen_rtx
(
REG
,
Pmode
,
5
);
saved_pc
=
gen_rtx
(
REG
,
Pmode
,
5
);
...
@@ -813,6 +839,11 @@ init_exception_processing ()
...
@@ -813,6 +839,11 @@ init_exception_processing ()
saved_throw_type
=
gen_rtx
(
REG
,
Pmode
,
17
);
saved_throw_type
=
gen_rtx
(
REG
,
Pmode
,
17
);
saved_throw_value
=
gen_rtx
(
REG
,
Pmode
,
18
);
saved_throw_value
=
gen_rtx
(
REG
,
Pmode
,
18
);
#endif
#endif
#ifdef __arm
saved_pc
=
gen_rtx
(
REG
,
Pmode
,
7
);
saved_throw_type
=
gen_rtx
(
REG
,
Pmode
,
8
);
saved_throw_value
=
gen_rtx
(
REG
,
Pmode
,
9
);
#endif
new_eh_queue
(
&
ehqueue
);
new_eh_queue
(
&
ehqueue
);
new_eh_queue
(
&
eh_table_output_queue
);
new_eh_queue
(
&
eh_table_output_queue
);
new_eh_stack
(
&
ehstack
);
new_eh_stack
(
&
ehstack
);
...
@@ -958,7 +989,13 @@ expand_start_all_catch ()
...
@@ -958,7 +989,13 @@ expand_start_all_catch ()
entry
->
end_label
=
gen_label_rtx
();
entry
->
end_label
=
gen_label_rtx
();
entry
->
exception_handler_label
=
gen_label_rtx
();
entry
->
exception_handler_label
=
gen_label_rtx
();
entry
->
finalization
=
TerminateFunctionCall
;
entry
->
finalization
=
TerminateFunctionCall
;
assemble_external
(
TREE_OPERAND
(
Terminate
,
0
));
pop_rtl_from_perm
();
pop_rtl_from_perm
();
LABEL_PRESERVE_P
(
entry
->
start_label
)
=
1
;
LABEL_PRESERVE_P
(
entry
->
end_label
)
=
1
;
LABEL_PRESERVE_P
(
entry
->
exception_handler_label
)
=
1
;
emit_label
(
entry
->
end_label
);
emit_label
(
entry
->
end_label
);
enqueue_eh_entry
(
&
eh_table_output_queue
,
copy_eh_entry
(
entry
));
enqueue_eh_entry
(
&
eh_table_output_queue
,
copy_eh_entry
(
entry
));
...
@@ -969,6 +1006,7 @@ expand_start_all_catch ()
...
@@ -969,6 +1006,7 @@ expand_start_all_catch ()
/* Will this help us not stomp on it? */
/* Will this help us not stomp on it? */
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
saved_throw_type
));
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
saved_throw_type
));
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
saved_throw_value
));
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
saved_throw_value
));
make_first_label
(
throw_label
);
emit_jump
(
throw_label
);
emit_jump
(
throw_label
);
emit_label
(
entry
->
exception_handler_label
);
emit_label
(
entry
->
exception_handler_label
);
expand_expr
(
entry
->
finalization
,
const0_rtx
,
VOIDmode
,
0
);
expand_expr
(
entry
->
finalization
,
const0_rtx
,
VOIDmode
,
0
);
...
@@ -992,6 +1030,7 @@ expand_end_all_catch ()
...
@@ -992,6 +1030,7 @@ expand_end_all_catch ()
emit_move_insn
(
saved_pc
,
gen_rtx
(
LABEL_REF
,
emit_move_insn
(
saved_pc
,
gen_rtx
(
LABEL_REF
,
Pmode
,
Pmode
,
top_label_entry
(
&
caught_return_label_stack
)));
top_label_entry
(
&
caught_return_label_stack
)));
make_first_label
(
throw_label
);
emit_jump
(
throw_label
);
emit_jump
(
throw_label
);
/* Find the start of the catch block. */
/* Find the start of the catch block. */
...
@@ -1052,7 +1091,13 @@ expand_leftover_cleanups ()
...
@@ -1052,7 +1091,13 @@ expand_leftover_cleanups ()
entry
.
end_label
=
label
;
entry
.
end_label
=
label
;
entry
.
exception_handler_label
=
gen_label_rtx
();
entry
.
exception_handler_label
=
gen_label_rtx
();
entry
.
finalization
=
TerminateFunctionCall
;
entry
.
finalization
=
TerminateFunctionCall
;
assemble_external
(
TREE_OPERAND
(
Terminate
,
0
));
pop_rtl_from_perm
();
pop_rtl_from_perm
();
LABEL_PRESERVE_P
(
entry
.
start_label
)
=
1
;
LABEL_PRESERVE_P
(
entry
.
end_label
)
=
1
;
LABEL_PRESERVE_P
(
entry
.
exception_handler_label
)
=
1
;
emit_label
(
label
);
emit_label
(
label
);
enqueue_eh_entry
(
&
eh_table_output_queue
,
copy_eh_entry
(
&
entry
));
enqueue_eh_entry
(
&
eh_table_output_queue
,
copy_eh_entry
(
&
entry
));
...
@@ -1063,6 +1108,7 @@ expand_leftover_cleanups ()
...
@@ -1063,6 +1108,7 @@ expand_leftover_cleanups ()
/* Will this help us not stomp on it? */
/* Will this help us not stomp on it? */
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
saved_throw_type
));
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
saved_throw_type
));
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
saved_throw_value
));
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
saved_throw_value
));
make_first_label
(
throw_label
);
emit_jump
(
throw_label
);
emit_jump
(
throw_label
);
emit_label
(
entry
.
exception_handler_label
);
emit_label
(
entry
.
exception_handler_label
);
expand_expr
(
entry
.
finalization
,
const0_rtx
,
VOIDmode
,
0
);
expand_expr
(
entry
.
finalization
,
const0_rtx
,
VOIDmode
,
0
);
...
@@ -1143,6 +1189,7 @@ expand_start_catch_block (declspecs, declarator)
...
@@ -1143,6 +1189,7 @@ expand_start_catch_block (declspecs, declarator)
NULL_TREE
));
NULL_TREE
));
catch_match_fcall
=
build_function_call
(
CatchMatch
,
params
);
catch_match_fcall
=
build_function_call
(
CatchMatch
,
params
);
call_rtx
=
expand_call
(
catch_match_fcall
,
NULL_RTX
,
0
);
call_rtx
=
expand_call
(
catch_match_fcall
,
NULL_RTX
,
0
);
assemble_external
(
TREE_OPERAND
(
CatchMatch
,
0
));
return_value_rtx
=
return_value_rtx
=
hard_function_value
(
integer_type_node
,
catch_match_fcall
);
hard_function_value
(
integer_type_node
,
catch_match_fcall
);
...
@@ -1192,6 +1239,7 @@ void expand_end_catch_block ()
...
@@ -1192,6 +1239,7 @@ void expand_end_catch_block ()
emit_move_insn
(
saved_pc
,
gen_rtx
(
LABEL_REF
,
emit_move_insn
(
saved_pc
,
gen_rtx
(
LABEL_REF
,
Pmode
,
Pmode
,
top_label_entry
(
&
caught_return_label_stack
)));
top_label_entry
(
&
caught_return_label_stack
)));
make_first_label
(
throw_label
);
emit_jump
(
throw_label
);
emit_jump
(
throw_label
);
/* No associated finalization. */
/* No associated finalization. */
entry
.
finalization
=
NULL_TREE
;
entry
.
finalization
=
NULL_TREE
;
...
@@ -1210,6 +1258,10 @@ void expand_end_catch_block ()
...
@@ -1210,6 +1258,10 @@ void expand_end_catch_block ()
entry
.
start_label
=
start_protect_label_rtx
;
entry
.
start_label
=
start_protect_label_rtx
;
entry
.
end_label
=
end_protect_label_rtx
;
entry
.
end_label
=
end_protect_label_rtx
;
LABEL_PRESERVE_P
(
entry
.
start_label
)
=
1
;
LABEL_PRESERVE_P
(
entry
.
end_label
)
=
1
;
LABEL_PRESERVE_P
(
entry
.
exception_handler_label
)
=
1
;
/* These set up a call to throw the caught exception into the outer
/* These set up a call to throw the caught exception into the outer
context. */
context. */
enqueue_eh_entry
(
&
eh_table_output_queue
,
copy_eh_entry
(
&
entry
));
enqueue_eh_entry
(
&
eh_table_output_queue
,
copy_eh_entry
(
&
entry
));
...
@@ -1279,6 +1331,7 @@ do_unwind (throw_label)
...
@@ -1279,6 +1331,7 @@ do_unwind (throw_label)
gen_rtx
(
LABEL_REF
,
Pmode
,
throw_label
)),
NULL_TREE
);
gen_rtx
(
LABEL_REF
,
Pmode
,
throw_label
)),
NULL_TREE
);
do_function_call
(
Unwind
,
params
,
NULL_TREE
);
do_function_call
(
Unwind
,
params
,
NULL_TREE
);
assemble_external
(
TREE_OPERAND
(
Unwind
,
0
));
emit_barrier
();
emit_barrier
();
#endif
#endif
#if m88k
#if m88k
...
@@ -1304,9 +1357,18 @@ do_unwind (throw_label)
...
@@ -1304,9 +1357,18 @@ do_unwind (throw_label)
(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
#endif
#endif
#endif
#endif
#ifdef __arm
if
(
flag_omit_frame_pointer
)
sorry
(
"this implementation of exception handling requires a frame pointer"
);
emit_move_insn
(
stack_pointer_rtx
,
gen_rtx
(
MEM
,
SImode
,
plus_constant
(
hard_frame_pointer_rtx
,
-
8
)));
emit_move_insn
(
hard_frame_pointer_rtx
,
gen_rtx
(
MEM
,
SImode
,
plus_constant
(
hard_frame_pointer_rtx
,
-
12
)));
#endif
}
}
/* is called from expand_exc
pe
tion_blocks () to generate the code in a function
/* is called from expand_exc
ep
tion_blocks () to generate the code in a function
to "throw" if anything in the function needs to preform a throw.
to "throw" if anything in the function needs to preform a throw.
expands "throw" as the following psuedo code:
expands "throw" as the following psuedo code:
...
@@ -1333,12 +1395,14 @@ expand_builtin_throw ()
...
@@ -1333,12 +1395,14 @@ expand_builtin_throw ()
rtx
unwind_and_throw
=
gen_label_rtx
();
rtx
unwind_and_throw
=
gen_label_rtx
();
rtx
goto_unwind_and_throw
=
gen_label_rtx
();
rtx
goto_unwind_and_throw
=
gen_label_rtx
();
make_first_label
(
throw_label
);
emit_label
(
throw_label
);
emit_label
(
throw_label
);
/* search for an exception handler for the saved_pc */
/* search for an exception handler for the saved_pc */
return_val_rtx
=
do_function_call
(
FirstExceptionMatch
,
return_val_rtx
=
do_function_call
(
FirstExceptionMatch
,
tree_cons
(
NULL_TREE
,
make_tree
(
ptr_type_node
,
saved_pc
),
NULL_TREE
),
tree_cons
(
NULL_TREE
,
make_tree
(
ptr_type_node
,
saved_pc
),
NULL_TREE
),
ptr_type_node
);
ptr_type_node
);
assemble_external
(
TREE_OPERAND
(
FirstExceptionMatch
,
0
));
/* did we find one? */
/* did we find one? */
emit_cmp_insn
(
return_val_rtx
,
const0_rtx
,
EQ
,
NULL_RTX
,
emit_cmp_insn
(
return_val_rtx
,
const0_rtx
,
EQ
,
NULL_RTX
,
...
@@ -1354,9 +1418,15 @@ expand_builtin_throw ()
...
@@ -1354,9 +1418,15 @@ expand_builtin_throw ()
emit_label
(
gotta_rethrow_it
);
emit_label
(
gotta_rethrow_it
);
/* call to __builtin_return_address () */
/* call to __builtin_return_address () */
#ifdef __arm
/* This replaces a 'call' to __builtin_return_address */
return_val_rtx
=
gen_reg_rtx
(
Pmode
);
emit_move_insn
(
return_val_rtx
,
gen_rtx
(
MEM
,
SImode
,
plus_constant
(
hard_frame_pointer_rtx
,
-
4
)));
#else
params
=
tree_cons
(
NULL_TREE
,
integer_zero_node
,
NULL_TREE
);
params
=
tree_cons
(
NULL_TREE
,
integer_zero_node
,
NULL_TREE
);
fcall
=
build_function_call
(
BuiltinReturnAddress
,
params
);
fcall
=
build_function_call
(
BuiltinReturnAddress
,
params
);
return_val_rtx
=
expand_expr
(
fcall
,
NULL_RTX
,
SImode
,
0
);
return_val_rtx
=
expand_expr
(
fcall
,
NULL_RTX
,
SImode
,
0
);
#endif
/* did __builtin_return_address () return a valid address? */
/* did __builtin_return_address () return a valid address? */
emit_cmp_insn
(
return_val_rtx
,
const0_rtx
,
EQ
,
NULL_RTX
,
emit_cmp_insn
(
return_val_rtx
,
const0_rtx
,
EQ
,
NULL_RTX
,
...
@@ -1364,20 +1434,35 @@ expand_builtin_throw ()
...
@@ -1364,20 +1434,35 @@ expand_builtin_throw ()
emit_jump_insn
(
gen_beq
(
gotta_call_terminate
));
emit_jump_insn
(
gen_beq
(
gotta_call_terminate
));
#ifdef __arm
/* On the ARM, '__builtin_return_address', must have 4
subtracted from it. */
emit_insn
(
gen_add2_insn
(
return_val_rtx
,
GEN_INT
(
-
4
)));
/* If we are generating code for an ARM2/ARM3 machine or for an ARM6 in 26 bit
mode, the condition codes must be masked out of the return value, or else
they will confuse BuiltinReturnAddress. This does not apply to ARM6 and
later processors when running in 32 bit mode. */
if
(
!
TARGET_6
)
emit_insn
(
gen_rtx
(
SET
,
SImode
,
return_val_rtx
,
gen_rtx
(
AND
,
SImode
,
return_val_rtx
,
GEN_INT
(
0x03fffffc
))));
#else
#ifndef sparc
#ifndef sparc
/* On the SPARC, __builtin_return_address is already -8, no need to
/* On the SPARC, __builtin_return_address is already -8, no need to
subtract any more from it. */
subtract any more from it. */
emit_insn
(
gen_add2_insn
(
return_val_rtx
,
GEN_INT
(
-
1
)));
emit_insn
(
gen_add2_insn
(
return_val_rtx
,
GEN_INT
(
-
1
)));
#endif
#endif
#endif
/* yes it did */
/* yes it did */
emit_move_insn
(
saved_pc
,
return_val_rtx
);
emit_move_insn
(
saved_pc
,
return_val_rtx
);
do_unwind
(
throw_label
);
do_unwind
(
throw_label
);
make_first_label
(
throw_label
);
emit_jump
(
throw_label
);
emit_jump
(
throw_label
);
/* no it didn't --> therefore we need to call terminate */
/* no it didn't --> therefore we need to call terminate */
emit_label
(
gotta_call_terminate
);
emit_label
(
gotta_call_terminate
);
do_function_call
(
Terminate
,
NULL_TREE
,
NULL_TREE
);
do_function_call
(
Terminate
,
NULL_TREE
,
NULL_TREE
);
assemble_external
(
TREE_OPERAND
(
Terminate
,
0
));
}
}
...
@@ -1424,7 +1509,7 @@ expand_exception_blocks ()
...
@@ -1424,7 +1509,7 @@ expand_exception_blocks ()
1. Allocate space to save the current PC onto the stack.
1. Allocate space to save the current PC onto the stack.
2. Generate and emit a label and save its address into the
2. Generate and emit a label and save its address into the
newly allocate stack space since we can't save the pc directly.
newly allocate
d
stack space since we can't save the pc directly.
3. If this is the first call to throw in this function:
3. If this is the first call to throw in this function:
generate a label for the throw block
generate a label for the throw block
4. jump to the throw block label. */
4. jump to the throw block label. */
...
@@ -1476,6 +1561,7 @@ expand_throw (exp)
...
@@ -1476,6 +1561,7 @@ expand_throw (exp)
/* This part is easy, as we dont' have to do anything else. */
/* This part is easy, as we dont' have to do anything else. */
}
}
make_first_label
(
throw_label
);
emit_jump
(
throw_label
);
emit_jump
(
throw_label
);
}
}
...
...
gcc/cp/gxx.gperf
View file @
e1cd6e56
...
@@ -19,8 +19,10 @@ __headof__, HEADOF, NORID
...
@@ -19,8 +19,10 @@ __headof__, HEADOF, NORID
__inline, SCSPEC, RID_INLINE
__inline, SCSPEC, RID_INLINE
__inline__, SCSPEC, RID_INLINE
__inline__, SCSPEC, RID_INLINE
__label__, LABEL, NORID
__label__, LABEL, NORID
__signature__, AGGR, RID_SIGNATURE /* Extension */,
__signed, TYPESPEC, RID_SIGNED
__signed, TYPESPEC, RID_SIGNED
__signed__, TYPESPEC, RID_SIGNED
__signed__, TYPESPEC, RID_SIGNED
__sigof__, SIGOF, NORID /* Extension */,
__typeof, TYPEOF, NORID
__typeof, TYPEOF, NORID
__typeof__, TYPEOF, NORID
__typeof__, TYPEOF, NORID
__volatile, TYPE_QUAL, RID_VOLATILE
__volatile, TYPE_QUAL, RID_VOLATILE
...
...
gcc/cp/init.c
View file @
e1cd6e56
...
@@ -2376,9 +2376,9 @@ add_friend (type, decl)
...
@@ -2376,9 +2376,9 @@ add_friend (type, decl)
{
{
if
(
decl
==
TREE_VALUE
(
friends
))
if
(
decl
==
TREE_VALUE
(
friends
))
{
{
cp_
pedwarn
(
"`%D' is already a friend of class `%T'"
,
cp_
warning
(
"`%D' is already a friend of class `%T'"
,
decl
,
type
);
decl
,
type
);
cp_
pedwarn
_at
(
"previous friend declaration of `%D'"
,
cp_
warning
_at
(
"previous friend declaration of `%D'"
,
TREE_VALUE
(
friends
));
TREE_VALUE
(
friends
));
return
;
return
;
}
}
...
@@ -2948,12 +2948,15 @@ build_new (placement, decl, init, use_global_new)
...
@@ -2948,12 +2948,15 @@ build_new (placement, decl, init, use_global_new)
else
else
size
=
size_in_bytes
(
type
);
size
=
size_in_bytes
(
type
);
if
(
true_type
==
void_type_node
)
{
error
(
"invalid type for new: `void'"
);
return
error_mark_node
;
}
if
(
TYPE_SIZE
(
true_type
)
==
0
)
if
(
TYPE_SIZE
(
true_type
)
==
0
)
{
{
if
(
true_type
==
void_type_node
)
incomplete_type_error
(
0
,
true_type
);
error
(
"invalid type for new: `void'"
);
else
incomplete_type_error
(
0
,
true_type
);
return
error_mark_node
;
return
error_mark_node
;
}
}
...
...
gcc/cp/lex.c
View file @
e1cd6e56
...
@@ -403,6 +403,8 @@ void
...
@@ -403,6 +403,8 @@ void
init_lex
()
init_lex
()
{
{
extern
char
*
(
*
decl_printable_name
)
();
extern
char
*
(
*
decl_printable_name
)
();
extern
int
flag_no_gnu_keywords
;
extern
int
flag_operator_names
;
int
i
;
int
i
;
...
@@ -788,23 +790,21 @@ init_lex ()
...
@@ -788,23 +790,21 @@ init_lex ()
}
}
#endif
#endif
if
(
!
(
flag_gc
||
flag_rtti
))
if
(
!
(
flag_gc
||
flag_rtti
)
||
flag_no_gnu_keywords
)
{
{
UNSET_RESERVED_WORD
(
"classof"
);
UNSET_RESERVED_WORD
(
"classof"
);
UNSET_RESERVED_WORD
(
"headof"
);
UNSET_RESERVED_WORD
(
"headof"
);
}
}
if
(
!
flag_handle_signatures
)
if
(
!
flag_handle_signatures
||
flag_no_gnu_keywords
)
{
{
/* Easiest way to not recognize signature
/* Easiest way to not recognize signature
handling extensions... */
handling extensions... */
UNSET_RESERVED_WORD
(
"signature"
);
UNSET_RESERVED_WORD
(
"signature"
);
UNSET_RESERVED_WORD
(
"sigof"
);
UNSET_RESERVED_WORD
(
"sigof"
);
}
}
if
(
flag_no_asm
)
if
(
flag_no_asm
||
flag_no_gnu_keywords
)
UNSET_RESERVED_WORD
(
"asm"
);
if
(
flag_no_asm
||
flag_traditional
)
UNSET_RESERVED_WORD
(
"typeof"
);
UNSET_RESERVED_WORD
(
"typeof"
);
if
(
!
flag_ansi
)
if
(
!
flag_operator_names
)
{
{
/* These are new ANSI keywords that may break code. */
/* These are new ANSI keywords that may break code. */
UNSET_RESERVED_WORD
(
"and"
);
UNSET_RESERVED_WORD
(
"and"
);
...
@@ -815,6 +815,8 @@ init_lex ()
...
@@ -815,6 +815,8 @@ init_lex ()
UNSET_RESERVED_WORD
(
"or"
);
UNSET_RESERVED_WORD
(
"or"
);
UNSET_RESERVED_WORD
(
"xor"
);
UNSET_RESERVED_WORD
(
"xor"
);
}
}
if
(
!
flag_traditional
)
UNSET_RESERVED_WORD
(
"overload"
);
token_count
=
init_parse
();
token_count
=
init_parse
();
interface_unknown
=
1
;
interface_unknown
=
1
;
...
@@ -4211,7 +4213,7 @@ real_yylex ()
...
@@ -4211,7 +4213,7 @@ real_yylex ()
goto
tryagain
;
goto
tryagain
;
if
(
width
<
HOST_BITS_PER_INT
if
(
width
<
HOST_BITS_PER_INT
&&
(
unsigned
)
c
>=
(
1
<<
width
))
&&
(
unsigned
)
c
>=
(
1
<<
width
))
pedwarn
(
"escape sequence out of range for character"
);
warning
(
"escape sequence out of range for character"
);
#ifdef MAP_CHARACTER
#ifdef MAP_CHARACTER
if
(
isprint
(
c
))
if
(
isprint
(
c
))
c
=
MAP_CHARACTER
(
c
);
c
=
MAP_CHARACTER
(
c
);
...
@@ -4328,7 +4330,7 @@ real_yylex ()
...
@@ -4328,7 +4330,7 @@ real_yylex ()
if
(
!
wide_flag
if
(
!
wide_flag
&&
TYPE_PRECISION
(
char_type_node
)
<
HOST_BITS_PER_INT
&&
TYPE_PRECISION
(
char_type_node
)
<
HOST_BITS_PER_INT
&&
c
>=
((
unsigned
)
1
<<
TYPE_PRECISION
(
char_type_node
)))
&&
c
>=
((
unsigned
)
1
<<
TYPE_PRECISION
(
char_type_node
)))
pedwarn
(
"escape sequence out of range for character"
);
warning
(
"escape sequence out of range for character"
);
}
}
else
if
(
c
==
'\n'
)
else
if
(
c
==
'\n'
)
{
{
...
@@ -4483,7 +4485,7 @@ real_yylex ()
...
@@ -4483,7 +4485,7 @@ real_yylex ()
}
}
else
if
((
c
==
'-'
)
&&
(
c1
==
'>'
))
else
if
((
c
==
'-'
)
&&
(
c1
==
'>'
))
{
{
nextchar
=
skip_white_space
(
getch
()
);
nextchar
=
getch
(
);
if
(
nextchar
==
'*'
)
if
(
nextchar
==
'*'
)
{
{
nextchar
=
-
1
;
nextchar
=
-
1
;
...
@@ -4510,11 +4512,22 @@ real_yylex ()
...
@@ -4510,11 +4512,22 @@ real_yylex ()
value
=
MIN_MAX
;
value
=
MIN_MAX
;
nextchar
=
c1
;
nextchar
=
c1
;
}
}
if
(
flag_ansi
)
if
(
pedantic
)
pedwarn
(
"use of `operator %s' is not standard C++"
,
pedwarn
(
"use of `operator %s' is not standard C++"
,
token_buffer
);
token_buffer
);
goto
done
;
goto
done
;
}
}
/* digraphs */
else
if
(
c
==
'<'
&&
c1
==
'%'
)
{
value
=
'{'
;
goto
done
;
}
else
if
(
c
==
'<'
&&
c1
==
':'
)
{
value
=
'['
;
goto
done
;
}
else
if
(
c
==
'%'
&&
c1
==
'>'
)
{
value
=
'}'
;
goto
done
;
}
else
if
(
c
==
'%'
&&
c1
==
':'
)
{
value
=
'#'
;
goto
done
;
}
else
if
(
c
==
':'
&&
c1
==
'>'
)
{
value
=
']'
;
goto
done
;
}
nextchar
=
c1
;
nextchar
=
c1
;
token_buffer
[
1
]
=
0
;
token_buffer
[
1
]
=
0
;
...
...
gcc/cp/lex.h
View file @
e1cd6e56
...
@@ -123,6 +123,7 @@ extern int looking_for_template;
...
@@ -123,6 +123,7 @@ extern int looking_for_template;
/* Tell the lexer where to look for names. */
/* Tell the lexer where to look for names. */
extern
tree
got_scope
;
extern
tree
got_scope
;
extern
tree
got_object
;
/* Pending language change.
/* Pending language change.
Positive is push count, negative is pop count. */
Positive is push count, negative is pop count. */
...
...
gcc/cp/parse.y
View file @
e1cd6e56
...
@@ -1246,7 +1246,8 @@ expr_no_commas:
...
@@ -1246,7 +1246,8 @@ expr_no_commas:
| expr_no_commas '?' xexpr ':' expr_no_commas
| expr_no_commas '?' xexpr ':' expr_no_commas
{ $$ = build_x_conditional_expr ($$, $3, $5); }
{ $$ = build_x_conditional_expr ($$, $3, $5); }
| expr_no_commas '=' expr_no_commas
| expr_no_commas '=' expr_no_commas
{ $$ = build_modify_expr ($$, NOP_EXPR, $3); }
{ $$ = build_modify_expr ($$, NOP_EXPR, $3);
C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); }
| expr_no_commas ASSIGN expr_no_commas
| expr_no_commas ASSIGN expr_no_commas
{ register tree rval;
{ register tree rval;
if ((rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3,
if ((rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3,
...
@@ -1333,7 +1334,12 @@ primary:
...
@@ -1333,7 +1334,12 @@ primary:
| string
| string
{ $$ = combine_strings ($$); }
{ $$ = combine_strings ($$); }
| '(' expr ')'
| '(' expr ')'
{ $$ = $2; }
{ char class = TREE_CODE_CLASS (TREE_CODE ($2));
if (class == 'e' || class == '1'
|| class == '2' || class == '<')
/* This inhibits warnings in truthvalue_conversion. */
C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
$$ = $2; }
| '(' error ')'
| '(' error ')'
{ $$ = error_mark_node; }
{ $$ = error_mark_node; }
| '('
| '('
...
@@ -1538,11 +1544,14 @@ primary:
...
@@ -1538,11 +1544,14 @@ primary:
| overqualified_id LEFT_RIGHT
| overqualified_id LEFT_RIGHT
{ $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }
{ $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }
| object unqualified_id %prec UNARY
| object unqualified_id %prec UNARY
{ $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
{ got_object = NULL_TREE;
$$ = build_component_ref ($$, $2, NULL_TREE, 1); }
| object qualified_id %prec UNARY
| object qualified_id %prec UNARY
{ $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
{ got_object = NULL_TREE;
$$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
| object unqualified_id '(' nonnull_exprlist ')'
| object unqualified_id '(' nonnull_exprlist ')'
{
{
got_object = NULL_TREE;
#if 0
#if 0
/* This is a future direction of this code, but because
/* This is a future direction of this code, but because
build_x_function_call cannot always undo what is done
build_x_function_call cannot always undo what is done
...
@@ -1558,6 +1567,7 @@ primary:
...
@@ -1558,6 +1567,7 @@ primary:
}
}
| object unqualified_id LEFT_RIGHT
| object unqualified_id LEFT_RIGHT
{
{
got_object = NULL_TREE;
#if 0
#if 0
/* This is a future direction of this code, but because
/* This is a future direction of this code, but because
build_x_function_call cannot always undo what is done
build_x_function_call cannot always undo what is done
...
@@ -1573,6 +1583,7 @@ primary:
...
@@ -1573,6 +1583,7 @@ primary:
}
}
| object qualified_id '(' nonnull_exprlist ')'
| object qualified_id '(' nonnull_exprlist ')'
{
{
got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
{
{
warning ("signature name in scope resolution ignored");
warning ("signature name in scope resolution ignored");
...
@@ -1584,6 +1595,7 @@ primary:
...
@@ -1584,6 +1595,7 @@ primary:
}
}
| object qualified_id LEFT_RIGHT
| object qualified_id LEFT_RIGHT
{
{
got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
{
{
warning ("signature name in scope resolution ignored");
warning ("signature name in scope resolution ignored");
...
@@ -1595,14 +1607,16 @@ primary:
...
@@ -1595,14 +1607,16 @@ primary:
}
}
/* p->int::~int() is valid -- 12.4 */
/* p->int::~int() is valid -- 12.4 */
| object '~' TYPESPEC LEFT_RIGHT
| object '~' TYPESPEC LEFT_RIGHT
{
{
got_object = NULL_TREE;
if (TREE_CODE (TREE_TYPE ($1))
if (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3))))
!= 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);
}
}
| object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT
| object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT
{
{
got_object = NULL_TREE;
if ($2 != $5)
if ($2 != $5)
cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5);
cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5);
if (TREE_CODE (TREE_TYPE ($1))
if (TREE_CODE (TREE_TYPE ($1))
...
@@ -1610,6 +1624,11 @@ primary:
...
@@ -1610,6 +1624,11 @@ primary:
cp_error ("`%E' is not of type `%T'", $1, $2);
cp_error ("`%E' is not of type `%T'", $1, $2);
$$ = convert (void_type_node, $1);
$$ = convert (void_type_node, $1);
}
}
| object error
{
got_object = NULL_TREE;
$$ = error_mark_node;
}
;
;
/* Not needed for now.
/* Not needed for now.
...
@@ -1690,9 +1709,11 @@ nodecls:
...
@@ -1690,9 +1709,11 @@ nodecls:
;
;
object: primary '.'
object: primary '.'
{ got_object = TREE_TYPE ($$); }
| primary POINTSAT
| primary POINTSAT
{
{
$$ = build_x_arrow ($$);
$$ = build_x_arrow ($$);
got_object = TREE_TYPE ($$);
}
}
;
;
...
@@ -3288,7 +3309,7 @@ simple_stmt:
...
@@ -3288,7 +3309,7 @@ simple_stmt:
else if (success == 2)
else if (success == 2)
{
{
cp_error ("duplicate case value `%E'", $2);
cp_error ("duplicate case value `%E'", $2);
cp_error_at ("
`%E'
previously used here", duplicate);
cp_error_at ("previously used here", duplicate);
}
}
else if (success == 3)
else if (success == 3)
warning ("case value out of range");
warning ("case value out of range");
...
...
gcc/cp/pt.c
View file @
e1cd6e56
...
@@ -1257,6 +1257,8 @@ tsubst (t, args, nargs, in_decl)
...
@@ -1257,6 +1257,8 @@ tsubst (t, args, nargs, in_decl)
type
=
newtype
;
type
=
newtype
;
fnargs
=
copy_node
(
DECL_ARGUMENTS
(
t
));
fnargs
=
copy_node
(
DECL_ARGUMENTS
(
t
));
TREE_CHAIN
(
fnargs
)
=
TREE_CHAIN
(
DECL_ARGUMENTS
(
t
));
/* In this case we need "in-charge" flag saying whether
/* In this case we need "in-charge" flag saying whether
this constructor is responsible for initialization
this constructor is responsible for initialization
of virtual baseclasses or not. */
of virtual baseclasses or not. */
...
@@ -1419,7 +1421,7 @@ tsubst (t, args, nargs, in_decl)
...
@@ -1419,7 +1421,7 @@ tsubst (t, args, nargs, in_decl)
r
=
build_lang_decl
(
FUNCTION_DECL
,
r
,
type
);
r
=
build_lang_decl
(
FUNCTION_DECL
,
r
,
type
);
DECL_ASSEMBLER_NAME
(
r
)
=
a
;
DECL_ASSEMBLER_NAME
(
r
)
=
a
;
}
}
else
if
(
DECL_INLINE
(
r
)
&&
DECL_SAVED_INSNS
(
r
))
else
if
(
TREE_STATIC
(
r
))
{
{
/* This overrides the template version, use it. */
/* This overrides the template version, use it. */
return
r
;
return
r
;
...
@@ -1718,7 +1720,7 @@ instantiate_template (tmpl, targ_ptr)
...
@@ -1718,7 +1720,7 @@ instantiate_template (tmpl, targ_ptr)
/* If we have a preexisting version of this function, don't expand
/* If we have a preexisting version of this function, don't expand
the template version, use the other instead. */
the template version, use the other instead. */
if
(
DECL_INLINE
(
fndecl
)
&&
DECL_SAVED_INSNS
(
fndecl
))
if
(
TREE_STATIC
(
fndecl
))
{
{
SET_DECL_TEMPLATE_SPECIALIZATION
(
fndecl
);
SET_DECL_TEMPLATE_SPECIALIZATION
(
fndecl
);
p
=
(
struct
pending_inline
*
)
0
;
p
=
(
struct
pending_inline
*
)
0
;
...
@@ -2448,7 +2450,7 @@ do_function_instantiation (declspecs, declarator, storage)
...
@@ -2448,7 +2450,7 @@ do_function_instantiation (declspecs, declarator, storage)
{
{
int
ntparms
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
fn
));
int
ntparms
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
fn
));
tree
*
targs
=
(
tree
*
)
malloc
(
sizeof
(
tree
)
*
ntparms
);
tree
*
targs
=
(
tree
*
)
malloc
(
sizeof
(
tree
)
*
ntparms
);
int
i
,
dummy
;
int
i
,
dummy
=
0
;
i
=
type_unification
(
DECL_TEMPLATE_PARMS
(
fn
),
targs
,
i
=
type_unification
(
DECL_TEMPLATE_PARMS
(
fn
),
targs
,
TYPE_ARG_TYPES
(
TREE_TYPE
(
fn
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
fn
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)),
...
@@ -2460,6 +2462,7 @@ do_function_instantiation (declspecs, declarator, storage)
...
@@ -2460,6 +2462,7 @@ do_function_instantiation (declspecs, declarator, storage)
else
else
result
=
instantiate_template
(
fn
,
targs
);
result
=
instantiate_template
(
fn
,
targs
);
}
}
free
(
targs
);
}
}
}
}
if
(
!
result
)
if
(
!
result
)
...
...
gcc/cp/search.c
View file @
e1cd6e56
...
@@ -1089,18 +1089,29 @@ lookup_field (xbasetype, name, protect, want_type)
...
@@ -1089,18 +1089,29 @@ lookup_field (xbasetype, name, protect, want_type)
entry
=
0
;
entry
=
0
;
rval
=
lookup_field_1
(
type
,
name
);
rval
=
lookup_field_1
(
type
,
name
);
if
(
rval
||
lookup_fnfields_here
(
type
,
name
)
>=
0
)
{
rval_binfo
=
basetype_path
;
rval_binfo_h
=
rval_binfo
;
}
if
(
rval
&&
TREE_CODE
(
rval
)
!=
TYPE_DECL
&&
want_type
)
rval
=
NULL_TREE
;
if
(
rval
)
if
(
rval
||
lookup_fnfields_here
(
type
,
name
)
>=
0
)
{
{
if
(
protect
)
if
(
rval
)
{
if
(
want_type
)
{
if
(
TREE_CODE
(
rval
)
!=
TYPE_DECL
)
{
rval
=
purpose_member
(
name
,
CLASSTYPE_TAGS
(
type
));
if
(
rval
)
rval
=
TYPE_MAIN_DECL
(
TREE_VALUE
(
rval
));
}
}
else
{
if
(
TREE_CODE
(
rval
)
==
TYPE_DECL
&&
lookup_fnfields_here
(
type
,
name
)
>=
0
)
rval
=
NULL_TREE
;
}
}
if
(
protect
&&
rval
)
{
{
if
(
TREE_PRIVATE
(
rval
)
|
TREE_PROTECTED
(
rval
))
if
(
TREE_PRIVATE
(
rval
)
|
TREE_PROTECTED
(
rval
))
this_v
=
compute_access
(
basetype_path
,
rval
);
this_v
=
compute_access
(
basetype_path
,
rval
);
...
@@ -1259,12 +1270,33 @@ lookup_field (xbasetype, name, protect, want_type)
...
@@ -1259,12 +1270,33 @@ lookup_field (xbasetype, name, protect, want_type)
if
(
entry
)
if
(
entry
)
TREE_VALUE
(
entry
)
=
rval
;
TREE_VALUE
(
entry
)
=
rval
;
if
(
want_type
&&
(
rval
==
NULL_TREE
||
TREE_CODE
(
rval
)
!=
TYPE_DECL
)
)
if
(
rval_binfo
)
{
{
rval
=
NULL_TREE
;
type
=
BINFO_TYPE
(
rval_binfo
);
errstr
=
0
;
if
(
rval
)
{
if
(
want_type
)
{
if
(
TREE_CODE
(
rval
)
!=
TYPE_DECL
)
{
rval
=
purpose_member
(
name
,
CLASSTYPE_TAGS
(
type
));
if
(
rval
)
rval
=
TYPE_MAIN_DECL
(
TREE_VALUE
(
rval
));
}
}
else
{
if
(
TREE_CODE
(
rval
)
==
TYPE_DECL
&&
lookup_fnfields_here
(
type
,
name
)
>=
0
)
rval
=
NULL_TREE
;
}
}
}
}
if
(
rval
==
NULL_TREE
)
errstr
=
0
;
/* If this FIELD_DECL defines its own access level, deal with that. */
/* If this FIELD_DECL defines its own access level, deal with that. */
if
(
rval
&&
errstr
==
0
if
(
rval
&&
errstr
==
0
&&
((
protect
&
1
)
||
entry
)
&&
((
protect
&
1
)
||
entry
)
...
@@ -1948,11 +1980,51 @@ get_matching_virtual (binfo, fndecl, dtorp)
...
@@ -1948,11 +1980,51 @@ get_matching_virtual (binfo, fndecl, dtorp)
==
TYPE_READONLY
(
instptr_type
))
==
TYPE_READONLY
(
instptr_type
))
&&
compparms
(
TREE_CHAIN
(
btypes
),
TREE_CHAIN
(
dtypes
),
3
))
&&
compparms
(
TREE_CHAIN
(
btypes
),
TREE_CHAIN
(
dtypes
),
3
))
{
{
if
(
IDENTIFIER_ERROR_LOCUS
(
name
)
==
NULL_TREE
tree
brettype
=
TREE_TYPE
(
TREE_TYPE
(
tmp
));
&&
!
comptypes
(
TREE_TYPE
(
TREE_TYPE
(
tmp
)),
drettype
,
1
))
if
(
comptypes
(
brettype
,
drettype
,
1
))
/* OK */
;
else
if
(
TREE_CODE
(
brettype
)
==
TREE_CODE
(
drettype
)
&&
(
TREE_CODE
(
brettype
)
==
POINTER_TYPE
||
TREE_CODE
(
brettype
)
==
REFERENCE_TYPE
)
&&
comptypes
(
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
brettype
)),
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
drettype
)),
0
))
/* covariant return type */
{
tree
b
=
TREE_TYPE
(
brettype
),
d
=
TREE_TYPE
(
drettype
);
if
(
TYPE_MAIN_VARIANT
(
b
)
!=
TYPE_MAIN_VARIANT
(
d
))
{
tree
binfo
=
get_binfo
(
b
,
d
,
1
);
if
(
binfo
!=
error_mark_node
&&
!
BINFO_OFFSET_ZEROP
(
binfo
))
sorry
(
"adjusting pointers for covariant returns"
);
}
if
(
TYPE_READONLY
(
d
)
>
TYPE_READONLY
(
b
))
{
cp_error
(
"return type of `%#D' adds const"
,
fndecl
);
cp_error_at
(
" overriding definition as `%#D'"
,
tmp
);
}
else
if
(
TYPE_VOLATILE
(
d
)
>
TYPE_VOLATILE
(
b
))
{
cp_error
(
"return type of `%#D' adds volatile"
,
fndecl
);
cp_error_at
(
" overriding definition as `%#D'"
,
tmp
);
}
}
else
if
(
IS_AGGR_TYPE_2
(
brettype
,
drettype
)
&&
comptypes
(
brettype
,
drettype
,
0
))
{
error
(
"invalid covariant return type (must use pointer or reference)"
);
cp_error_at
(
" overriding `%#D'"
,
tmp
);
cp_error
(
" with `%#D'"
,
fndecl
);
}
else
if
(
IDENTIFIER_ERROR_LOCUS
(
name
)
==
NULL_TREE
)
{
{
cp_error
(
"conflicting return type specified for virtual function `%#D'"
,
fndecl
);
cp_error
(
"conflicting return type specified for virtual function `%#D'"
,
fndecl
);
cp_error_at
(
"overriding definition as `%#D'"
,
tmp
);
cp_error_at
(
"
overriding definition as `%#D'"
,
tmp
);
SET_IDENTIFIER_ERROR_LOCUS
(
name
,
basetype
);
SET_IDENTIFIER_ERROR_LOCUS
(
name
,
basetype
);
}
}
break
;
break
;
...
@@ -2192,7 +2264,7 @@ dfs_walk (binfo, fn, qfn)
...
@@ -2192,7 +2264,7 @@ dfs_walk (binfo, fn, qfn)
{
{
tree
base_binfo
=
TREE_VEC_ELT
(
binfos
,
i
);
tree
base_binfo
=
TREE_VEC_ELT
(
binfos
,
i
);
if
((
*
qfn
)(
base_binfo
))
if
(
qfn
==
0
||
(
*
qfn
)(
base_binfo
))
{
{
if
(
fn
==
dfs_init_vbase_pointers
)
if
(
fn
==
dfs_init_vbase_pointers
)
{
{
...
@@ -2800,8 +2872,14 @@ dfs_pushdecls (binfo)
...
@@ -2800,8 +2872,14 @@ dfs_pushdecls (binfo)
?
DECL_CLASS_CONTEXT
(
value
)
?
DECL_CLASS_CONTEXT
(
value
)
:
DECL_CONTEXT
(
value
);
:
DECL_CONTEXT
(
value
);
if
(
context
&&
(
context
==
type
if
(
context
==
type
)
||
TYPE_DERIVES_FROM
(
context
,
type
)))
{
if
(
TREE_CODE
(
value
)
==
TYPE_DECL
&&
DECL_ARTIFICIAL
(
value
))
value
=
fields
;
/* else the old value wins */
}
else
if
(
context
&&
TYPE_DERIVES_FROM
(
context
,
type
))
value
=
fields
;
value
=
fields
;
else
else
value
=
tree_cons
(
NULL_TREE
,
fields
,
value
=
tree_cons
(
NULL_TREE
,
fields
,
...
@@ -3210,3 +3288,24 @@ reinit_search_statistics ()
...
@@ -3210,3 +3288,24 @@ reinit_search_statistics ()
n_outer_fields_searched
=
0
;
n_outer_fields_searched
=
0
;
n_contexts_saved
=
0
;
n_contexts_saved
=
0
;
}
}
static
tree
conversions
;
static
void
add_conversions
(
binfo
)
tree
binfo
;
{
tree
tmp
=
CLASSTYPE_FIRST_CONVERSION
(
BINFO_TYPE
(
binfo
));
for
(;
tmp
&&
IDENTIFIER_TYPENAME_P
(
DECL_NAME
(
tmp
));
tmp
=
TREE_CHAIN
(
tmp
))
conversions
=
tree_cons
(
DECL_NAME
(
tmp
),
TREE_TYPE
(
TREE_TYPE
(
tmp
)),
conversions
);
}
tree
lookup_conversions
(
type
)
tree
type
;
{
conversions
=
NULL_TREE
;
dfs_walk
(
TYPE_BINFO
(
type
),
add_conversions
,
0
);
return
conversions
;
}
gcc/cp/spew.c
View file @
e1cd6e56
...
@@ -242,6 +242,7 @@ int looking_for_template;
...
@@ -242,6 +242,7 @@ int looking_for_template;
extern
struct
obstack
*
current_obstack
,
*
saveable_obstack
;
extern
struct
obstack
*
current_obstack
,
*
saveable_obstack
;
tree
got_scope
;
tree
got_scope
;
tree
got_object
;
int
int
yylex
()
yylex
()
...
@@ -316,7 +317,7 @@ yylex()
...
@@ -316,7 +317,7 @@ yylex()
if
(
lastiddecl
!=
trrr
)
if
(
lastiddecl
!=
trrr
)
{
{
lastiddecl
=
trrr
;
lastiddecl
=
trrr
;
if
(
got_scope
)
if
(
got_scope
||
got_object
)
tmp_token
.
yylval
.
ttype
=
DECL_NESTED_TYPENAME
(
trrr
);
tmp_token
.
yylval
.
ttype
=
DECL_NESTED_TYPENAME
(
trrr
);
}
}
break
;
break
;
...
@@ -334,8 +335,11 @@ yylex()
...
@@ -334,8 +335,11 @@ yylex()
lastiddecl
=
trrr
;
lastiddecl
=
trrr
;
got_scope
=
NULL_TREE
;
got_scope
=
NULL_TREE
;
/* and fall through to... */
/* and fall through to... */
case
IDENTIFIER_DEFN
:
case
TYPENAME
:
case
TYPENAME
:
case
TYPENAME_DEFN
:
case
PTYPENAME
:
case
PTYPENAME
:
case
PTYPENAME_DEFN
:
consume_token
();
consume_token
();
if
(
looking_for_typename
>
0
)
if
(
looking_for_typename
>
0
)
looking_for_typename
--
;
looking_for_typename
--
;
...
...
gcc/cp/tree.c
View file @
e1cd6e56
...
@@ -102,6 +102,11 @@ lvalue_p (ref)
...
@@ -102,6 +102,11 @@ lvalue_p (ref)
case
COMPOUND_EXPR
:
case
COMPOUND_EXPR
:
return
lvalue_p
(
TREE_OPERAND
(
ref
,
1
));
return
lvalue_p
(
TREE_OPERAND
(
ref
,
1
));
case
MAX_EXPR
:
case
MIN_EXPR
:
return
(
lvalue_p
(
TREE_OPERAND
(
ref
,
0
))
&&
lvalue_p
(
TREE_OPERAND
(
ref
,
1
)));
}
}
return
0
;
return
0
;
...
@@ -570,9 +575,13 @@ layout_vbasetypes (rec, max)
...
@@ -570,9 +575,13 @@ layout_vbasetypes (rec, max)
BINFO_OFFSET
(
vbase_types
)
=
offset
;
BINFO_OFFSET
(
vbase_types
)
=
offset
;
if
(
TREE_CODE
(
TYPE_SIZE
(
basetype
))
==
INTEGER_CST
)
if
(
TREE_CODE
(
TYPE_SIZE
(
basetype
))
==
INTEGER_CST
)
const_size
+=
MAX
(
BITS_PER_UNIT
,
{
TREE_INT_CST_LOW
(
TYPE_SIZE
(
basetype
))
/* Every virtual baseclass takes a least a UNIT, so that we can
-
TREE_INT_CST_LOW
(
CLASSTYPE_VBASE_SIZE
(
basetype
)));
take it's address and get something different for each base. */
const_size
+=
MAX
(
BITS_PER_UNIT
,
TREE_INT_CST_LOW
(
TYPE_SIZE
(
basetype
))
-
TREE_INT_CST_LOW
(
CLASSTYPE_VBASE_SIZE
(
basetype
)));
}
else
if
(
var_size
==
0
)
else
if
(
var_size
==
0
)
var_size
=
TYPE_SIZE
(
basetype
);
var_size
=
TYPE_SIZE
(
basetype
);
else
else
...
@@ -581,6 +590,15 @@ layout_vbasetypes (rec, max)
...
@@ -581,6 +590,15 @@ layout_vbasetypes (rec, max)
vbase_types
=
TREE_CHAIN
(
vbase_types
);
vbase_types
=
TREE_CHAIN
(
vbase_types
);
}
}
if
(
const_size
)
{
/* Because a virtual base might take a single byte above,
we have to re-adjust the total size to make sure it it
a multiple of the alignment. */
/* Give the whole object the alignment it wants. */
const_size
=
CEIL
(
const_size
,
record_align
)
*
record_align
;
}
/* Set the alignment in the complete type. We don't set CLASSTYPE_ALIGN
/* Set the alignment in the complete type. We don't set CLASSTYPE_ALIGN
here, as that is for this class, without any virtual base classes. */
here, as that is for this class, without any virtual base classes. */
TYPE_ALIGN
(
rec
)
=
record_align
;
TYPE_ALIGN
(
rec
)
=
record_align
;
...
...
gcc/cp/typeck.c
View file @
e1cd6e56
...
@@ -202,9 +202,6 @@ commonparms (p1, p2)
...
@@ -202,9 +202,6 @@ commonparms (p1, p2)
{
{
if
(
TREE_PURPOSE
(
p1
)
&&
!
TREE_PURPOSE
(
p2
))
if
(
TREE_PURPOSE
(
p1
)
&&
!
TREE_PURPOSE
(
p2
))
{
{
/* We used to give a warning here that advised about a default
argument being given in the prototype but not in the function's
declaration. It's best not to bother. */
TREE_PURPOSE
(
n
)
=
TREE_PURPOSE
(
p1
);
TREE_PURPOSE
(
n
)
=
TREE_PURPOSE
(
p1
);
any_change
=
1
;
any_change
=
1
;
}
}
...
@@ -352,6 +349,11 @@ common_type (t1, t2)
...
@@ -352,6 +349,11 @@ common_type (t1, t2)
return
build_type_attribute_variant
(
t1
,
attributes
);
return
build_type_attribute_variant
(
t1
,
attributes
);
}
}
if
(
TYPE_MAIN_VARIANT
(
t1
)
==
long_double_type_node
||
TYPE_MAIN_VARIANT
(
t2
)
==
long_double_type_node
)
return
build_type_attribute_variant
(
long_double_type_node
,
attributes
);
/* Otherwise prefer the unsigned one. */
/* Otherwise prefer the unsigned one. */
if
(
TREE_UNSIGNED
(
t1
))
if
(
TREE_UNSIGNED
(
t1
))
...
@@ -445,9 +447,12 @@ common_type (t1, t2)
...
@@ -445,9 +447,12 @@ common_type (t1, t2)
my_friendly_assert
(
TYPE_MAIN_VARIANT
(
t1
)
==
t1
my_friendly_assert
(
TYPE_MAIN_VARIANT
(
t1
)
==
t1
&&
TYPE_MAIN_VARIANT
(
t2
)
==
t2
,
306
);
&&
TYPE_MAIN_VARIANT
(
t2
)
==
t2
,
306
);
if
(
!
binfo_or_else
(
t1
,
t2
))
if
(
DERIVED_FROM_P
(
t1
,
t2
)
&&
binfo_or_else
(
t1
,
t2
))
compiler_error
(
"common_type called with uncommon aggregate types"
);
return
build_type_attribute_variant
(
t1
,
attributes
);
return
build_type_attribute_variant
(
t1
,
attributes
);
else
if
(
binfo_or_else
(
t2
,
t1
))
return
build_type_attribute_variant
(
t2
,
attributes
);
else
compiler_error
(
"common_type called with uncommon aggregate types"
);
case
METHOD_TYPE
:
case
METHOD_TYPE
:
if
(
comptypes
(
TYPE_METHOD_BASETYPE
(
t1
),
TYPE_METHOD_BASETYPE
(
t2
),
1
)
if
(
comptypes
(
TYPE_METHOD_BASETYPE
(
t1
),
TYPE_METHOD_BASETYPE
(
t2
),
1
)
...
@@ -761,9 +766,7 @@ comp_target_types (ttl, ttr, nptrs)
...
@@ -761,9 +766,7 @@ comp_target_types (ttl, ttr, nptrs)
case
1
:
case
1
:
return
1
;
return
1
;
case
2
:
case
2
:
cp_pedwarn
(
"converting `%T' to `%T' is a contravariance violation"
,
return
-
1
;
ttr
,
ttl
);
return
1
;
default:
default:
my_friendly_abort
(
112
);
my_friendly_abort
(
112
);
}
}
...
@@ -780,17 +783,17 @@ comp_target_types (ttl, ttr, nptrs)
...
@@ -780,17 +783,17 @@ comp_target_types (ttl, ttr, nptrs)
return
comp_target_types
(
TREE_TYPE
(
ttl
),
TREE_TYPE
(
ttr
),
nptrs
);
return
comp_target_types
(
TREE_TYPE
(
ttl
),
TREE_TYPE
(
ttr
),
nptrs
);
else
if
(
comptypes
(
TYPE_OFFSET_BASETYPE
(
ttl
),
TYPE_OFFSET_BASETYPE
(
ttr
),
0
)
else
if
(
comptypes
(
TYPE_OFFSET_BASETYPE
(
ttl
),
TYPE_OFFSET_BASETYPE
(
ttr
),
0
)
&&
comp_target_types
(
TREE_TYPE
(
ttl
),
TREE_TYPE
(
ttr
),
nptrs
))
&&
comp_target_types
(
TREE_TYPE
(
ttl
),
TREE_TYPE
(
ttr
),
nptrs
))
{
return
-
1
;
cp_pedwarn
(
"converting `%T' to `%T' is a contravariance violation"
,
ttr
,
ttl
);
return
1
;
}
}
}
else
if
(
IS_AGGR_TYPE
(
ttl
))
else
if
(
IS_AGGR_TYPE
(
ttl
))
{
{
if
(
nptrs
<
0
)
if
(
nptrs
<
0
)
return
0
;
return
0
;
return
comptypes
(
TYPE_POINTER_TO
(
ttl
),
TYPE_POINTER_TO
(
ttr
),
0
);
if
(
comptypes
(
TYPE_POINTER_TO
(
ttl
),
TYPE_POINTER_TO
(
ttr
),
0
))
return
1
;
if
(
comptypes
(
TYPE_POINTER_TO
(
ttr
),
TYPE_POINTER_TO
(
ttl
),
0
))
return
-
1
;
return
0
;
}
}
return
0
;
return
0
;
...
@@ -1223,7 +1226,7 @@ c_sizeof_nowarn (type)
...
@@ -1223,7 +1226,7 @@ c_sizeof_nowarn (type)
/* Convert in case a char is more than one unit. */
/* Convert in case a char is more than one unit. */
t
=
size_binop
(
CEIL_DIV_EXPR
,
TYPE_SIZE
(
type
),
t
=
size_binop
(
CEIL_DIV_EXPR
,
TYPE_SIZE
(
type
),
size_int
(
TYPE_PRECISION
(
char_type_node
)));
size_int
(
TYPE_PRECISION
(
char_type_node
)));
force_fit_type
(
t
,
0
);
force_fit_type
(
t
,
0
);
return
t
;
return
t
;
}
}
...
@@ -1665,7 +1668,14 @@ build_component_ref (datum, component, basetype_path, protect)
...
@@ -1665,7 +1668,14 @@ build_component_ref (datum, component, basetype_path, protect)
return
error_mark_node
;
return
error_mark_node
;
}
}
else
else
return
build
(
COMPONENT_REF
,
unknown_type_node
,
datum
,
fndecls
);
{
/* Just act like build_offset_ref, since the object does
not matter unless we're actually calling the function. */
tree
t
=
build_tree_list
(
error_mark_node
,
fndecls
);
TREE_TYPE
(
t
)
=
build_offset_type
(
basetype
,
unknown_type_node
);
return
t
;
}
}
}
#if 0
#if 0
...
@@ -2187,12 +2197,13 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
...
@@ -2187,12 +2197,13 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
if
(
TYPE_PTRMEMFUNC_P
(
TREE_TYPE
(
function
)))
if
(
TYPE_PTRMEMFUNC_P
(
TREE_TYPE
(
function
)))
{
{
tree
fntype
=
TYPE_PTRMEMFUNC_FN_TYPE
(
TREE_TYPE
(
function
));
tree
fntype
=
TYPE_PTRMEMFUNC_FN_TYPE
(
TREE_TYPE
(
function
));
tree
index
=
save_expr
(
convert
(
integer_type_node
,
tree
index
=
save_expr
(
build_component_ref
(
function
,
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
,
integer_type_node
,
index
,
integer_zero_node
);
convert
(
delta_type_node
,
integer_zero_node
));
tree
delta
=
build_component_ref
(
function
,
delta_identifier
,
0
,
0
);
tree
delta
=
convert
(
ptrdiff_type_node
,
build_component_ref
(
function
,
delta_identifier
,
0
,
0
));
tree
delta2
=
DELTA2_FROM_PTRMEMFUNC
(
function
);
tree
delta2
=
DELTA2_FROM_PTRMEMFUNC
(
function
);
tree
e2
;
tree
e2
;
tree
e3
;
tree
e3
;
...
@@ -2208,11 +2219,11 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
...
@@ -2208,11 +2219,11 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
vtbl
vtbl
=
build
(
PLUS_EXPR
,
=
build
(
PLUS_EXPR
,
build_pointer_type
(
build_pointer_type
(
vtable_entry_type
)),
build_pointer_type
(
build_pointer_type
(
vtable_entry_type
)),
vtbl
,
convert
(
sizetyp
e
,
delta2
));
vtbl
,
convert
(
ptrdiff_type_nod
e
,
delta2
));
vtbl
=
build_indirect_ref
(
vtbl
,
NULL_PTR
);
vtbl
=
build_indirect_ref
(
vtbl
,
NULL_PTR
);
aref
=
build_array_ref
(
vtbl
,
size_bin
op
(
MINUS_EXPR
,
aref
=
build_array_ref
(
vtbl
,
build_binary_
op
(
MINUS_EXPR
,
index
,
index
,
integer_one_node
));
integer_one_node
,
1
));
if
(
!
flag_vtable_thunks
)
if
(
!
flag_vtable_thunks
)
{
{
aref
=
save_expr
(
aref
);
aref
=
save_expr
(
aref
);
...
@@ -2222,14 +2233,14 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
...
@@ -2222,14 +2233,14 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
if
(
/* !building_cleanup && */
TREE_CODE
(
aref
)
==
INDIRECT_REF
)
if
(
/* !building_cleanup && */
TREE_CODE
(
aref
)
==
INDIRECT_REF
)
TREE_OPERAND
(
aref
,
0
)
=
save_expr
(
TREE_OPERAND
(
aref
,
0
));
TREE_OPERAND
(
aref
,
0
)
=
save_expr
(
TREE_OPERAND
(
aref
,
0
));
delta
=
build
(
PLUS_EXPR
,
integer_type_node
,
delta
=
build
_binary_op
(
PLUS_EXPR
,
build_conditional_expr
(
e1
,
build_component_ref
(
aref
,
delta_identifier
,
0
,
0
),
integer_zero_node
),
build_conditional_expr
(
e1
,
build_component_ref
(
aref
,
delta_identifier
,
0
,
0
),
integer_zero_node
),
delta
);
delta
,
1
);
}
}
*
instance_ptrptr
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
*
instance_ptrptr
),
*
instance_ptrptr
=
build
(
PLUS_EXPR
,
TREE_TYPE
(
*
instance_ptrptr
),
*
instance_ptrptr
,
*
instance_ptrptr
,
convert
(
integer_type_node
,
delta
)
);
delta
);
if
(
flag_vtable_thunks
)
if
(
flag_vtable_thunks
)
e2
=
aref
;
e2
=
aref
;
else
else
...
@@ -3162,7 +3173,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
...
@@ -3162,7 +3173,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
tree
delta21
=
DELTA2_FROM_PTRMEMFUNC
(
op1
);
tree
delta21
=
DELTA2_FROM_PTRMEMFUNC
(
op1
);
tree
e1
,
e2
,
e3
;
tree
e1
,
e2
,
e3
;
tree
integer_neg_one_node
tree
integer_neg_one_node
=
size_binop
(
MINUS_EXPR
,
integer_zero_node
,
integer_one_node
);
=
build_binary_op
(
MINUS_EXPR
,
integer_zero_node
,
integer_one_node
,
1
);
e1
=
build_binary_op
(
EQ_EXPR
,
index0
,
index1
,
1
);
e1
=
build_binary_op
(
EQ_EXPR
,
index0
,
index1
,
1
);
e2
=
build_binary_op
(
NE_EXPR
,
index1
,
integer_neg_one_node
,
1
);
e2
=
build_binary_op
(
NE_EXPR
,
index1
,
integer_neg_one_node
,
1
);
e2
=
build_binary_op
(
TRUTH_ANDIF_EXPR
,
e2
,
build_binary_op
(
EQ_EXPR
,
delta20
,
delta21
,
1
),
1
);
e2
=
build_binary_op
(
TRUTH_ANDIF_EXPR
,
e2
,
build_binary_op
(
EQ_EXPR
,
delta20
,
delta21
,
1
),
1
);
...
@@ -3183,7 +3194,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
...
@@ -3183,7 +3194,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
tree
delta21
=
integer_zero_node
;
tree
delta21
=
integer_zero_node
;
tree
e1
,
e2
,
e3
;
tree
e1
,
e2
,
e3
;
tree
integer_neg_one_node
tree
integer_neg_one_node
=
size_binop
(
MINUS_EXPR
,
integer_zero_node
,
integer_one_node
);
=
build_binary_op
(
MINUS_EXPR
,
integer_zero_node
,
integer_one_node
,
1
);
if
(
TREE_CODE
(
TREE_OPERAND
(
op1
,
0
))
==
FUNCTION_DECL
if
(
TREE_CODE
(
TREE_OPERAND
(
op1
,
0
))
==
FUNCTION_DECL
&&
DECL_VINDEX
(
TREE_OPERAND
(
op1
,
0
)))
&&
DECL_VINDEX
(
TREE_OPERAND
(
op1
,
0
)))
{
{
...
@@ -3828,9 +3839,17 @@ build_unary_op (code, xarg, noconvert)
...
@@ -3828,9 +3839,17 @@ build_unary_op (code, xarg, noconvert)
errstring
=
"wrong type argument to unary plus"
;
errstring
=
"wrong type argument to unary plus"
;
else
if
(
!
noconvert
)
else
if
(
!
noconvert
)
arg
=
default_conversion
(
arg
);
arg
=
default_conversion
(
arg
);
arg
=
build1
(
NON_LVALUE_EXPR
,
TREE_TYPE
(
arg
),
arg
);
break
;
break
;
case
NEGATE_EXPR
:
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
(
isaggrtype
)
{
{
if
(
!
noconvert
)
if
(
!
noconvert
)
...
@@ -3852,6 +3871,13 @@ build_unary_op (code, xarg, noconvert)
...
@@ -3852,6 +3871,13 @@ build_unary_op (code, xarg, noconvert)
break
;
break
;
case
BIT_NOT_EXPR
:
case
BIT_NOT_EXPR
:
if
(
typecode
==
OFFSET_TYPE
)
{
arg
=
resolve_offset_ref
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
isaggrtype
=
IS_AGGR_TYPE_CODE
(
typecode
);
}
if
(
isaggrtype
)
if
(
isaggrtype
)
{
{
if
(
!
noconvert
)
if
(
!
noconvert
)
...
@@ -3873,6 +3899,13 @@ build_unary_op (code, xarg, noconvert)
...
@@ -3873,6 +3899,13 @@ build_unary_op (code, xarg, noconvert)
break
;
break
;
case
ABS_EXPR
:
case
ABS_EXPR
:
if
(
typecode
==
OFFSET_TYPE
)
{
arg
=
resolve_offset_ref
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
isaggrtype
=
IS_AGGR_TYPE_CODE
(
typecode
);
}
if
(
isaggrtype
)
if
(
isaggrtype
)
{
{
if
(
!
noconvert
)
if
(
!
noconvert
)
...
@@ -3917,6 +3950,13 @@ build_unary_op (code, xarg, noconvert)
...
@@ -3917,6 +3950,13 @@ build_unary_op (code, xarg, noconvert)
/* Report invalid types. */
/* Report invalid types. */
if
(
typecode
==
OFFSET_TYPE
)
{
arg
=
resolve_offset_ref
(
arg
);
typecode
=
TREE_CODE
(
TREE_TYPE
(
arg
));
isaggrtype
=
IS_AGGR_TYPE_CODE
(
typecode
);
}
if
(
isaggrtype
)
if
(
isaggrtype
)
{
{
arg
=
default_conversion
(
arg
);
arg
=
default_conversion
(
arg
);
...
@@ -4012,9 +4052,6 @@ build_unary_op (code, xarg, noconvert)
...
@@ -4012,9 +4052,6 @@ build_unary_op (code, xarg, noconvert)
}
}
}
}
if
(
TREE_CODE
(
arg
)
==
OFFSET_REF
)
arg
=
resolve_offset_ref
(
arg
);
/* Complain about anything else that is not a true lvalue. */
/* Complain about anything else that is not a true lvalue. */
if
(
!
lvalue_or_else
(
arg
,
((
code
==
PREINCREMENT_EXPR
if
(
!
lvalue_or_else
(
arg
,
((
code
==
PREINCREMENT_EXPR
||
code
==
POSTINCREMENT_EXPR
)
||
code
==
POSTINCREMENT_EXPR
)
...
@@ -4244,7 +4281,9 @@ unary_complex_lvalue (code, arg)
...
@@ -4244,7 +4281,9 @@ unary_complex_lvalue (code, arg)
if
(
TREE_CODE
(
arg
)
==
COND_EXPR
)
if
(
TREE_CODE
(
arg
)
==
COND_EXPR
)
return
rationalize_conditional_expr
(
code
,
arg
);
return
rationalize_conditional_expr
(
code
,
arg
);
if
(
TREE_CODE
(
arg
)
==
MODIFY_EXPR
)
if
(
TREE_CODE
(
arg
)
==
MODIFY_EXPR
||
TREE_CODE
(
arg
)
==
PREINCREMENT_EXPR
||
TREE_CODE
(
arg
)
==
PREDECREMENT_EXPR
)
return
unary_complex_lvalue
return
unary_complex_lvalue
(
code
,
build
(
COMPOUND_EXPR
,
TREE_TYPE
(
TREE_OPERAND
(
arg
,
0
)),
(
code
,
build
(
COMPOUND_EXPR
,
TREE_TYPE
(
TREE_OPERAND
(
arg
,
0
)),
arg
,
TREE_OPERAND
(
arg
,
0
)));
arg
,
TREE_OPERAND
(
arg
,
0
)));
...
@@ -4499,7 +4538,7 @@ build_conditional_expr (ifexp, op1, op2)
...
@@ -4499,7 +4538,7 @@ build_conditional_expr (ifexp, op1, op2)
ifexp
=
op1
=
save_expr
(
ifexp
);
ifexp
=
op1
=
save_expr
(
ifexp
);
}
}
ifexp
=
bool_truthvalue_conversion
(
default_conversion
(
ifexp
)
);
ifexp
=
bool_truthvalue_conversion
(
ifexp
);
if
(
TREE_CODE
(
ifexp
)
==
ERROR_MARK
)
if
(
TREE_CODE
(
ifexp
)
==
ERROR_MARK
)
return
error_mark_node
;
return
error_mark_node
;
...
@@ -5780,8 +5819,7 @@ build_modify_expr (lhs, modifycode, rhs)
...
@@ -5780,8 +5819,7 @@ build_modify_expr (lhs, modifycode, rhs)
int
from_array
;
int
from_array
;
/* Allow array assignment in compiler-generated code. */
/* Allow array assignment in compiler-generated code. */
if
((
pedantic
||
flag_ansi
)
if
(
pedantic
&&
!
DECL_ARTIFICIAL
(
current_function_decl
))
&&
!
DECL_ARTIFICIAL
(
current_function_decl
))
pedwarn
(
"ANSI C++ forbids assignment of arrays"
);
pedwarn
(
"ANSI C++ forbids assignment of arrays"
);
/* Have to wrap this in RTL_EXPR for two cases:
/* Have to wrap this in RTL_EXPR for two cases:
...
@@ -6010,9 +6048,9 @@ get_delta_difference (from, to, force)
...
@@ -6010,9 +6048,9 @@ get_delta_difference (from, to, force)
{
{
warning
(
"pointer to member conversion to virtual base class will only work if your very careful"
);
warning
(
"pointer to member conversion to virtual base class will only work if your very careful"
);
}
}
return
fold
(
size_bin
op
(
MINUS_EXPR
,
return
build_binary_
op
(
MINUS_EXPR
,
integer_zero_node
,
integer_zero_node
,
BINFO_OFFSET
(
binfo
))
);
BINFO_OFFSET
(
binfo
),
1
);
}
}
if
(
TREE_VIA_VIRTUAL
(
binfo
))
if
(
TREE_VIA_VIRTUAL
(
binfo
))
{
{
...
@@ -6069,14 +6107,14 @@ build_ptrmemfunc (type, pfn, force)
...
@@ -6069,14 +6107,14 @@ build_ptrmemfunc (type, pfn, force)
if
(
TREE_CODE
(
pfn
)
!=
CONSTRUCTOR
)
if
(
TREE_CODE
(
pfn
)
!=
CONSTRUCTOR
)
{
{
tree
e1
,
e2
,
e3
;
tree
e1
,
e2
,
e3
;
ndelta
=
convert
(
sizetyp
e
,
build_component_ref
(
pfn
,
delta_identifier
,
0
,
0
));
ndelta
=
convert
(
ptrdiff_type_nod
e
,
build_component_ref
(
pfn
,
delta_identifier
,
0
,
0
));
ndelta2
=
convert
(
sizetyp
e
,
DELTA2_FROM_PTRMEMFUNC
(
pfn
));
ndelta2
=
convert
(
ptrdiff_type_nod
e
,
DELTA2_FROM_PTRMEMFUNC
(
pfn
));
index
=
build_component_ref
(
pfn
,
index_identifier
,
0
,
0
);
index
=
build_component_ref
(
pfn
,
index_identifier
,
0
,
0
);
delta
=
get_delta_difference
(
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
TYPE_PTRMEMFUNC_FN_TYPE
(
TREE_TYPE
(
pfn
)))),
delta
=
get_delta_difference
(
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
TYPE_PTRMEMFUNC_FN_TYPE
(
TREE_TYPE
(
pfn
)))),
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
type
)),
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
type
)),
force
);
force
);
delta
=
fold
(
size_binop
(
PLUS_EXPR
,
delta
,
ndelta
)
);
delta
=
build_binary_op
(
PLUS_EXPR
,
delta
,
ndelta
,
1
);
delta2
=
fold
(
size_binop
(
PLUS_EXPR
,
ndelta2
,
delta2
)
);
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
,
integer_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
));
...
@@ -6136,7 +6174,7 @@ build_ptrmemfunc (type, pfn, force)
...
@@ -6136,7 +6174,7 @@ build_ptrmemfunc (type, pfn, force)
delta
=
get_delta_difference
(
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
TREE_TYPE
(
pfn
))),
delta
=
get_delta_difference
(
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
TREE_TYPE
(
pfn
))),
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
type
)),
TYPE_METHOD_BASETYPE
(
TREE_TYPE
(
type
)),
force
);
force
);
delta2
=
fold
(
size_binop
(
PLUS_EXPR
,
delta2
,
delta
)
);
delta2
=
build_binary_op
(
PLUS_EXPR
,
delta2
,
delta
,
1
);
if
(
TREE_CODE
(
TREE_OPERAND
(
pfn
,
0
))
!=
FUNCTION_DECL
)
if
(
TREE_CODE
(
TREE_OPERAND
(
pfn
,
0
))
!=
FUNCTION_DECL
)
warning
(
"assuming pointer to member function is non-virtual"
);
warning
(
"assuming pointer to member function is non-virtual"
);
...
@@ -6159,7 +6197,7 @@ build_ptrmemfunc (type, pfn, force)
...
@@ -6159,7 +6197,7 @@ build_ptrmemfunc (type, pfn, force)
}
}
else
else
{
{
index
=
fold
(
size_binop
(
MINUS_EXPR
,
integer_zero_node
,
integer_one_node
)
);
index
=
size_binop
(
MINUS_EXPR
,
integer_zero_node
,
integer_one_node
);
npfn
=
build1
(
NOP_EXPR
,
type
,
pfn
);
npfn
=
build1
(
NOP_EXPR
,
type
,
pfn
);
TREE_CONSTANT
(
npfn
)
=
TREE_CONSTANT
(
pfn
);
TREE_CONSTANT
(
npfn
)
=
TREE_CONSTANT
(
pfn
);
...
@@ -6306,6 +6344,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
...
@@ -6306,6 +6344,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
{
{
register
tree
ttl
=
TREE_TYPE
(
type
);
register
tree
ttl
=
TREE_TYPE
(
type
);
register
tree
ttr
;
register
tree
ttr
;
int
ctt
=
0
;
if
(
coder
==
RECORD_TYPE
)
if
(
coder
==
RECORD_TYPE
)
{
{
...
@@ -6358,7 +6397,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
...
@@ -6358,7 +6397,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
Meanwhile, the lhs target must have all the qualifiers of the rhs. */
Meanwhile, the lhs target must have all the qualifiers of the rhs. */
else
if
(
TYPE_MAIN_VARIANT
(
ttl
)
==
void_type_node
else
if
(
TYPE_MAIN_VARIANT
(
ttl
)
==
void_type_node
||
TYPE_MAIN_VARIANT
(
ttr
)
==
void_type_node
||
TYPE_MAIN_VARIANT
(
ttr
)
==
void_type_node
||
comp_target_types
(
type
,
rhstype
,
1
)
||
(
ctt
=
comp_target_types
(
type
,
rhstype
,
1
)
)
||
(
unsigned_type
(
TYPE_MAIN_VARIANT
(
ttl
))
||
(
unsigned_type
(
TYPE_MAIN_VARIANT
(
ttl
))
==
unsigned_type
(
TYPE_MAIN_VARIANT
(
ttr
))))
==
unsigned_type
(
TYPE_MAIN_VARIANT
(
ttr
))))
{
{
...
@@ -6366,17 +6405,21 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
...
@@ -6366,17 +6405,21 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if
(
TYPE_MAIN_VARIANT
(
ttl
)
==
void_type_node
if
(
TYPE_MAIN_VARIANT
(
ttl
)
==
void_type_node
&&
TREE_CODE
(
ttr
)
==
OFFSET_TYPE
)
&&
TREE_CODE
(
ttr
)
==
OFFSET_TYPE
)
{
{
error
(
"no standard conversion from pointer to member to `void *'"
);
cp_error
(
"no standard conversion from `%T' to `void *'"
,
ttr
);
return
error_mark_node
;
return
error_mark_node
;
}
}
if
(
ctt
<
0
)
cp_pedwarn
(
"converting `%T' to `%T' is a contravariance violation"
,
ttr
,
ttl
);
if
(
TYPE_MAIN_VARIANT
(
ttl
)
!=
void_type_node
if
(
TYPE_MAIN_VARIANT
(
ttl
)
!=
void_type_node
&&
TYPE_MAIN_VARIANT
(
ttr
)
==
void_type_node
&&
TYPE_MAIN_VARIANT
(
ttr
)
==
void_type_node
&&
rhs
!=
null_pointer_node
)
&&
rhs
!=
null_pointer_node
)
{
{
if
(
coder
==
RECORD_TYPE
)
if
(
coder
==
RECORD_TYPE
)
pedwarn
(
"implicit conversion of signature pointer to type `%s
'"
,
cp_pedwarn
(
"implicit conversion of signature pointer to type `%T
'"
,
type_as_string
(
type
,
0
)
);
type
);
else
else
pedwarn
(
"ANSI C++ forbids implicit conversion from `void *' in %s"
,
pedwarn
(
"ANSI C++ forbids implicit conversion from `void *' in %s"
,
errtype
);
errtype
);
...
@@ -6481,7 +6524,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
...
@@ -6481,7 +6524,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
ttl
=
unsigned_type
(
ttl
);
ttl
=
unsigned_type
(
ttl
);
}
}
if
(
comp_target_types
(
ttl
,
ttr
,
nptrs
))
if
(
comp_target_types
(
ttl
,
ttr
,
nptrs
)
>
0
)
{
{
if
(
add_quals
)
if
(
add_quals
)
{
{
...
@@ -6585,7 +6628,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
...
@@ -6585,7 +6628,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
}
}
return
null_pointer_node
;
return
null_pointer_node
;
}
}
else
if
(
(
codel
==
INTEGER_TYPE
||
codel
==
BOOLEAN_TYPE
)
else
if
(
codel
==
INTEGER_TYPE
&&
(
coder
==
POINTER_TYPE
&&
(
coder
==
POINTER_TYPE
||
(
coder
==
RECORD_TYPE
||
(
coder
==
RECORD_TYPE
&&
(
IS_SIGNATURE_POINTER
(
rhstype
)
&&
(
IS_SIGNATURE_POINTER
(
rhstype
)
...
@@ -6600,6 +6643,13 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
...
@@ -6600,6 +6643,13 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
errtype
,
type
,
rhstype
);
errtype
,
type
,
rhstype
);
return
convert
(
type
,
rhs
);
return
convert
(
type
,
rhs
);
}
}
else
if
(
codel
==
BOOLEAN_TYPE
&&
(
coder
==
POINTER_TYPE
||
(
coder
==
RECORD_TYPE
&&
(
IS_SIGNATURE_POINTER
(
rhstype
)
||
TYPE_PTRMEMFUNC_FLAG
(
rhstype
)
||
IS_SIGNATURE_REFERENCE
(
rhstype
)))))
return
convert
(
type
,
rhs
);
/* C++ */
/* C++ */
else
if
(((
coder
==
POINTER_TYPE
&&
TREE_CODE
(
rhs
)
==
ADDR_EXPR
else
if
(((
coder
==
POINTER_TYPE
&&
TREE_CODE
(
rhs
)
==
ADDR_EXPR
...
...
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