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
28cbf42c
Commit
28cbf42c
authored
Mar 23, 1995
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
59th Cygnus<->FSF merge
From-SVN: r9225
parent
e96a50cc
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
618 additions
and
190 deletions
+618
-190
gcc/cp/ChangeLog
+185
-0
gcc/cp/Makefile.in
+1
-0
gcc/cp/call.c
+1
-1
gcc/cp/class.c
+13
-43
gcc/cp/cp-tree.h
+1
-1
gcc/cp/cvt.c
+12
-0
gcc/cp/decl.c
+79
-36
gcc/cp/decl2.c
+74
-43
gcc/cp/error.c
+7
-0
gcc/cp/expr.c
+82
-1
gcc/cp/init.c
+5
-1
gcc/cp/lex.c
+9
-1
gcc/cp/method.c
+14
-3
gcc/cp/parse.y
+6
-2
gcc/cp/pt.c
+24
-2
gcc/cp/tree.c
+2
-0
gcc/cp/typeck.c
+103
-56
No files found.
gcc/cp/ChangeLog
View file @
28cbf42c
Wed Mar 22 15:10:34 1995 Mike Stump <mrs@cygnus.com>
* decl2.c (finish_prevtable_vardecl, finish_vtable_vardecl): Revert
Brendan's last change and fix latent problem that causes TD entries
to not come out when the things that need them has yet to be
expanded.
Wed Mar 22 15:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_binary_op_nodefault, comparison ops): Update type0
and type1, since we might have changed op0 or op1.
Wed Mar 22 13:33:45 1995 Jason Merrill <jason@python.cygnus.com>
* typeck.c (common_type): Don't mess up templates.
Wed Mar 22 04:56:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (common_type): Handle ptms properly. Also handle
T* -> void*.
(build_binary_op_nodefault): New variable build_type controls what
type is given to the expression when it is created. Set this to
boolean_type_node for comparison ops instead of using result_type.
(comp_target_types): Allow T * -> void *.
* cvt.c (cp_convert_to_pointer): Do access control when converting
ptms, too.
Tue Mar 21 17:25:06 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* parse.y (extern_lang_string): Catch use of linkage specs that
aren't all naming the same language.
* class.c (finish_struct): Delete accidental duplicate code.
Tue Mar 21 14:00:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_binary_op_nodefault): Disable pedwarns about
comparing functions and incomplete types.
* decl.c (finish_function): Only unset current_function_decl if
!nested.
(duplicate_decls): Last change went too far; we only want to stop
checking for value/reference ambiguity.
Tue Mar 21 01:26:39 1995 Mike Stump <mrs@cygnus.com>
* gc.c (build_generic_desc): Zap the DECL_SIZE so that we can lay it
out fresh, as the new type may be larger.
Mon Mar 20 19:01:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* expr.c (extract_init): Try to expand the RTL for the
initialization and figure out what it will look like so we can avoid
run-time initialization. Disabled for now.
(extract_scalar_init): Helper for scalar initialization.
(extract_aggr_init): Helper for aggregate initialization.
* decl.c (duplicate_decls): Don't complain about ambiguous
declarations.
(obscure_complex_init): Now returns a tree. Call extract_init if
we're optimizing and this is a toplevel decl.
(finish_decl): Update accordingly.
* lex.c (check_newline): If we're just changing files (not pushing
or popping), update input_file_stack->name.
Mon Mar 20 17:55:04 1995 Mike Stump <mrs@cygnus.com>
* pt.c (type_unification): Only TEMPLATE_DECLs are handled right now
in the transitive unification code.
Mon Mar 20 16:07:50 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (shadow_tag): Don't allow inline, virtual, or explicit on
non-functions.
(grokdeclarator): Don't allow friends to be defined in local classes.
Sat Mar 18 04:03:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (finish_prevtable_vardecl): Use DECL_DECLARED_STATIC
rather than DECL_SAVED_INSNS to decide whether or not this method
was declared inline.
* method.c (synthesize_method): Turn off DECL_INLINE if
function_cannot_inline_p thinks we're too large.
* typeck.c (build_indirect_ref): Use build_expr_type_conversion.
Fri Mar 17 17:47:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* class.c (instantiate_type): Handle pmfs.
* typeck.c (convert_for_assignment): Check types when assigning one
pmf to another.
* decl.c (define_label): Fix logic for printing out the name of the
label in an error message.
* error.c (dump_expr): Support ARRAY_REF.
Fri Mar 17 17:43:02 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl2.c (finish_vtable_vardecl): Call build_t_desc here.
(finish_prevtable_vardecl): Instead of here.
Fri Mar 17 14:40:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (expand_static_init): Also use expand_aggr_init if the
initializer is a TREE_LIST.
(grokdeclarator): Only pedwarn about extra qualification if -pedantic.
* pt.c (unify): Fix unification of return type.
* expr.c (fixup_result_decl): Use store_expr, rather than
emit_move_insn, to move the return value into the place where
callers will expect it.
Thu Mar 16 22:05:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* init.c (build_offset_ref): Call assmble_external on functions.
* typeck.c (build_component_ref): Ditto.
Thu Mar 16 20:28:16 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (struct saved_scope): Add members base_init_list and
member_init_list.
(push_to_top_level): Save current_base_init_list and
current_member_init_list to them.
(pop_from_top_level): Put it back.
Thu Mar 16 19:21:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* pt.c (instantiate_template): Call assemble_external.
Thu Mar 16 18:07:54 1995 Brendan Kehoe (brendan@phydeaux.cygnus.com)
* class.c: Include rtl.h, to get NULL_RTX.
(finish_struct): Also zero out DECL_SAVED_INSNS, to avoid problems
on hosts with different sizes for each part of the union.
* tree.c: Also include rtl.h.
(layout_basetypes): Same change for DECL_SAVED_INSNS.
Thu Mar 16 13:57:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* pt.c (unify): Fix array domain unification for 64-bit targets.
* decl2.c (finish_file): Push bizarre type decl before walking the
vtables the first time.
(walk_vtables): OK, don't set prev to vars if the vardecl_fn messed
with TREE_CHAIN (prev).
* init.c (emit_base_init): Use convert_pointer_to_real instead of
convert_pointer_to when converting to a direct base.
Wed Mar 15 20:26:29 1995 Mike Stump <mrs@cygnus.com>
* pt.c (type_unification): Handle transitive unification better.
Wed Mar 15 13:56:16 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (walk_vtables): Always set prev to vars.
(mark_vtable_entries): Call assemble_external on the vtable entries.
* class.c (finish_struct): Set the vtable's size to NULL_TREE before
calling layout_decl, so that it gets updated properly.
Finally re-enable dynamic synthesis. This time it works.
* method.c (synthesize_method): Pass decl_function_context (fndecl)
to {push,pop}_cp_function_context.
* decl.c (push_cp_function_context): Now takes a tree argument.
(pop_cp_function_context): Ditto.
* call.c (build_method_call): Enable synthesis.
* lex.c (cons_up_default_function): Ditto.
Tue Mar 14 19:14:19 1995 Doug Evans <dje@chestnut.cygnus.com>
* parse.y (setattrs): Chain onto prefix_attributes rather than
setting it.
Wed Mar 15 13:00:00 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (pushdecl): Check if the type of the VAR_DECL is an
error_mark_node before trying to read TYPE_LANG_SPECIFIC.
Mon Mar 13 21:00:28 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator, case ARRAY_REF): Wrap the exp with fold,
...
...
gcc/cp/Makefile.in
View file @
28cbf42c
...
...
@@ -167,6 +167,7 @@ OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o
compiler
:
../cc1plus
../cc1plus
:
$(P) $(CXX_OBJS) $(OBJDEPS) $(LIBDEPS)
rm
-f
$@
$(CC)
$(ALL_CFLAGS)
$(LDFLAGS)
-o
../cc1plus
\
$(CXX_OBJS)
$(OBJS)
$(LIBS)
...
...
gcc/cp/call.c
View file @
28cbf42c
...
...
@@ -2379,7 +2379,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* Declare external function if necessary. */
assemble_external
(
function
);
#if
0
#if
1
/* Is it a synthesized method that needs to be synthesized? */
if
(
DECL_ARTIFICIAL
(
function
)
&&
!
flag_no_inline
&&
DECL_SAVED_INSNS
(
function
)
==
0
...
...
gcc/cp/class.c
View file @
28cbf42c
...
...
@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "cp-tree.h"
#include "flags.h"
#include "rtl.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
...
...
@@ -2963,6 +2964,11 @@ finish_struct (t, list_of_fieldlists, warn_anon)
DECL_CLASS_CONTEXT
(
x
)
=
t
;
/* Do both of these, even though they're in the same union;
if the insn `r' member and the size `i' member are
different sizes, as on the alpha, the larger of the two
will end up with garbage in it. */
DECL_SAVED_INSNS
(
x
)
=
NULL_RTX
;
DECL_FIELD_SIZE
(
x
)
=
0
;
/* The name of the field is the original field name
...
...
@@ -3027,6 +3033,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
fields
=
x
;
last_x
=
x
;
DECL_SAVED_INSNS
(
x
)
=
NULL_RTX
;
DECL_FIELD_SIZE
(
x
)
=
0
;
/* When this goes into scope, it will be a non-local reference. */
...
...
@@ -3505,6 +3512,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
DECL_FIELD_CONTEXT
(
vfield
)
=
t
;
DECL_CLASS_CONTEXT
(
vfield
)
=
t
;
DECL_FCONTEXT
(
vfield
)
=
t
;
DECL_SAVED_INSNS
(
vfield
)
=
NULL_RTX
;
DECL_FIELD_SIZE
(
vfield
)
=
0
;
DECL_ALIGN
(
vfield
)
=
TYPE_ALIGN
(
ptr_type_node
);
if
(
CLASSTYPE_RTTI
(
t
))
...
...
@@ -3576,47 +3584,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_ALIGN
(
t
)
=
round_up_size
;
/* Pass layout information about base classes to layout_type, if any. */
{
tree
field
;
for
(
field
=
TYPE_FIELDS
(
t
);
field
;
field
=
TREE_CHAIN
(
field
))
{
if
(
TREE_STATIC
(
field
))
continue
;
if
(
TREE_CODE
(
field
)
!=
FIELD_DECL
)
continue
;
/* If this field is an anonymous union,
give each union-member the same position as the union has.
??? This is a real kludge because it makes the structure
of the types look strange. This feature is only used by
C++, which should have build_component_ref build two
COMPONENT_REF operations, one for the union and one for
the inner field. We set the offset of this field to zero
so that either the old or the correct method will work.
Setting DECL_FIELD_CONTEXT is wrong unless the inner fields are
moved into the type of this field, but nothing seems to break
by doing this. */
if
(
DECL_NAME
(
field
)
==
NULL_TREE
&&
TREE_CODE
(
TREE_TYPE
(
field
))
==
UNION_TYPE
)
{
tree
uelt
=
TYPE_FIELDS
(
TREE_TYPE
(
field
));
for
(;
uelt
;
uelt
=
TREE_CHAIN
(
uelt
))
{
if
(
TREE_CODE
(
uelt
)
!=
FIELD_DECL
)
continue
;
DECL_FIELD_CONTEXT
(
uelt
)
=
DECL_FIELD_CONTEXT
(
field
);
DECL_FIELD_BITPOS
(
uelt
)
=
DECL_FIELD_BITPOS
(
field
);
}
DECL_FIELD_BITPOS
(
field
)
=
integer_zero_node
;
}
}
}
if
(
n_baseclasses
)
{
tree
pseudo_basetype
=
TREE_TYPE
(
base_layout_decl
);
...
...
@@ -3911,6 +3878,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
if
(
TREE_TYPE
(
TYPE_BINFO_VTABLE
(
t
))
!=
atype
)
{
TREE_TYPE
(
TYPE_BINFO_VTABLE
(
t
))
=
atype
;
DECL_SIZE
(
TYPE_BINFO_VTABLE
(
t
))
=
0
;
layout_decl
(
TYPE_BINFO_VTABLE
(
t
),
0
);
/* At one time the vtable info was grabbed 2 words at a time. This
fails on sparc unless you have 8-byte alignment. (tiemann) */
...
...
@@ -4726,6 +4694,9 @@ instantiate_type (lhstype, rhs, complain)
functions or member functions. May have to undo what
`default_conversion' might do to lhstype. */
if
(
TYPE_PTRMEMFUNC_P
(
lhstype
))
lhstype
=
TYPE_PTRMEMFUNC_FN_TYPE
(
lhstype
);
if
(
TREE_CODE
(
lhstype
)
==
POINTER_TYPE
)
if
(
TREE_CODE
(
TREE_TYPE
(
lhstype
))
==
FUNCTION_TYPE
||
TREE_CODE
(
TREE_TYPE
(
lhstype
))
==
METHOD_TYPE
)
...
...
@@ -4884,8 +4855,7 @@ instantiate_type (lhstype, rhs, complain)
#endif
}
if
(
complain
)
error
(
"no compatible member functions named `%s'"
,
IDENTIFIER_POINTER
(
name
));
cp_error
(
"no compatible member functions named `%D'"
,
name
);
return
error_mark_node
;
}
...
...
gcc/cp/cp-tree.h
View file @
28cbf42c
/* Definitions for C++ parsing and type checking.
Copyright (C) 1987, 1993, 1995 Free Software Foundation, Inc.
Copyright (C) 1987, 1993, 199
4, 199
5 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
...
...
gcc/cp/cvt.c
View file @
28cbf42c
...
...
@@ -155,6 +155,18 @@ cp_convert_to_pointer (type, expr)
&&
TREE_CODE
(
TREE_TYPE
(
intype
))
==
METHOD_TYPE
)
return
convert_fn_ptr
(
type
,
expr
);
if
(
TREE_CODE
(
TREE_TYPE
(
type
))
==
OFFSET_TYPE
&&
TREE_CODE
(
TREE_TYPE
(
intype
))
==
OFFSET_TYPE
)
{
tree
b1
=
TYPE_OFFSET_BASETYPE
(
TREE_TYPE
(
type
));
tree
b2
=
TYPE_OFFSET_BASETYPE
(
TREE_TYPE
(
intype
));
tree
binfo
=
get_binfo
(
b1
,
b2
,
1
);
if
(
binfo
==
NULL_TREE
)
binfo
=
get_binfo
(
b2
,
b1
,
1
);
if
(
binfo
==
error_mark_node
)
return
error_mark_node
;
}
return
build1
(
NOP_EXPR
,
type
,
expr
);
}
...
...
gcc/cp/decl.c
View file @
28cbf42c
...
...
@@ -1443,6 +1443,7 @@ struct saved_scope {
tree
old_bindings
;
struct
saved_scope
*
prev
;
tree
class_name
,
class_type
,
class_decl
,
function_decl
;
tree
base_init_list
,
member_init_list
;
struct
binding_level
*
class_bindings
;
tree
previous_class_type
;
tree
*
lang_base
,
*
lang_stack
,
lang_name
;
...
...
@@ -1519,6 +1520,8 @@ push_to_top_level ()
s
->
class_type
=
current_class_type
;
s
->
class_decl
=
current_class_decl
;
s
->
function_decl
=
current_function_decl
;
s
->
base_init_list
=
current_base_init_list
;
s
->
member_init_list
=
current_member_init_list
;
s
->
class_bindings
=
class_binding_level
;
s
->
previous_class_type
=
previous_class_type
;
s
->
lang_stack
=
current_lang_stack
;
...
...
@@ -1571,6 +1574,8 @@ pop_from_top_level ()
C_C_D
=
CLASSTYPE_INST_VAR
(
current_class_type
);
else
C_C_D
=
NULL_TREE
;
current_base_init_list
=
s
->
base_init_list
;
current_member_init_list
=
s
->
member_init_list
;
current_function_decl
=
s
->
function_decl
;
class_binding_level
=
s
->
class_bindings
;
previous_class_type
=
s
->
previous_class_type
;
...
...
@@ -2230,7 +2235,7 @@ duplicate_decls (newdecl, olddecl)
cp_error_at
(
"previous declaration `%#D' here"
,
olddecl
);
}
else
if
(
compparms
(
TYPE_ARG_TYPES
(
TREE_TYPE
(
newdecl
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
olddecl
)),
2
))
TYPE_ARG_TYPES
(
TREE_TYPE
(
olddecl
)),
3
))
{
cp_error
(
"new declaration `%#D'"
,
newdecl
);
cp_error_at
(
"ambiguates old declaration `%#D'"
,
olddecl
);
...
...
@@ -3061,6 +3066,7 @@ pushdecl (x)
/* Keep count of variables in this level with incomplete type. */
/* RTTI TD entries are created while defining the type_info. */
if
(
TREE_CODE
(
x
)
==
VAR_DECL
&&
TREE_TYPE
(
x
)
!=
error_mark_node
&&
TYPE_LANG_SPECIFIC
(
TREE_TYPE
(
x
))
&&
TYPE_BEING_DEFINED
(
TREE_TYPE
(
x
)))
{
...
...
@@ -3606,6 +3612,7 @@ define_label (filename, line, name)
else
{
tree
uses
,
prev
;
int
identified
=
0
;
/* Mark label as having been defined. */
DECL_INITIAL
(
decl
)
=
error_mark_node
;
...
...
@@ -3636,10 +3643,11 @@ define_label (filename, line, name)
&&
DECL_INITIAL
(
new_decls
)
!=
error_mark_node
)
||
TYPE_NEEDS_CONSTRUCTING
(
TREE_TYPE
(
new_decls
))))
{
if
(
IDENTIFIER_ERROR_LOCUS
(
decl
)
==
NULL_TREE
)
cp_error
(
"invalid jump to label `%D'"
,
decl
);
SET_IDENTIFIER_ERROR_LOCUS
(
decl
,
current_function_decl
);
cp_error
(
"crosses initialization of `%D'"
,
new_decls
);
if
(
!
identified
)
cp_error
(
"jump to label `%D'"
,
decl
);
identified
=
1
;
cp_error_at
(
" crosses initialization of `%#D'"
,
new_decls
);
}
new_decls
=
TREE_CHAIN
(
new_decls
);
}
...
...
@@ -5259,7 +5267,10 @@ shadow_tag (declspecs)
else
if
(
value
==
ridpointers
[(
int
)
RID_STATIC
]
||
value
==
ridpointers
[(
int
)
RID_EXTERN
]
||
value
==
ridpointers
[(
int
)
RID_AUTO
]
||
value
==
ridpointers
[(
int
)
RID_REGISTER
])
||
value
==
ridpointers
[(
int
)
RID_REGISTER
]
||
value
==
ridpointers
[(
int
)
RID_INLINE
]
||
value
==
ridpointers
[(
int
)
RID_VIRTUAL
]
||
value
==
ridpointers
[(
int
)
RID_EXPLICIT
])
ob_modifier
=
value
;
}
...
...
@@ -5290,9 +5301,19 @@ shadow_tag (declspecs)
{
/* Anonymous unions are objects, that's why we only check for
inappropriate specifiers in this branch. */
if
(
ob_modifier
)
cp_error
(
"`%D' can only be specified for objects and functions"
,
ob_modifier
);
{
if
(
ob_modifier
==
ridpointers
[(
int
)
RID_INLINE
]
||
ob_modifier
==
ridpointers
[(
int
)
RID_VIRTUAL
])
cp_error
(
"`%D' can only be specified for functions"
,
ob_modifier
);
else
if
(
ob_modifier
==
ridpointers
[(
int
)
RID_EXPLICIT
])
cp_error
(
"`%D' can only be specified for constructors"
,
ob_modifier
);
else
cp_error
(
"`%D' can only be specified for objects and functions"
,
ob_modifier
);
}
if
(
found_tag
==
0
)
pedwarn
(
"abstract declarator used as declaration"
);
...
...
@@ -5837,16 +5858,24 @@ grok_reference_init (decl, type, init, cleanupp)
it in with a dummy CONSTRUCTOR to force the variable into .data;
otherwise we can use error_mark_node. */
static
void
obscure_complex_init
(
decl
)
tree
decl
;
static
tree
obscure_complex_init
(
decl
,
init
)
tree
decl
,
init
;
{
if
(
!
flag_no_inline
&&
TREE_STATIC
(
decl
))
{
if
(
extract_init
(
decl
,
init
))
return
NULL_TREE
;
}
if
(
current_binding_level
==
global_binding_level
&&
!
DECL_COMMON
(
decl
))
DECL_INITIAL
(
decl
)
=
build
(
CONSTRUCTOR
,
TREE_TYPE
(
decl
),
NULL_TREE
,
NULL_TREE
);
else
DECL_INITIAL
(
decl
)
=
error_mark_node
;
return
init
;
}
/* Finish processing of a declaration;
...
...
@@ -6078,22 +6107,18 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags)
}
}
#endif
/* We must hide the initializer so that expand_decl
won't try to do something it does not understand. */
obscure_complex_init
(
decl
);
}
else
{
dont_use_constructor:
if
(
TREE_CODE
(
init
)
!=
TREE_VEC
)
init
=
store_init_value
(
decl
,
init
);
/* Don't let anyone try to initialize this variable
until we are ready to do so. */
if
(
init
)
obscure_complex_init
(
decl
);
}
if
(
init
)
/* We must hide the initializer so that expand_decl
won't try to do something it does not understand. */
init
=
obscure_complex_init
(
decl
,
init
);
}
else
if
(
DECL_EXTERNAL
(
decl
))
;
...
...
@@ -6120,7 +6145,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags)
if
(
TYPE_SIZE
(
type
)
!=
NULL_TREE
&&
TYPE_NEEDS_CONSTRUCTING
(
type
))
obscure_complex_init
(
decl
);
init
=
obscure_complex_init
(
decl
,
NULL_TREE
);
}
else
if
(
TREE_CODE
(
decl
)
==
VAR_DECL
&&
TREE_CODE
(
type
)
!=
REFERENCE_TYPE
...
...
@@ -6589,7 +6614,8 @@ expand_static_init (decl, init)
integer_zero_node
,
1
),
0
);
old_cleanups
=
cleanups_this_call
;
expand_assignment
(
temp
,
integer_one_node
,
0
,
0
);
if
(
TYPE_NEEDS_CONSTRUCTING
(
TREE_TYPE
(
decl
)))
if
(
TYPE_NEEDS_CONSTRUCTING
(
TREE_TYPE
(
decl
))
||
TREE_CODE
(
init
)
==
TREE_LIST
)
{
expand_aggr_init
(
decl
,
init
,
0
,
0
);
do_pending_stack_adjust
();
...
...
@@ -8372,11 +8398,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
RIDBIT_RESET
(
RID_FRIEND
,
specbits
);
friendp
=
0
;
}
if
(
decl_context
==
NORMAL
)
error
(
"friend declaration not in class definition"
);
if
(
current_function_decl
&&
funcdef_flag
)
cp_error
(
"can't define friend function `%s' in a local class definition"
,
name
);
}
if
(
decl_context
==
NORMAL
&&
friendp
)
error
(
"friend declaration not in class definition"
);
/* Traditionally, declaring return type float means double. */
if
(
flag_traditional
...
...
@@ -8598,8 +8626,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
basetype :: member . */
if
(
ctype
==
current_class_type
)
cp_pedwarn
(
"extra qualification `%T::' on member `%s' ignored"
,
ctype
,
name
);
{
/* class A {
void A::f ();
};
Is this ill-formed? */
if
(
pedantic
)
cp_pedwarn
(
"extra qualification `%T::' on member `%s' ignored"
,
ctype
,
name
);
}
else
if
(
TREE_CODE
(
type
)
==
FUNCTION_TYPE
)
{
if
(
current_class_type
==
NULL_TREE
...
...
@@ -11307,7 +11344,7 @@ finish_function (lineno, call_poplevel, nested)
int
ok_to_optimize_dtor
=
0
;
if
(
current_function_assigns_this
)
cond
=
build
(
NE_EXPR
,
integer
_type_node
,
cond
=
build
(
NE_EXPR
,
boolean
_type_node
,
current_class_decl
,
integer_zero_node
);
else
{
...
...
@@ -11756,8 +11793,14 @@ finish_function (lineno, call_poplevel, nested)
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. */
current_function_decl
=
NULL_TREE
;
if
(
!
nested
)
{
/* Let the error reporting routines know that we're outside a
function. For a nested function, this value is used in
pop_cp_function_context and then reset via pop_function_context. */
current_function_decl
=
NULL_TREE
;
}
named_label_uses
=
NULL_TREE
;
}
...
...
@@ -12190,13 +12233,13 @@ struct cp_function *cp_function_chain;
used during compilation of a C++ function. */
void
push_cp_function_context
(
toplev
)
int
toplev
;
push_cp_function_context
(
context
)
tree
context
;
{
struct
cp_function
*
p
=
(
struct
cp_function
*
)
xmalloc
(
sizeof
(
struct
cp_function
));
push_function_context_to
(
toplev
);
push_function_context_to
(
context
);
p
->
next
=
cp_function_chain
;
cp_function_chain
=
p
;
...
...
@@ -12221,8 +12264,8 @@ push_cp_function_context (toplev)
/* Restore the variables used during compilation of a C++ function. */
void
pop_cp_function_context
(
toplev
)
int
toplev
;
pop_cp_function_context
(
context
)
tree
context
;
{
struct
cp_function
*
p
=
cp_function_chain
;
tree
link
;
...
...
@@ -12244,7 +12287,7 @@ pop_cp_function_context (toplev)
}
#endif
pop_function_context_from
(
toplev
);
pop_function_context_from
(
context
);
cp_function_chain
=
p
->
next
;
...
...
gcc/cp/decl2.c
View file @
28cbf42c
...
...
@@ -1932,7 +1932,8 @@ build_push_scope (cname, name)
return
rval
;
}
void
cplus_decl_attributes
(
decl
,
attributes
,
prefix_attributes
)
void
cplus_decl_attributes
(
decl
,
attributes
,
prefix_attributes
)
tree
decl
,
attributes
,
prefix_attributes
;
{
if
(
decl
&&
decl
!=
void_type_node
)
...
...
@@ -2463,7 +2464,14 @@ mark_vtable_entries (decl)
extern
tree
abort_fndecl
;
if
(
flag_vtable_thunks
)
fnaddr
=
TREE_VALUE
(
entries
);
TREE_OPERAND
(
fnaddr
,
0
)
=
abort_fndecl
;
TREE_OPERAND
(
fnaddr
,
0
)
=
fn
=
abort_fndecl
;
}
if
(
TREE_PUBLIC
(
fn
)
&&
!
TREE_ASM_WRITTEN
(
fn
))
{
int
save_extern
=
DECL_EXTERNAL
(
fn
);
DECL_EXTERNAL
(
fn
)
=
1
;
assemble_external
(
fn
);
DECL_EXTERNAL
(
fn
)
=
save_extern
;
}
}
}
...
...
@@ -2561,7 +2569,8 @@ finish_prevtable_vardecl (prev, vars)
for
(
method
=
CLASSTYPE_METHODS
(
ctype
);
method
!=
NULL_TREE
;
method
=
DECL_NEXT_METHOD
(
method
))
{
if
(
DECL_VINDEX
(
method
)
!=
NULL_TREE
&&
!
DECL_SAVED_INSNS
(
method
)
if
(
DECL_VINDEX
(
method
)
!=
NULL_TREE
&&
!
DECL_DECLARED_STATIC
(
method
)
&&
!
DECL_ABSTRACT_VIRTUAL_P
(
method
))
{
SET_CLASSTYPE_INTERFACE_KNOWN
(
ctype
);
...
...
@@ -2574,10 +2583,17 @@ finish_prevtable_vardecl (prev, vars)
import_export_vtable
(
vars
,
ctype
,
1
);
/* We cannot use TREE_USED here, as it may be set by the expanding of a
ctor that is used to build a global object. The long term plan is to
make the TD entries statically initialized and move this to
finish_vtable_vardecl time. */
if
(
flag_rtti
&&
write_virtuals
>=
0
&&
!
DECL_EXTERNAL
(
vars
)
&&
(
TREE_PUBLIC
(
vars
)
||
TREE_USED
(
vars
)))
&&
!
DECL_EXTERNAL
(
vars
)
&&
(
TREE_PUBLIC
(
vars
)
||
1
||
TREE_USED
(
vars
)))
{
/* Kick out the type descriptor before writing out the vtable. */
/* Kick out the type descriptor before we dump out global
initializers, as they are initialized at run time and
we have to find them when we scan for things that need initialized
at the top level. */
build_t_desc
(
ctype
,
1
);
}
}
...
...
@@ -2589,6 +2605,15 @@ finish_vtable_vardecl (prev, vars)
if
(
write_virtuals
>=
0
&&
!
DECL_EXTERNAL
(
vars
)
&&
(
TREE_PUBLIC
(
vars
)
||
TREE_USED
(
vars
)))
{
#if 0
/* The long term plan it to make the TD entries statically initialized,
have the entries built and emitted here. When that happens, this
can be enabled, and the other call to build_t_desc removed. */
/* Kick out the type descriptor before writing out the vtable. */
if (flag_rtti)
build_t_desc (DECL_CONTEXT (vars), 1);
#endif
/* Write it out. */
mark_vtable_entries
(
vars
);
if
(
TREE_TYPE
(
DECL_INITIAL
(
vars
))
==
0
)
...
...
@@ -2651,19 +2676,22 @@ walk_vtables (typedecl_fn, vardecl_fn)
{
register
tree
type
=
TREE_TYPE
(
vars
);
if
(
TREE_CODE
(
vars
)
==
TYPE_DECL
&&
type
!=
error_mark_node
&&
TYPE_LANG_SPECIFIC
(
type
)
&&
CLASSTYPE_VSIZE
(
type
))
if
(
TREE_CODE
(
vars
)
==
VAR_DECL
&&
DECL_VIRTUAL_P
(
vars
))
{
if
(
typedecl_fn
)
(
*
typedecl_fn
)
(
prev
,
vars
);
if
(
vardecl_fn
)
(
*
vardecl_fn
)
(
prev
,
vars
);
if
(
prev
&&
TREE_CHAIN
(
prev
)
!=
vars
)
continue
;
}
else
if
(
TREE_CODE
(
vars
)
==
VAR_DECL
&&
DECL_VIRTUAL_P
(
vars
))
else
if
(
TREE_CODE
(
vars
)
==
TYPE_DECL
&&
type
!=
error_mark_node
&&
TYPE_LANG_SPECIFIC
(
type
)
&&
CLASSTYPE_VSIZE
(
type
))
{
if
(
vardecl_fn
)
(
*
var
decl_fn
)
(
prev
,
vars
);
if
(
typedecl_fn
)
(
*
type
decl_fn
)
(
prev
,
vars
);
}
else
prev
=
vars
;
prev
=
vars
;
}
}
...
...
@@ -2805,6 +2833,31 @@ finish_file ()
interface_unknown
=
1
;
interface_only
=
0
;
#if 1
/* The reason for pushing garbage onto the global_binding_level is to
ensure that we can slice out _DECLs which pertain to virtual function
tables. If the last thing pushed onto the global_binding_level was a
virtual function table, then slicing it out would slice away all the
decls (i.e., we lose the head of the chain).
There are several ways of getting the same effect, from changing the
way that iterators over the chain treat the elements that pertain to
virtual function tables, moving the implementation of this code to
decl.c (where we can manipulate global_binding_level directly),
popping the garbage after pushing it and slicing away the vtable
stuff, or just leaving it alone. */
/* Make last thing in global scope not be a virtual function table. */
#if 0 /* not yet, should get fixed properly later */
vars = make_type_decl (get_identifier (" @%$#@!"), integer_type_node);
#else
vars
=
build_decl
(
TYPE_DECL
,
get_identifier
(
" @%$#@!"
),
integer_type_node
);
#endif
DECL_IGNORED_P
(
vars
)
=
1
;
SET_DECL_ARTIFICIAL
(
vars
);
pushdecl
(
vars
);
#endif
/* Walk to mark the inline functions we need, then output them so
that we can pick up any other tdecls that those routines need. */
walk_vtables
((
void
(
*
)())
0
,
finish_prevtable_vardecl
);
...
...
@@ -3023,37 +3076,12 @@ finish_file ()
start_time
=
get_run_time
();
/* Now delete from the chain of variables all virtual function tables.
We output them all ourselves, because each will be treated specially. */
#if 1
/* The reason for pushing garbage onto the global_binding_level is to
ensure that we can slice out _DECLs which pertain to virtual function
tables. If the last thing pushed onto the global_binding_level was a
virtual function table, then slicing it out would slice away all the
decls (i.e., we lose the head of the chain).
There are several ways of getting the same effect, from changing the
way that iterators over the chain treat the elements that pertain to
virtual function tables, moving the implementation of this code to
decl.c (where we can manipulate global_binding_level directly),
popping the garbage after pushing it and slicing away the vtable
stuff, or just leaving it alone. */
/* Make last thing in global scope not be a virtual function table. */
#if 0 /* not yet, should get fixed properly later */
vars = make_type_decl (get_identifier (" @%$#@!"), integer_type_node);
#else
vars
=
build_decl
(
TYPE_DECL
,
get_identifier
(
" @%$#@!"
),
integer_type_node
);
#endif
DECL_IGNORED_P
(
vars
)
=
1
;
SET_DECL_ARTIFICIAL
(
vars
);
pushdecl
(
vars
);
#endif
if
(
flag_handle_signatures
)
walk_sigtables
((
void
(
*
)())
0
,
finish_sigtable_vardecl
);
for
(
fnname
=
saved_inlines
;
fnname
;
fnname
=
TREE_CHAIN
(
fnname
))
import_export_inline
(
TREE_VALUE
(
fnname
));
/* Now write out inline functions which had their addresses taken and
which were not declared virtual and which were not declared `extern
inline'. */
...
...
@@ -3089,7 +3117,7 @@ finish_file ()
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
continue
;
}
import_export_inline
(
decl
);
if
(
TREE_PUBLIC
(
decl
)
||
TREE_SYMBOL_REFERENCED
(
DECL_ASSEMBLER_NAME
(
decl
))
||
flag_keep_inline_functions
)
...
...
@@ -3112,6 +3140,9 @@ finish_file ()
}
}
/* Now delete from the chain of variables all virtual function tables.
We output them all ourselves, because each will be treated specially. */
walk_vtables
((
void
(
*
)())
0
,
prune_vtable_vardecl
);
for
(
vars
=
getdecls
();
vars
;
vars
=
TREE_CHAIN
(
vars
))
...
...
gcc/cp/error.c
View file @
28cbf42c
...
...
@@ -1142,6 +1142,13 @@ dump_expr (t, nop)
}
break
;
case
ARRAY_REF
:
dump_expr
(
TREE_OPERAND
(
t
,
0
),
0
);
OB_PUTC
(
'['
);
dump_expr
(
TREE_OPERAND
(
t
,
1
),
0
);
OB_PUTC
(
']'
);
break
;
case
CONVERT_EXPR
:
dump_unary_op
(
"+"
,
t
,
nop
);
break
;
...
...
gcc/cp/expr.c
View file @
28cbf42c
...
...
@@ -264,7 +264,7 @@ fixup_result_decl (decl, result)
REG_FUNCTION_VALUE_P
(
real_decl_result
)
=
1
;
result
=
real_decl_result
;
}
emit_move_insn
(
result
,
DECL_RTL
(
decl
)
);
store_expr
(
decl
,
result
,
0
);
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
result
));
}
}
...
...
@@ -274,9 +274,90 @@ fixup_result_decl (decl, result)
in some cases. We cannot use `memory_operand' as a test
here because on most RISC machines, a variable's address
is not, by itself, a legitimate address. */
int
decl_in_memory_p
(
decl
)
tree
decl
;
{
return
DECL_RTL
(
decl
)
!=
0
&&
GET_CODE
(
DECL_RTL
(
decl
))
==
MEM
;
}
/* Expand this initialization inline and see if it's simple enough that
it can be done at compile-time. */
static
tree
extract_aggr_init
(
decl
,
init
)
tree
decl
,
init
;
{
return
0
;
}
static
tree
extract_scalar_init
(
decl
,
init
)
tree
decl
,
init
;
{
rtx
value
,
insns
,
insn
;
extern
struct
obstack
temporary_obstack
;
tree
t
=
NULL_TREE
;
push_obstacks
(
&
temporary_obstack
,
&
temporary_obstack
);
start_sequence
();
value
=
expand_expr
(
init
,
NULL_RTX
,
VOIDmode
,
0
);
insns
=
get_insns
();
end_sequence
();
reg_scan
(
insns
,
max_reg_num
(),
0
);
jump_optimize
(
insns
,
0
,
0
,
1
);
pop_obstacks
();
for
(
insn
=
insns
;
insn
;
insn
=
NEXT_INSN
(
insn
))
{
rtx
r
,
to
;
if
(
GET_CODE
(
insn
)
==
NOTE
)
continue
;
else
if
(
GET_CODE
(
insn
)
!=
INSN
)
return
0
;
r
=
PATTERN
(
insn
);
if
(
GET_CODE
(
r
)
!=
SET
)
return
0
;
to
=
XEXP
(
r
,
0
);
if
(
!
(
to
==
value
||
(
GET_CODE
(
to
)
==
SUBREG
&&
XEXP
(
to
,
0
)
==
value
)))
return
0
;
r
=
XEXP
(
r
,
1
);
switch
(
GET_CODE
(
r
))
{
case
CONST_INT
:
t
=
build_int_2
(
XEXP
(
r
,
0
),
0
);
break
;
default
:
return
0
;
}
}
return
t
;
}
int
extract_init
(
decl
,
init
)
tree
decl
,
init
;
{
return
0
;
if
(
IS_AGGR_TYPE
(
TREE_TYPE
(
decl
))
||
TREE_CODE
(
TREE_TYPE
(
decl
))
==
ARRAY_TYPE
)
init
=
extract_aggr_init
(
decl
,
init
);
else
init
=
extract_scalar_init
(
decl
,
init
);
if
(
init
==
NULL_TREE
)
return
0
;
DECL_INITIAL
(
decl
)
=
init
;
return
1
;
}
gcc/cp/init.c
View file @
28cbf42c
...
...
@@ -571,7 +571,7 @@ emit_base_init (t, immediately)
if
(
init
!=
void_list_node
)
{
member
=
convert_pointer_to
(
base_binfo
,
current_class_decl
);
member
=
convert_pointer_to
_real
(
base_binfo
,
current_class_decl
);
expand_aggr_init_1
(
base_binfo
,
0
,
build_indirect_ref
(
member
,
NULL_PTR
),
init
,
BINFO_OFFSET_ZEROP
(
base_binfo
),
LOOKUP_NORMAL
);
...
...
@@ -1980,6 +1980,10 @@ build_offset_ref (cname, name)
&&
((
flag_save_memoized_contexts
&&
global_bindings_p
())
||
!
allocation_temporary_p
()))
fnfields
=
copy_list
(
fnfields
);
for
(
t
=
TREE_VALUE
(
fnfields
);
t
;
t
=
DECL_CHAIN
(
t
))
assemble_external
(
t
);
t
=
build_tree_list
(
error_mark_node
,
fnfields
);
TREE_TYPE
(
t
)
=
build_offset_type
(
type
,
unknown_type_node
);
return
t
;
...
...
gcc/cp/lex.c
View file @
28cbf42c
...
...
@@ -1796,8 +1796,10 @@ cons_up_default_function (type, full_name, kind)
/* When on-the-fly synthesis works properly, remove the second and third
conditions here. */
if
(
flag_keep_inline_functions
#if 0
|| ! flag_no_inline
|| complex
#endif
||
!
DECL_EXTERNAL
(
fn
))
{
struct
pending_inline
*
t
;
...
...
@@ -2812,7 +2814,13 @@ linenum:
extract_interface_info
();
c
=
get_last_nonwhite_on_line
();
if
(
c
!=
EOF
)
if
(
c
==
EOF
)
{
/* Update the name in the top element of input_file_stack. */
if
(
input_file_stack
)
input_file_stack
->
name
=
input_filename
;
}
else
{
put_back
(
c
);
...
...
gcc/cp/method.c
View file @
28cbf42c
...
...
@@ -2209,12 +2209,12 @@ synthesize_method (fndecl)
tree
fndecl
;
{
int
nested
=
(
current_function_decl
!=
NULL_TREE
);
int
toplev
=
(
decl_function_context
(
fndecl
)
==
NULL_TREE
);
tree
context
=
decl_function_context
(
fndecl
);
char
*
f
=
input_filename
;
tree
base
=
DECL_CLASS_CONTEXT
(
fndecl
);
if
(
nested
)
push_cp_function_context
(
toplev
);
push_cp_function_context
(
context
);
input_filename
=
DECL_SOURCE_FILE
(
fndecl
);
interface_unknown
=
CLASSTYPE_INTERFACE_UNKNOWN
(
base
);
...
...
@@ -2238,8 +2238,19 @@ synthesize_method (fndecl)
}
finish_function
(
lineno
,
0
,
nested
);
/* Do we really *want* to inline this function? */
if
(
DECL_INLINE
(
fndecl
))
{
/* Turn off DECL_INLINE for the moment so function_cannot_inline_p
will check our size. */
DECL_INLINE
(
fndecl
)
=
0
;
if
(
function_cannot_inline_p
(
fndecl
)
==
0
)
DECL_INLINE
(
fndecl
)
=
1
;
}
input_filename
=
f
;
extract_interface_info
();
if
(
nested
)
pop_cp_function_context
(
toplev
);
pop_cp_function_context
(
context
);
}
gcc/cp/parse.y
View file @
28cbf42c
...
...
@@ -402,8 +402,12 @@ any_id:
;
extern_lang_string:
EXTERN_LANG_STRING
EXTERN_LANG_STRING
{ push_lang_context ($1); }
| extern_lang_string EXTERN_LANG_STRING
{ if (current_lang_name != $2)
cp_error ("use of linkage spec `%D' is different from previous spec `%D'", $2, current_lang_name);
pop_lang_context (); push_lang_context ($2); }
;
template_header:
...
...
@@ -1725,7 +1729,7 @@ object: primary '.'
;
setattrs: /* empty */
{ prefix_attributes =
$<ttype>0
; }
{ prefix_attributes =
chainon (prefix_attributes, $<ttype>0)
; }
;
decl:
...
...
gcc/cp/pt.c
View file @
28cbf42c
...
...
@@ -1712,6 +1712,8 @@ instantiate_template (tmpl, targ_ptr)
if
(
fndecl
==
error_mark_node
)
goto
exit
;
assemble_external
(
fndecl
);
/* If it's a static member fn in the template, we need to change it
into a FUNCTION_TYPE and chop off its this pointer. */
if
(
TREE_CODE
(
TREE_TYPE
(
DECL_RESULT
(
tmpl
)))
==
METHOD_TYPE
...
...
@@ -2059,6 +2061,23 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
if
(
TREE_CODE_CLASS
(
TREE_CODE
(
arg
))
!=
't'
)
{
my_friendly_assert
(
TREE_TYPE
(
arg
)
!=
NULL_TREE
,
293
);
if
(
TREE_CODE
(
arg
)
==
TREE_LIST
&&
TREE_TYPE
(
arg
)
==
unknown_type_node
&&
TREE_CODE
(
TREE_VALUE
(
arg
))
==
TEMPLATE_DECL
)
{
int
nsubsts
,
ntparms
;
tree
*
targs
;
/* Have to back unify here */
arg
=
TREE_VALUE
(
arg
);
nsubsts
=
0
;
ntparms
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
arg
));
targs
=
(
tree
*
)
alloca
(
sizeof
(
tree
)
*
ntparms
);
parm
=
tree_cons
(
NULL_TREE
,
parm
,
NULL_TREE
);
return
type_unification
(
DECL_TEMPLATE_PARMS
(
arg
),
targs
,
TYPE_ARG_TYPES
(
TREE_TYPE
(
arg
)),
parm
,
&
nsubsts
,
0
);
}
arg
=
TREE_TYPE
(
arg
);
}
#endif
...
...
@@ -2200,6 +2219,8 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
nsubsts
);
case
REFERENCE_TYPE
:
if
(
TREE_CODE
(
arg
)
==
REFERENCE_TYPE
)
arg
=
TREE_TYPE
(
arg
);
return
unify
(
tparms
,
targs
,
ntparms
,
TREE_TYPE
(
parm
),
arg
,
nsubsts
);
case
ARRAY_TYPE
:
...
...
@@ -2242,8 +2263,6 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
tree
t1
,
t2
;
t1
=
TREE_OPERAND
(
parm
,
0
);
t2
=
TREE_OPERAND
(
parm
,
1
);
if
(
TREE_CODE
(
t1
)
!=
TEMPLATE_CONST_PARM
)
return
1
;
return
unify
(
tparms
,
targs
,
ntparms
,
t1
,
fold
(
build
(
PLUS_EXPR
,
integer_type_node
,
arg
,
t2
)),
nsubsts
);
...
...
@@ -2299,6 +2318,9 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
if
(
TREE_CODE
(
arg
)
!=
FUNCTION_TYPE
)
return
1
;
check_args
:
if
(
unify
(
tparms
,
targs
,
ntparms
,
TREE_TYPE
(
parm
),
TREE_TYPE
(
arg
),
nsubsts
))
return
1
;
return
type_unification
(
tparms
,
targs
,
TYPE_ARG_TYPES
(
parm
),
TYPE_ARG_TYPES
(
arg
),
nsubsts
,
1
);
...
...
gcc/cp/tree.c
View file @
28cbf42c
...
...
@@ -24,6 +24,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "rtl.h"
#define CEIL(x,y) (((x) + (y) - 1) / (y))
...
...
@@ -826,6 +827,7 @@ layout_basetypes (rec, binfos)
DECL_FIELD_CONTEXT
(
decl
)
=
rec
;
DECL_CLASS_CONTEXT
(
decl
)
=
rec
;
DECL_FCONTEXT
(
decl
)
=
basetype
;
DECL_SAVED_INSNS
(
decl
)
=
NULL_RTX
;
DECL_FIELD_SIZE
(
decl
)
=
0
;
DECL_ALIGN
(
decl
)
=
TYPE_ALIGN
(
ptr_type_node
);
TREE_CHAIN
(
decl
)
=
vbase_decls
;
...
...
gcc/cp/typeck.c
View file @
28cbf42c
...
...
@@ -369,12 +369,24 @@ common_type (t1, t2)
But ANSI C++ specifies doing this with the qualifiers.
So I turned it on again. */
{
tree
t
arget
=
common_type
(
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
t1
)),
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
t2
)
));
tree
t
t1
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
t1
));
tree
tt2
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
t2
));
int
constp
=
TYPE_READONLY
(
TREE_TYPE
(
t1
))
||
TYPE_READONLY
(
TREE_TYPE
(
t2
));
int
volatilep
=
TYPE_VOLATILE
(
TREE_TYPE
(
t1
))
||
TYPE_VOLATILE
(
TREE_TYPE
(
t2
));
tree
target
;
if
(
tt1
==
tt2
)
target
=
tt1
;
else
if
((
IS_AGGR_TYPE_CODE
(
TREE_CODE
(
tt1
))
||
TREE_CODE
(
tt1
)
==
OFFSET_TYPE
||
TREE_CODE
(
tt1
)
==
METHOD_TYPE
)
&&
TREE_CODE
(
tt2
)
==
TREE_CODE
(
tt1
))
target
=
common_type
(
tt1
,
tt2
);
else
target
=
void_type_node
;
target
=
cp_build_type_variant
(
target
,
constp
,
volatilep
);
if
(
code1
==
POINTER_TYPE
)
t1
=
build_pointer_type
(
target
);
...
...
@@ -480,17 +492,18 @@ common_type (t1, t2)
return
build_type_attribute_variant
(
t1
,
attributes
);
case
OFFSET_TYPE
:
if
(
TYPE_OFFSET_BASETYPE
(
t1
)
==
TYPE_OFFSET_BASETYPE
(
t2
)
&&
TREE_CODE
(
TREE_TYPE
(
t1
))
==
TREE_CODE
(
TREE_TYPE
(
t2
)))
if
(
TREE_CODE
(
TREE_TYPE
(
t1
))
==
TREE_CODE
(
TREE_TYPE
(
t2
)))
{
tree
basetype
=
TYPE_OFFSET_BASETYPE
(
t1
);
t1
=
build_offset_type
(
basetype
,
common_type
(
TREE_TYPE
(
t1
),
TREE_TYPE
(
t2
)));
}
else
compiler_error
(
"common_type called with uncommon member types"
);
tree
b1
=
TYPE_OFFSET_BASETYPE
(
t1
);
tree
b2
=
TYPE_OFFSET_BASETYPE
(
t2
);
tree
base
;
/* ... falls through ... */
if
(
DERIVED_FROM_P
(
b1
,
b2
)
&&
binfo_or_else
(
b1
,
b2
))
return
build_type_attribute_variant
(
t1
,
attributes
);
else
if
(
binfo_or_else
(
b2
,
b1
))
return
build_type_attribute_variant
(
t2
,
attributes
);
}
compiler_error
(
"common_type called with uncommon member types"
);
default
:
return
build_type_attribute_variant
(
t1
,
attributes
);
...
...
@@ -762,6 +775,17 @@ comp_target_types (ttl, ttr, nptrs)
if
(
ttl
==
ttr
)
return
1
;
if
(
TREE_CODE
(
ttl
)
==
VOID_TYPE
&&
TREE_CODE
(
ttr
)
!=
FUNCTION_TYPE
&&
TREE_CODE
(
ttr
)
!=
METHOD_TYPE
&&
TREE_CODE
(
ttr
)
!=
OFFSET_TYPE
)
return
1
;
if
(
TREE_CODE
(
ttr
)
==
VOID_TYPE
&&
TREE_CODE
(
ttl
)
!=
FUNCTION_TYPE
&&
TREE_CODE
(
ttl
)
!=
METHOD_TYPE
&&
TREE_CODE
(
ttl
)
!=
OFFSET_TYPE
)
return
-
1
;
if
(
TREE_CODE
(
ttr
)
!=
TREE_CODE
(
ttl
))
return
0
;
...
...
@@ -1680,6 +1704,7 @@ build_component_ref (datum, component, basetype_path, protect)
my_friendly_assert
(
datum
!=
error_mark_node
,
310
);
fndecl
=
build_vfn_ref
(
&
addr
,
datum
,
DECL_VINDEX
(
fndecl
));
}
assemble_external
(
fndecl
);
return
fndecl
;
}
if
(
access
==
access_protected
)
...
...
@@ -1692,7 +1717,12 @@ build_component_ref (datum, component, basetype_path, protect)
{
/* 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
t
;
for
(
t
=
TREE_VALUE
(
fndecls
);
t
;
t
=
DECL_CHAIN
(
t
))
assemble_external
(
t
);
t
=
build_tree_list
(
error_mark_node
,
fndecls
);
TREE_TYPE
(
t
)
=
build_offset_type
(
basetype
,
unknown_type_node
);
return
t
;
...
...
@@ -1779,6 +1809,13 @@ build_indirect_ref (ptr, errorstring)
if
(
ptr
==
current_class_decl
)
return
C_C_D
;
ptr
=
build_expr_type_conversion
(
WANT_POINTER
,
pointer
,
1
);
if
(
ptr
)
{
pointer
=
ptr
;
type
=
TREE_TYPE
(
pointer
);
}
if
(
TREE_CODE
(
type
)
==
POINTER_TYPE
||
TREE_CODE
(
type
)
==
REFERENCE_TYPE
)
{
if
(
TREE_CODE
(
pointer
)
==
ADDR_EXPR
...
...
@@ -2821,6 +2858,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
Zero means they need to be converted to RESULT_TYPE. */
int
converted
=
0
;
/* Nonzero means create the expression with this type, rather than
RESULT_TYPE. */
tree
build_type
=
0
;
/* Nonzero means after finally constructing the expression
give it this type. Otherwise, give it type RESULT_TYPE. */
tree
final_type
=
0
;
...
...
@@ -3064,8 +3105,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
case
EQ_EXPR
:
case
NE_EXPR
:
result_type
=
boolean_type_node
;
converted
=
1
;
build_type
=
boolean_type_node
;
if
((
code0
==
INTEGER_TYPE
||
code0
==
REAL_TYPE
)
&&
(
code1
==
INTEGER_TYPE
||
code1
==
REAL_TYPE
))
short_compare
=
1
;
...
...
@@ -3073,33 +3113,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
{
register
tree
tt0
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
type0
));
register
tree
tt1
=
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
type1
));
/* Anything compares with void *. void * compares with anything.
Otherwise, the targets must be the same. */
if
(
tt0
!=
tt1
&&
TREE_CODE
(
tt0
)
==
RECORD_TYPE
&&
TREE_CODE
(
tt1
)
==
RECORD_TYPE
)
{
tree
base
=
common_base_type
(
tt0
,
tt1
);
if
(
base
==
NULL_TREE
)
cp_pedwarn
(
"comparison of distinct object pointer types `%T' and `%T'"
,
type0
,
type1
);
else
if
(
base
==
error_mark_node
)
{
cp_error
(
"comparison of pointer types `%T' and `%T' requires conversion to ambiguous supertype"
,
type0
,
type1
);
return
error_mark_node
;
}
else
{
if
(
integer_zerop
(
op0
))
op0
=
null_pointer_node
;
else
op0
=
convert_pointer_to
(
base
,
op0
);
if
(
integer_zerop
(
op1
))
op1
=
null_pointer_node
;
else
op1
=
convert_pointer_to
(
base
,
op1
);
}
}
else
if
(
comp_target_types
(
type0
,
type1
,
1
))
;
if
(
comp_target_types
(
type0
,
type1
,
1
))
result_type
=
common_type
(
type0
,
type1
);
else
if
(
tt0
==
void_type_node
)
{
if
(
pedantic
&&
TREE_CODE
(
tt1
)
==
FUNCTION_TYPE
...
...
@@ -3225,10 +3241,11 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
{
return
build_binary_op
(
code
,
op1
,
op0
,
1
);
}
else
/* If args are not valid, clear out RESULT_TYPE
to cause an error message later. */
result_type
=
0
;
type0
=
TREE_TYPE
(
op0
);
type1
=
TREE_TYPE
(
op1
);
if
(
result_type
==
NULL_TREE
)
result_type
=
type0
;
break
;
case
MAX_EXPR
:
...
...
@@ -3239,8 +3256,12 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
else
if
(
code0
==
POINTER_TYPE
&&
code1
==
POINTER_TYPE
)
{
if
(
!
comp_target_types
(
type0
,
type1
,
1
))
cp_pedwarn
(
"comparison of distinct pointer types `%T' and `%T' lacks a cast"
,
type0
,
type1
);
{
cp_pedwarn
(
"comparison of distinct pointer types `%T' and `%T' lacks a cast"
,
type0
,
type1
);
result_type
=
ptr_type_node
;
}
#if 0
else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
!= (TYPE_SIZE (TREE_TYPE (type1)) != 0))
cp_pedwarn ("comparison of %scomplete and %scomplete pointers",
...
...
@@ -3250,15 +3271,20 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
else if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids ordered comparisons of pointers to functions");
result_type
=
common_type
(
type0
,
type1
);
#endif
else
result_type
=
common_type
(
type0
,
type1
);
}
if
(
result_type
==
NULL_TREE
)
result_type
=
type0
;
break
;
case
LE_EXPR
:
case
GE_EXPR
:
case
LT_EXPR
:
case
GT_EXPR
:
result
_type
=
boolean_type_node
;
build
_type
=
boolean_type_node
;
if
((
code0
==
INTEGER_TYPE
||
code0
==
REAL_TYPE
)
&&
(
code1
==
INTEGER_TYPE
||
code1
==
REAL_TYPE
))
short_compare
=
1
;
...
...
@@ -3267,6 +3293,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
if
(
!
comp_target_types
(
type0
,
type1
,
1
))
cp_pedwarn
(
"comparison of distinct pointer types `%T' and `%T' lacks a cast"
,
type0
,
type1
);
#if 0
else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
!= (TYPE_SIZE (TREE_TYPE (type1)) != 0))
cp_pedwarn ("comparison of %scomplete and %scomplete pointers",
...
...
@@ -3276,6 +3303,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
else if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids ordered comparisons of pointers to functions");
#endif
else
result_type
=
common_type
(
type0
,
type1
);
}
else
if
(
code0
==
POINTER_TYPE
&&
TREE_CODE
(
op1
)
==
INTEGER_CST
&&
integer_zerop
(
op1
))
...
...
@@ -3299,9 +3329,11 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
warning
(
"comparison between pointer and integer"
);
op0
=
convert
(
TREE_TYPE
(
op1
),
op0
);
}
else
result_type
=
0
;
converted
=
1
;
type0
=
TREE_TYPE
(
op0
);
type1
=
TREE_TYPE
(
op1
);
if
(
result_type
==
NULL_TREE
)
result_type
=
type0
;
break
;
}
...
...
@@ -3437,7 +3469,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
=
shorten_compare
(
&
xop0
,
&
xop1
,
&
xresult_type
,
&
xresultcode
);
if
(
val
!=
0
)
return
convert
(
boolean_type_node
,
val
);
op0
=
xop0
,
op1
=
xop1
,
result_type
=
boolean_type_node
;
op0
=
xop0
,
op1
=
xop1
;
converted
=
1
;
resultcode
=
xresultcode
;
}
...
...
@@ -3544,8 +3577,11 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
op1
=
convert
(
result_type
,
op1
);
}
if
(
build_type
==
NULL_TREE
)
build_type
=
result_type
;
{
register
tree
result
=
build
(
resultcode
,
result
_type
,
op0
,
op1
);
register
tree
result
=
build
(
resultcode
,
build
_type
,
op0
,
op1
);
register
tree
folded
;
folded
=
fold
(
result
);
...
...
@@ -6731,11 +6767,22 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
&&
TREE_CODE
(
rhstype
)
==
POINTER_TYPE
&&
TREE_CODE
(
TREE_TYPE
(
rhstype
))
==
METHOD_TYPE
)
||
integer_zerop
(
rhs
)
||
TYPE_PTRMEMFUNC_P
(
TREE_TYPE
(
rhs
)
))
||
TYPE_PTRMEMFUNC_P
(
rhstype
))
&&
TYPE_PTRMEMFUNC_P
(
type
))
{
tree
ttl
=
TYPE_PTRMEMFUNC_FN_TYPE
(
type
);
tree
ttr
=
(
TREE_CODE
(
rhstype
)
==
POINTER_TYPE
?
rhstype
:
TYPE_PTRMEMFUNC_FN_TYPE
(
type
));
int
ctt
=
comp_target_types
(
ttl
,
ttr
,
1
);
if
(
ctt
<
0
)
cp_pedwarn
(
"converting `%T' to `%T' is a contravariance violation"
,
ttr
,
ttl
);
else
if
(
ctt
==
0
)
cp_error
(
"%s to `%T' from `%T'"
,
errtype
,
ttl
,
ttr
);
/* compatible pointer to member functions. */
return
build_ptrmemfunc
(
TYPE_PTRMEMFUNC_FN_TYPE
(
type
)
,
rhs
,
0
);
return
build_ptrmemfunc
(
ttl
,
rhs
,
0
);
}
else
if
(
codel
==
ERROR_MARK
||
coder
==
ERROR_MARK
)
return
error_mark_node
;
...
...
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