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
e8abc66f
Commit
e8abc66f
authored
Apr 24, 1995
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
67th Cygnus<->FSF merge
From-SVN: r9433
parent
87c73618
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
358 additions
and
481 deletions
+358
-481
gcc/cp/ChangeLog
+95
-0
gcc/cp/call.c
+19
-4
gcc/cp/class.c
+12
-17
gcc/cp/cp-tree.h
+10
-0
gcc/cp/decl.c
+1
-0
gcc/cp/decl2.c
+26
-5
gcc/cp/expr.c
+2
-2
gcc/cp/gxxint.texi
+75
-22
gcc/cp/init.c
+2
-2
gcc/cp/lex.c
+2
-348
gcc/cp/method.c
+2
-2
gcc/cp/parse.y
+1
-0
gcc/cp/pt.c
+20
-6
gcc/cp/repo.c
+36
-34
gcc/cp/search.c
+3
-0
gcc/cp/tree.c
+8
-4
gcc/cp/typeck.c
+39
-31
gcc/cp/typeck2.c
+5
-4
No files found.
gcc/cp/ChangeLog
View file @
e8abc66f
Sun Apr 23 12:32:38 1995 Mike Stump <mrs@cygnus.com>
* decl2.c (finish_file): Fix broken linked list handling.
Fri Apr 21 18:08:43 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* class.c (finish_base_struct): Don't set TYPE_HAS_COMPLEX_*_REF
as often.
(finish_struct): Ditto.
* various: Use TYPE_HAS_TRIVIAL_* instead of TYPE_HAS_COMPLEX_*.
* cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): New macro.
(TYPE_HAS_TRIVIAL_ASSIGN_REF): New macro.
Fri Apr 21 15:52:22 1995 Jason Merrill <jason@python.cygnus.com>
* typeck.c (c_expand_return): Only expand a returned TARGET_EXPR if
it is of the same type as the return value.
Fri Apr 21 03:01:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (finish_file): Reconsider if synthesizing a method wrote
out its assembly.
* typeck.c (convert_for_initialization): Don't call a trivial copy
constructor.
* typeck2.c (store_init_value): Only abort if the type has a
non-trivial copy constructor.
* typeck.c (c_expand_return): If we're returning in a register and
the return value is a TARGET_EXPR, expand it. Only do
expand_aggr_init if we're returning in memory.
(expand_target_expr): Function to expand a TARGET_EXPR.
(build_modify_expr): Use it.
* tree.c (build_cplus_new): Layout the slot.
* expr.c (cplus_expand_expr): Use expand_call to expand the call
under a NEW_EXPR, so the target is not discarded.
Thu Apr 20 14:59:31 1995 Mike Stump <mrs@cygnus.com>
* gc.c (build_dynamic_cast): Tighten error checking.
Thu Apr 20 11:23:54 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* expr.c (cplus_expand_expr): Only abort if the returned target is
different from what we expected if the type has a non-trivial copy
constructor.
* decl2.c (cplus_decl_attributes): Attributes applied to a template
really apply to the template's result.
* tree.c (lvalue_p): Check IS_AGGR_TYPE instead of TREE_ADDRESSABLE
to decide whether to consider a CALL_EXPR an lvalue.
* class.c (finish_struct_bits): Only set TREE_ADDRESSABLE if the
type has a non-trivial copy constructor.
* decl.c (start_function): If interface_known, unset
DECL_NOT_REALLY_EXTERN on the function.
Wed Apr 19 16:53:13 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* pt.c (do_function_instantiation): Handle explicit instantiation of
member functions.
(do_type_instantiation): Handle 'inline template class foo<int>',
meaning just spit out the vtable.
* lex.c (cons_up_default_function): Set DECL_NOT_REALLY_EXTERN on
the consed functions.
* decl2.c (import_export_inline): Set DECL_INTERFACE_KNOWN.
Wed Apr 19 16:28:17 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* call.c, class.c, decl2.c, gc.c, init.c, parse.y, pt.c, search.c,
typeck.c: Include output.h.
Wed Apr 19 14:57:21 1995 Gerald Baumgartner (gb@alexander.cs.purdue.edu)
* call.c (build_method_call): Allow a signature member functions to
be called from a default implementation.
Wed Apr 19 10:21:17 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* repo.c (finish_repo): Remember what directory we are in.
* search.c (expand_upcast_fixups): Don't mess with abort_fndecl.
* repo.c: Use obstacks instead of fixed-size buffers. Don't spit
out the second copy of the symbol name. Don't remember COLLECT_GCC.
Wed Apr 19 02:32:40 1995 Mike Stump <mrs@cygnus.com>
* search.c (virtual_context): New function to get the virtual
...
...
gcc/cp/call.c
View file @
e8abc66f
...
...
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "cp-tree.h"
#include "class.h"
#include "output.h"
#include "flags.h"
#include "obstack.h"
...
...
@@ -1683,10 +1684,24 @@ build_method_call (instance, name, parms, basetype_path, flags)
need_vtbl
=
(
dtor_label
||
ctor_label
)
?
unneeded
:
maybe_needed
;
instance
=
C_C_D
;
instance_ptr
=
current_class_decl
;
result
=
build_field_call
(
TYPE_BINFO
(
current_class_type
),
instance_ptr
,
name
,
parms
);
/* If `this' is a signature pointer and `name' is not a constructor,
we are calling a signature member function. In that case, set the
`basetype' to the signature type and dereference the `optr' field. */
if
(
IS_SIGNATURE_POINTER
(
basetype
)
&&
TYPE_IDENTIFIER
(
basetype
)
!=
name
)
{
basetype
=
SIGNATURE_TYPE
(
basetype
);
instance_ptr
=
build_optr_ref
(
instance
);
instance_ptr
=
convert
(
TYPE_POINTER_TO
(
basetype
),
instance_ptr
);
basetype_path
=
TYPE_BINFO
(
basetype
);
}
else
{
instance
=
C_C_D
;
instance_ptr
=
current_class_decl
;
basetype_path
=
TYPE_BINFO
(
current_class_type
);
}
result
=
build_field_call
(
basetype_path
,
instance_ptr
,
name
,
parms
);
if
(
result
)
return
result
;
...
...
gcc/cp/class.c
View file @
e8abc66f
...
...
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "cp-tree.h"
#include "flags.h"
#include "rtl.h"
#include "output.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
...
...
@@ -1412,8 +1413,7 @@ finish_base_struct (t, b, t_binfo)
TYPE_NEEDS_CONSTRUCTING
(
t
)
|=
TYPE_NEEDS_CONSTRUCTING
(
basetype
);
TYPE_NEEDS_DESTRUCTOR
(
t
)
|=
TYPE_NEEDS_DESTRUCTOR
(
basetype
);
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
|=
TYPE_HAS_COMPLEX_ASSIGN_REF
(
basetype
);
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
(
TYPE_HAS_COMPLEX_INIT_REF
(
basetype
)
||
TYPE_NEEDS_CONSTRUCTING
(
basetype
));
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
TYPE_HAS_COMPLEX_INIT_REF
(
basetype
);
TYPE_OVERLOADS_CALL_EXPR
(
t
)
|=
TYPE_OVERLOADS_CALL_EXPR
(
basetype
);
TYPE_OVERLOADS_ARRAY_REF
(
t
)
|=
TYPE_OVERLOADS_ARRAY_REF
(
basetype
);
...
...
@@ -1688,19 +1688,19 @@ finish_struct_bits (t, max_has_virtual)
}
}
/* If this type has constructors, force its mode to be BLKmode,
and force its TREE_ADDRESSABLE bit to be nonzero. */
if
(
TYPE_NEEDS_CONSTRUCTING
(
t
)
||
TYPE_NEEDS_DESTRUCTOR
(
t
))
/* If this type has a copy constructor, force its mode to be BLKmode, and
force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to
be passed by invisible reference and prevent it from being returned in
a register. */
if
(
!
TYPE_HAS_TRIVIAL_INIT_REF
(
t
))
{
tree
variants
=
t
;
tree
variants
;
if
(
TREE_CODE
(
TYPE_NAME
(
t
))
==
TYPE_DECL
)
DECL_MODE
(
TYPE_NAME
(
t
))
=
BLKmode
;
while
(
variants
)
for
(
variants
=
t
;
variants
;
variants
=
TYPE_NEXT_VARIANT
(
variants
)
)
{
TYPE_MODE
(
variants
)
=
BLKmode
;
TREE_ADDRESSABLE
(
variants
)
=
1
;
variants
=
TYPE_NEXT_VARIANT
(
variants
);
}
}
}
...
...
@@ -3085,7 +3085,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
members. */
cant_synth_asn_ref
=
1
;
cant_have_default_ctor
=
1
;
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
=
1
;
if
(
!
TYPE_HAS_CONSTRUCTOR
(
t
)
&&
extra_warnings
)
{
...
...
@@ -3109,7 +3108,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
members. */
cant_synth_asn_ref
=
1
;
cant_have_default_ctor
=
1
;
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
=
1
;
if
(
!
TYPE_HAS_CONSTRUCTOR
(
t
)
&&
!
IS_SIGNATURE
(
t
)
&&
extra_warnings
)
...
...
@@ -3266,9 +3264,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_NEEDS_CONSTRUCTING
(
t
)
|=
TYPE_NEEDS_CONSTRUCTING
(
type
);
TYPE_NEEDS_DESTRUCTOR
(
t
)
|=
TYPE_NEEDS_DESTRUCTOR
(
type
);
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
|=
TYPE_HAS_COMPLEX_ASSIGN_REF
(
type
);
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
(
TYPE_HAS_COMPLEX_INIT_REF
(
type
)
||
TYPE_NEEDS_CONSTRUCTING
(
type
));
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
TYPE_HAS_COMPLEX_INIT_REF
(
type
);
}
if
(
!
TYPE_HAS_INIT_REF
(
type
)
...
...
@@ -3374,7 +3370,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
(
TYPE_HAS_INIT_REF
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
)
||
has_virtual
||
any_default_members
||
first_vfn_base_index
>=
0
);
||
any_default_members
);
TYPE_NEEDS_CONSTRUCTING
(
t
)
|=
(
TYPE_HAS_CONSTRUCTOR
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
)
||
has_virtual
||
any_default_members
||
first_vfn_base_index
>=
0
);
...
...
@@ -3406,8 +3402,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_HAS_REAL_ASSIGNMENT
(
t
)
|=
TYPE_HAS_ASSIGNMENT
(
t
);
TYPE_HAS_REAL_ASSIGN_REF
(
t
)
|=
TYPE_HAS_ASSIGN_REF
(
t
);
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
|=
(
TYPE_HAS_ASSIGN_REF
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
)
||
has_virtual
||
first_vfn_base_index
>=
0
);
|=
TYPE_HAS_ASSIGN_REF
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
);
if
(
!
TYPE_HAS_ASSIGN_REF
(
t
)
&&
!
cant_synth_asn_ref
&&
!
IS_SIGNATURE
(
t
))
...
...
gcc/cp/cp-tree.h
View file @
e8abc66f
...
...
@@ -1220,6 +1220,16 @@ struct lang_decl
of ARRAY_TYPE is the type of the elements needs a destructor. */
#define TYPE_NEEDS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_4(NODE))
/* Nonzero for class type means that initialization of this type can use
a bitwise copy. */
#define TYPE_HAS_TRIVIAL_INIT_REF(NODE) \
(TYPE_HAS_INIT_REF (NODE) && ! TYPE_HAS_COMPLEX_INIT_REF (NODE))
/* Nonzero for class type means that assignment of this type can use
a bitwise copy. */
#define TYPE_HAS_TRIVIAL_ASSIGN_REF(NODE) \
(TYPE_HAS_ASSIGN_REF (NODE) && ! TYPE_HAS_COMPLEX_ASSIGN_REF (NODE))
/* Nonzero for _TYPE node means that this type is a pointer to member
function type. */
#define TYPE_PTRMEMFUNC_P(NODE) (TREE_CODE(NODE) == RECORD_TYPE && TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag)
...
...
gcc/cp/decl.c
View file @
e8abc66f
...
...
@@ -10827,6 +10827,7 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
||
(
DECL_THIS_INLINE
(
decl1
)
&&
!
flag_implement_inlines
));
else
DECL_EXTERNAL
(
decl1
)
=
0
;
DECL_NOT_REALLY_EXTERN
(
decl1
)
=
0
;
DECL_INTERFACE_KNOWN
(
decl1
)
=
1
;
}
else
...
...
gcc/cp/decl2.c
View file @
e8abc66f
...
...
@@ -34,6 +34,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "cp-tree.h"
#include "decl.h"
#include "lex.h"
#include "output.h"
extern
tree
grokdeclarator
();
extern
tree
get_file_function_name
();
...
...
@@ -1948,8 +1949,13 @@ void
cplus_decl_attributes
(
decl
,
attributes
,
prefix_attributes
)
tree
decl
,
attributes
,
prefix_attributes
;
{
if
(
decl
&&
decl
!=
void_type_node
)
decl_attributes
(
decl
,
attributes
,
prefix_attributes
);
if
(
decl
==
NULL_TREE
||
decl
==
void_type_node
)
return
;
if
(
TREE_CODE
(
decl
)
==
TEMPLATE_DECL
)
decl
=
DECL_TEMPLATE_RESULT
(
decl
);
decl_attributes
(
decl
,
attributes
,
prefix_attributes
);
}
/* CONSTRUCTOR_NAME:
...
...
@@ -2775,6 +2781,8 @@ import_export_inline (decl)
}
else
TREE_PUBLIC
(
decl
)
=
0
;
DECL_INTERFACE_KNOWN
(
decl
)
=
1
;
}
extern
int
parse_time
,
varconst_time
;
...
...
@@ -3086,11 +3094,12 @@ finish_file ()
inline'. */
{
int
reconsider
=
1
;
/* More may be referenced; check again */
saved_inlines
=
tree_cons
(
NULL_TREE
,
NULL_TREE
,
saved_inlines
);
while
(
reconsider
)
{
tree
last
=
saved_inlines
;
tree
last
=
saved_inlines
=
tree_cons
(
NULL_TREE
,
NULL_TREE
,
saved_inlines
);
tree
last_head
=
last
;
tree
place
=
TREE_CHAIN
(
saved_inlines
);
reconsider
=
0
;
...
...
@@ -3100,11 +3109,23 @@ finish_file ()
{
tree
decl
=
TREE_VALUE
(
place
);
/* Slice out the empty elements put in just above in the
previous reconsidering. */
if
(
decl
==
NULL_TREE
)
{
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
continue
;
}
if
(
DECL_ARTIFICIAL
(
decl
)
&&
!
DECL_INITIAL
(
decl
))
{
if
(
TREE_USED
(
decl
)
||
(
TREE_PUBLIC
(
decl
)
&&
DECL_NOT_REALLY_EXTERN
(
decl
)))
synthesize_method
(
decl
);
{
synthesize_method
(
decl
);
if
(
TREE_ASM_WRITTEN
(
decl
))
reconsider
=
1
;
}
else
{
last
=
place
;
...
...
gcc/cp/expr.c
View file @
e8abc66f
...
...
@@ -142,7 +142,7 @@ cplus_expand_expr (exp, target, tmode, modifier)
preserve_temp_slots
(
DECL_RTL
(
slot
));
call_exp
=
build
(
CALL_EXPR
,
type
,
func
,
args
,
0
);
TREE_SIDE_EFFECTS
(
call_exp
)
=
1
;
return_target
=
expand_
expr
(
call_exp
,
call_target
,
mode
,
0
);
return_target
=
expand_
call
(
call_exp
,
call_target
,
ignore
);
free_temp_slots
();
if
(
call_target
==
0
)
{
...
...
@@ -174,7 +174,7 @@ cplus_expand_expr (exp, target, tmode, modifier)
if
(
call_target
!=
return_target
)
{
my_friendly_assert
(
!
TYPE_NEEDS_CONSTRUCTING
(
type
),
317
);
my_friendly_assert
(
TYPE_HAS_TRIVIAL_INIT_REF
(
type
),
317
);
if
(
GET_MODE
(
return_target
)
==
BLKmode
)
emit_block_move
(
call_target
,
return_target
,
expr_size
(
exp
),
TYPE_ALIGN
(
type
)
/
BITS_PER_UNIT
);
...
...
gcc/cp/gxxint.texi
View file @
e8abc66f
...
...
@@ -1145,16 +1145,21 @@ independent representation for exceptions.
The
C
++
front
-
end
exceptions
are
mapping
into
the
unwind
-
protect
semantics
by
the
C
++
front
-
end
.
The
mapping
is
describe
below
.
Objects
with
RTTI
support
should
use
the
RTTI
information
to
do
mapping
and
checking
.
Objects
without
RTTI
,
like
int
and
const
char
*
,
have
to
use
another
means
of
matching
.
Currently
we
use
the
normal
mangling
used
in
building
functions
names
.
Int
'
s
are
"i"
,
const
char
*
is
PCc
,
etc
...
Unfortunately
,
the
standard
allows
standard
type
conversions
on
throw
parameters
so
they
can
match
catch
handlers
.
This
means
we
need
a
mechanism
to
handle
type
conversion
at
run
time
,
ICK
.
I
read
this
part
again
,
and
it
appears
that
we
only
have
to
be
able
to
do
a
few
of
the
conversions
at
run
time
,
so
we
should
be
ok
.
When
-
frtti
is
used
,
rtti
is
used
to
do
exception
object
type
checking
,
when
it
isn
'
t
used
,
the
encoded
name
for
the
type
of
the
object
being
thrown
is
used
instead
.
All
code
that
originates
exceptions
,
even
code
that
throws
exceptions
as
a
side
effect
,
like
dynamic
casting
,
and
all
code
that
catches
exceptions
must
be
compiled
with
either
-
frtti
,
or
-
fno
-
rtti
.
It
is
not
possible
to
mix
rtti
base
exception
handling
objects
with
code
that
doesn
'
t
use
rtti
.
The
exceptions
to
this
,
are
code
that
doesn
'
t
catch
or
throw
exceptions
,
catch
(...),
and
code
that
just
rethrows
an
exception
.
Currently
we
use
the
normal
mangling
used
in
building
functions
names
(
int
'
s
are
"i"
,
const
char
*
is
PCc
)
to
build
the
non
-
rtti
base
type
descriptors
for
exception
handling
.
These
descriptors
are
just
plain
NULL
terminated
strings
,
and
internally
they
are
passed
around
as
char
*
.
In
C
++
,
all
cleanups
should
be
protected
by
exception
regions
.
The
region
starts
just
after
the
reason
why
the
cleanup
is
created
has
...
...
@@ -1192,18 +1197,20 @@ throwing. The only bad part, is that the stack remains large.
The
below
points
out
some
flaws
in
g
++
'
s
exception
handling
,
as
it
now
stands
.
Only
exact
type
matching
or
reference
matching
of
throw
types
works
.
Only
works
on
a
SPARC
machines
(
like
Suns
),
i386
machines
,
arm
machines
and
rs6000
machines
.
Partial
support
is
also
in
for
alpha
,
hppa
,
m68k
and
mips
machines
,
but
a
stack
unwinder
called
__unwind_function
has
to
be
written
,
and
added
to
libgcc2
for
them
.
All
completely
constructed
temps
and
local
variables
are
cleaned
up
in
all
unwinded
scopes
.
Completed
parts
of
partially
constructed
objects
are
not
cleaned
up
.
Don
'
t
expect
exception
handling
to
work
right
if
you
optimize
,
in
fact
the
compiler
will
probably
core
dump
.
If
two
EH
regions
are
the
exact
same
size
,
the
backend
cannot
tell
which
one
is
first
.
It
punts
by
picking
the
last
one
,
if
they
tie
.
This
is
usually
right
.
We
really
should
stick
in
a
nop
,
if
they
are
the
same
size
.
Only
exact
type
matching
or
reference
matching
of
throw
types
works
when
-
fno
-
rtti
is
used
.
Only
works
on
a
SPARC
(
like
Suns
),
i386
,
arm
and
rs6000
machines
.
Partial
support
is
also
in
for
alpha
,
hppa
,
m68k
and
mips
machines
,
but
a
stack
unwinder
called
__unwind_function
has
to
be
written
,
and
added
to
libgcc2
for
them
.
See
below
for
details
on
__unwind_function
.
All
completely
constructed
temps
and
local
variables
are
cleaned
up
in
all
unwinded
scopes
.
Completed
parts
of
partially
constructed
objects
are
cleaned
up
with
the
exception
that
partially
built
arrays
are
not
cleaned
up
as
required
.
Don
'
t
expect
exception
handling
to
work
right
if
you
optimize
,
in
fact
the
compiler
will
probably
core
dump
.
If
two
EH
regions
are
the
exact
same
size
,
the
backend
cannot
tell
which
one
is
first
.
It
punts
by
picking
the
last
one
,
if
they
tie
.
This
is
usually
right
.
We
really
should
stick
in
a
nop
,
if
they
are
the
same
size
.
When
we
invoke
the
copy
constructor
for
an
exception
object
because
it
is
passed
by
value
,
and
if
we
take
a
hit
(
exception
)
inside
the
copy
...
...
@@ -1232,6 +1239,52 @@ When the backend returns a value, it can create new exception regions
that
need
protecting
.
The
new
region
should
rethrow
the
object
in
context
of
the
last
associated
cleanup
that
ran
to
completion
.
The
__unwind_function
takes
a
pointer
to
the
throw
handler
,
and
is
expected
to
pop
the
stack
frame
that
was
built
to
call
it
,
as
well
as
the
frame
underneath
and
then
jump
to
the
throw
handler
.
It
must
not
change
the
three
registers
allocated
for
the
pointer
to
the
exception
object
,
the
pointer
to
the
type
descriptor
that
identifies
the
type
of
the
exception
object
,
and
the
pointer
to
the
code
that
threw
.
On
hppa
,
these
are
%
r5
,
%
r6
,
%
r7
.
On
m68k
these
are
a2
,
a3
,
a4
.
On
mips
they
are
s0
,
s1
,
s2
.
On
Alpha
these
are
$
9
,
$
10
,
$
11
.
It
takes
about
a
day
to
write
this
routine
,
if
someone
wants
to
volunteer
to
write
this
routine
for
any
architecture
,
exception
support
for
that
architecture
will
be
added
to
g
++
.
Please
send
in
those
code
donations
.
The
backend
must
be
extended
to
fully
support
exceptions
.
Right
now
there
are
a
few
hooks
into
the
alpha
exception
handling
backend
that
resides
in
the
C
++
frontend
from
that
backend
that
allows
exception
handling
to
work
in
g
++
.
An
exception
region
is
a
segment
of
generated
code
that
has
a
handler
associated
with
it
.
The
exception
regions
are
denoted
in
the
generated
code
as
address
ranges
denoted
by
a
starting
PC
value
and
an
ending
PC
value
of
the
region
.
Some
of
the
limitations
with
this
scheme
are
:
@itemize
@bullet
@item
The
backend
replicates
insns
for
such
things
as
loop
unrolling
and
function
inlining
.
Right
now
,
there
are
no
hooks
into
the
frontend
'
s
exception
handling
backend
to
handle
the
replication
of
insns
.
When
replication
happens
,
a
new
exception
region
descriptor
needs
to
be
generated
for
the
new
region
.
@item
The
backend
expects
to
be
able
to
rearrange
code
,
for
things
like
jump
optimization
.
Any
rearranging
of
the
code
needs
have
exception
region
descriptors
updated
appropriately
.
@item
The
backend
can
eliminate
dead
code
.
Any
associated
exception
region
descriptor
that
refers
to
fully
contained
code
that
has
been
eliminated
should
also
be
removed
,
although
not
doing
this
is
harmless
in
terms
of
semantics
.
#end itemize
The
above
is
not
meant
to
be
exhaustive
,
but
does
include
all
things
I
have
thought
of
so
far
.
I
am
sure
other
limitations
exist
.
@node
Free
Store
,
Concept
Index
,
Exception
Handling
,
Top
@section
Free
Store
...
...
gcc/cp/init.c
View file @
e8abc66f
...
...
@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "rtl.h"
#include "cp-tree.h"
#include "flags.h"
#include "output.h"
#undef NULL
#define NULL 0
...
...
@@ -1202,8 +1203,7 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
}
if
(
init
&&
TREE_CHAIN
(
parms
)
==
NULL_TREE
&&
TYPE_HAS_CONSTRUCTOR
(
type
)
&&
!
TYPE_NEEDS_CONSTRUCTING
(
type
)
&&
TYPE_HAS_TRIVIAL_INIT_REF
(
type
)
&&
TYPE_MAIN_VARIANT
(
type
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
init
)))
{
rval
=
build
(
INIT_EXPR
,
type
,
exp
,
init
);
...
...
gcc/cp/lex.c
View file @
e8abc66f
...
...
@@ -1801,6 +1801,8 @@ cons_up_default_function (type, full_name, kind)
||
!
flag_implement_inlines
);
TREE_STATIC
(
fn
)
=
!
DECL_EXTERNAL
(
fn
);
}
else
DECL_NOT_REALLY_EXTERN
(
fn
)
=
1
;
/* When on-the-fly synthesis works properly, remove the second and third
conditions here. */
...
...
@@ -1849,354 +1851,6 @@ cons_up_default_function (type, full_name, kind)
return
fn
;
}
#if 0
/* Used by default_copy_constructor_body. For the anonymous union
in TYPE, return the member that is at least as large as the rest
of the members, so we can copy it. */
static tree
largest_union_member (type)
tree type;
{
tree f, type_size = TYPE_SIZE (type);
for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f))
if (simple_cst_equal (DECL_SIZE (f), type_size))
return f;
/* We should always find one. */
my_friendly_abort (323);
return NULL_TREE;
}
/* Construct the body of a default assignment operator.
Mostly copied directly from default_copy_constructor_body. */
static void
default_assign_ref_body (bufp, lenp, type, fields)
char **bufp;
int *lenp;
tree type, fields;
{
static struct obstack body;
static int inited = FALSE;
int n_bases = CLASSTYPE_N_BASECLASSES (type);
char *tbuf;
int tgot, tneed;
if (!inited)
{
obstack_init (&body);
inited = TRUE;
}
body.next_free = body.object_base;
obstack_1grow (&body, '{');
/* Small buffer for sprintf(). */
tgot = 100;
tbuf = (char *) alloca (tgot);
/* If we don't need a real op=, just do a bitwise copy. */
if (! TYPE_HAS_COMPLEX_ASSIGN_REF (type))
{
tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));return *this;}";
*lenp = strlen (tbuf);
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
strcpy (*bufp, tbuf);
return;
}
if (TREE_CODE (type) == UNION_TYPE)
{
if (fields)
{
tree main = fields;
char * s;
tree f;
for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f))
if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)),
TYPE_SIZE (TREE_TYPE (f))))
main = f;
s = IDENTIFIER_POINTER (DECL_NAME (main));
tneed = (2 * strlen (s)) + 28;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "{%s=_ctor_arg.%s;return *this;}", s, s);
}
else
tbuf = "{}";
*lenp = strlen (tbuf);
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
strcpy (*bufp, tbuf);
return;
}
/* Construct base classes...
FIXME: Does not deal with multiple inheritance and virtual bases
correctly. See g++.old-deja/g++.jason/opeq5.C for a testcase.
We need to do wacky things if everything between us and the virtual
base (by all paths) has a "complex" op=. */
if (n_bases)
{
tree bases = TYPE_BINFO_BASETYPES (type);
int i = 0;
for (i = 0; i < n_bases; i++)
{
tree binfo = TREE_VEC_ELT (bases, i);
tree btype, name;
char *s;
btype = BINFO_TYPE (binfo);
name = TYPE_NESTED_NAME (btype);
s = IDENTIFIER_POINTER (name);
tneed = (2 * strlen (s)) + 42;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "%s::operator=((%s%s ::%s&)_ctor_arg);", s,
TYPE_READONLY (type) ? "const " : "",
CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct",
s);
obstack_grow (&body, tbuf, strlen (tbuf));
}
}
/* Construct fields. */
if (fields)
{
tree f;
for (f = fields; f; f = TREE_CHAIN (f))
{
if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f))
{
char *s;
tree x;
tree t = TREE_TYPE (f);
if (DECL_NAME (f))
x = f;
else if (t != NULL_TREE
&& TREE_CODE (t) == UNION_TYPE
&& ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE
&& ANON_AGGRNAME_P (TYPE_NAME (t)))
|| (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))
&& TYPE_FIELDS (t) != NULL_TREE)
x = largest_union_member (t);
else
continue;
s = IDENTIFIER_POINTER (DECL_NAME (x));
tneed = (2 * strlen (s)) + 13;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "%s=_ctor_arg.%s;", s, s);
obstack_grow (&body, tbuf, strlen (tbuf));
}
}
}
obstack_grow (&body, "return *this;}", 15);
*lenp = obstack_object_size (&body) - 1;
*bufp = obstack_alloc (&inline_text_obstack, *lenp);
strcpy (*bufp, body.object_base);
}
/* Construct the body of a default copy constructor. */
static void
default_copy_constructor_body (bufp, lenp, type, fields)
char **bufp;
int *lenp;
tree type, fields;
{
static struct obstack prologue;
static int inited = FALSE;
int n_bases = CLASSTYPE_N_BASECLASSES (type);
char sep = ':';
char *tbuf;
int tgot, tneed;
/* Create a buffer to call base class constructors and construct members
(fields). */
if (!inited)
{
obstack_init (&prologue);
inited = TRUE;
}
prologue.next_free = prologue.object_base;
/* If we don't need a real copy ctor, just do a bitwise copy. */
if (! TYPE_HAS_COMPLEX_INIT_REF (type))
{
tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));}";
*lenp = strlen (tbuf);
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
strcpy (*bufp, tbuf);
return;
}
/* Small buffer for sprintf(). */
tgot = 100;
tbuf = (char *) alloca (tgot);
if (TREE_CODE (type) == UNION_TYPE)
{
if (fields)
{
tree main = fields;
char * s;
tree f;
for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f))
if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)),
TYPE_SIZE (TREE_TYPE (f))))
main = f;
s = IDENTIFIER_POINTER (DECL_NAME (main));
tneed = (2 * strlen (s)) + 16;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, ":%s(_ctor_arg.%s){}", s, s);
}
else
tbuf = "{}";
*lenp = strlen (tbuf);
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
strcpy (*bufp, tbuf);
return;
}
/* Construct base classes... */
if (n_bases)
{
/* Note that CLASSTYPE_VBASECLASSES isn't set yet... */
tree v = get_vbase_types (type);
tree bases = TYPE_BINFO_BASETYPES (type);
int i = 0;
for (;;)
{
tree binfo, btype, name;
char *s;
if (v)
{
binfo = v;
v = TREE_CHAIN (v);
}
else if (i < n_bases)
{
binfo = TREE_VEC_ELT (bases, i++);
if (TREE_VIA_VIRTUAL (binfo))
continue;
}
else
break;
btype = BINFO_TYPE (binfo);
name = TYPE_NESTED_NAME (btype);
s = IDENTIFIER_POINTER (name);
tneed = (2 * strlen (s)) + 39;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "%c%s((%s%s ::%s&)_ctor_arg)", sep, s,
TYPE_READONLY (type) ? "const " : "",
CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct",
s);
sep = ',';
obstack_grow (&prologue, tbuf, strlen (tbuf));
}
}
/* Construct fields. */
if (fields)
{
tree f;
for (f = fields; f; f = TREE_CHAIN (f))
{
if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f))
{
char *s;
tree x;
tree t = TREE_TYPE (f);
if (DECL_NAME (f))
x = f;
else if (t != NULL_TREE
&& TREE_CODE (t) == UNION_TYPE
&& ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE
&& ANON_AGGRNAME_P (TYPE_NAME (t)))
|| (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))
&& TYPE_FIELDS (t) != NULL_TREE)
x = largest_union_member (t);
else
continue;
s = IDENTIFIER_POINTER (DECL_NAME (x));
tneed = (2 * strlen (s)) + 30;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "%c%s(_ctor_arg.%s)", sep, s, s);
sep = ',';
obstack_grow (&prologue, tbuf, strlen (tbuf));
}
}
}
/* Concatenate constructor body to prologue. */
*lenp = obstack_object_size (&prologue) + 2;
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
obstack_1grow (&prologue, '\0');
strcpy (*bufp, prologue.object_base);
strcat (*bufp, "{}");
}
#endif
/* Heuristic to tell whether the user is missing a semicolon
after a struct or enum declaration. Emit an error message
if we know the user has blown it. */
...
...
gcc/cp/method.c
View file @
e8abc66f
...
...
@@ -2052,7 +2052,7 @@ do_build_copy_constructor (fndecl)
parm
=
TREE_CHAIN
(
parm
);
parm
=
convert_from_reference
(
parm
);
if
(
!
TYPE_HAS_COMPLEX
_INIT_REF
(
current_class_type
))
if
(
TYPE_HAS_TRIVIAL
_INIT_REF
(
current_class_type
))
{
t
=
build
(
INIT_EXPR
,
void_type_node
,
C_C_D
,
parm
);
TREE_SIDE_EFFECTS
(
t
)
=
1
;
...
...
@@ -2140,7 +2140,7 @@ do_build_assign_ref (fndecl)
parm
=
convert_from_reference
(
parm
);
if
(
!
TYPE_HAS_COMPLEX
_ASSIGN_REF
(
current_class_type
))
if
(
TYPE_HAS_TRIVIAL
_ASSIGN_REF
(
current_class_type
))
{
tree
t
=
build
(
MODIFY_EXPR
,
void_type_node
,
C_C_D
,
parm
);
TREE_SIDE_EFFECTS
(
t
)
=
1
;
...
...
gcc/cp/parse.y
View file @
e8abc66f
...
...
@@ -53,6 +53,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "flags.h"
#include "lex.h"
#include "cp-tree.h"
#include "output.h"
/* Since parsers are distinct for each language, put the language string
definition here. (fnf) */
...
...
gcc/cp/pt.c
View file @
e8abc66f
...
...
@@ -38,6 +38,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "decl.h"
#include "parse.h"
#include "lex.h"
#include "output.h"
extern
struct
obstack
permanent_obstack
;
extern
tree
grokdeclarator
();
...
...
@@ -2510,11 +2511,17 @@ do_function_instantiation (declspecs, declarator, storage)
tree
declspecs
,
declarator
,
storage
;
{
tree
decl
=
grokdeclarator
(
declarator
,
declspecs
,
NORMAL
,
0
,
0
);
tree
name
=
DECL_NAME
(
decl
)
;
tree
fn
=
IDENTIFIER_GLOBAL_VALUE
(
name
)
;
tree
name
;
tree
fn
;
tree
result
=
NULL_TREE
;
int
extern_p
=
0
;
if
(
fn
)
/* If we've already seen this template instance, use it. */
if
(
name
=
DECL_ASSEMBLER_NAME
(
decl
),
fn
=
IDENTIFIER_GLOBAL_VALUE
(
name
),
fn
&&
DECL_TEMPLATE_INSTANTIATION
(
fn
))
result
=
fn
;
else
if
(
name
=
DECL_NAME
(
decl
),
fn
=
IDENTIFIER_GLOBAL_VALUE
(
name
),
fn
)
{
for
(
fn
=
get_first_fn
(
fn
);
fn
;
fn
=
DECL_CHAIN
(
fn
))
if
(
decls_match
(
fn
,
decl
)
...
...
@@ -2578,12 +2585,14 @@ mark_class_instantiated (t, extern_p)
rest_of_type_compilation
(
t
,
1
);
}
}
void
do_type_instantiation
(
name
,
storage
)
tree
name
,
storage
;
{
tree
t
=
TREE_TYPE
(
name
);
int
extern_p
;
int
extern_p
=
0
;
int
nomem_p
=
0
;
/* With -fexternal-templates, explicit instantiations are treated the same
as implicit ones. */
...
...
@@ -2598,7 +2607,9 @@ do_type_instantiation (name, storage)
}
if
(
storage
==
NULL_TREE
)
extern_p
=
0
;
/* OK */
;
else
if
(
storage
==
ridpointers
[(
int
)
RID_INLINE
])
nomem_p
=
1
;
else
if
(
storage
==
ridpointers
[(
int
)
RID_EXTERN
])
extern_p
=
1
;
else
...
...
@@ -2618,7 +2629,10 @@ do_type_instantiation (name, storage)
mark_class_instantiated
(
t
,
extern_p
);
repo_template_instantiated
(
t
,
extern_p
);
}
if
(
nomem_p
)
return
;
{
tree
tmp
;
/* Classes nested in template classes currently don't have an
...
...
gcc/cp/repo.c
View file @
e8abc66f
...
...
@@ -33,14 +33,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
extern
char
*
rindex
();
extern
char
*
getenv
();
extern
char
*
getpwd
();
static
tree
pending_repo
;
static
tree
original_repo
;
static
char
repo_name
[
1024
]
;
static
char
*
repo_name
;
static
FILE
*
repo_file
;
extern
int
flag_use_repository
;
extern
int
errorcount
,
sorrycount
;
extern
struct
obstack
temporary_obstack
;
extern
struct
obstack
permanent_obstack
;
#define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE))
#define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE))
...
...
@@ -187,7 +190,6 @@ save_string (s, len)
char
*
s
;
int
len
;
{
extern
struct
obstack
temporary_obstack
;
return
obstack_copy0
(
&
temporary_obstack
,
s
,
len
);
}
...
...
@@ -244,36 +246,42 @@ open_repo_file (filename)
char
*
filename
;
{
register
char
*
p
,
*
q
;
char
*
file
=
get_base_filename
(
filename
);
char
*
s
;
char
*
s
=
get_base_filename
(
filename
);
if
(
file
==
NULL
)
if
(
s
==
NULL
)
return
;
s
=
rindex
(
file
,
'/'
);
if
(
s
==
NULL
)
s
=
file
;
else
++
s
;
p
=
rindex
(
s
,
'/'
);
if
(
!
p
)
p
=
s
;
p
=
rindex
(
p
,
'.'
);
if
(
!
p
)
p
=
s
+
strlen
(
s
);
for
(
p
=
repo_name
,
q
=
file
;
q
<
s
;
)
*
p
++
=
*
q
++
;
/* *p++ = '.'; */
if
((
s
=
rindex
(
q
,
'.'
))
==
NULL
)
strcpy
(
p
,
q
);
else
for
(;
q
<
s
;)
*
p
++
=
*
q
++
;
strcat
(
p
,
".rpo"
);
obstack_grow
(
&
permanent_obstack
,
s
,
p
-
s
);
repo_name
=
obstack_copy0
(
&
permanent_obstack
,
".rpo"
,
4
);
repo_file
=
fopen
(
repo_name
,
"r"
);
}
static
char
*
afgets
(
stream
)
FILE
*
stream
;
{
int
c
;
while
((
c
=
getc
(
stream
))
!=
EOF
&&
c
!=
'\n'
)
obstack_1grow
(
&
temporary_obstack
,
c
);
if
(
obstack_object_size
(
&
temporary_obstack
)
==
0
)
return
NULL
;
obstack_1grow
(
&
temporary_obstack
,
'\0'
);
return
obstack_finish
(
&
temporary_obstack
);
}
void
init_repo
(
filename
)
char
*
filename
;
{
char
buf
[
1024
]
;
char
*
buf
;
if
(
!
flag_use_repository
)
return
;
...
...
@@ -283,23 +291,19 @@ init_repo (filename)
if
(
repo_file
==
0
)
return
;
while
(
fgets
(
buf
,
1024
,
repo_file
))
while
(
buf
=
afgets
(
repo_file
))
{
switch
(
buf
[
0
])
{
case
'A'
:
case
'
G
'
:
case
'
D
'
:
case
'M'
:
break
;
case
'C'
:
case
'O'
:
{
char
*
q
;
tree
id
,
orig
;
for
(
q
=
&
buf
[
2
];
*
q
&&
*
q
!=
' '
&&
*
q
!=
'\n'
;
++
q
)
;
q
=
save_string
(
&
buf
[
2
],
q
-
&
buf
[
2
]);
id
=
get_identifier
(
q
);
tree
id
=
get_identifier
(
buf
+
2
);
tree
orig
;
if
(
buf
[
0
]
==
'C'
)
{
...
...
@@ -315,6 +319,7 @@ init_repo (filename)
default
:
error
(
"mysterious repository information in %s"
,
repo_name
);
}
obstack_free
(
&
temporary_obstack
,
buf
);
}
}
...
...
@@ -382,9 +387,8 @@ finish_repo ()
fprintf
(
repo_file
,
"M %s
\n
"
,
main_input_filename
);
p
=
getenv
(
"COLLECT_GCC"
);
if
(
p
!=
0
)
fprintf
(
repo_file
,
"G %s
\n
"
,
p
);
p
=
getpwd
();
fprintf
(
repo_file
,
"D %s
\n
"
,
p
);
p
=
getenv
(
"COLLECT_GCC_OPTIONS"
);
if
(
p
!=
0
)
...
...
@@ -395,9 +399,7 @@ finish_repo ()
tree
val
=
TREE_VALUE
(
t
);
char
type
=
IDENTIFIER_REPO_CHOSEN
(
val
)
?
'C'
:
'O'
;
fprintf
(
repo_file
,
"%c %s "
,
type
,
IDENTIFIER_POINTER
(
val
));
ASM_OUTPUT_LABELREF
(
repo_file
,
IDENTIFIER_POINTER
(
val
));
putc
(
'\n'
,
repo_file
);
fprintf
(
repo_file
,
"%c %s
\n
"
,
type
,
IDENTIFIER_POINTER
(
val
));
}
out
:
...
...
gcc/cp/search.c
View file @
e8abc66f
...
...
@@ -28,12 +28,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "obstack.h"
#include "flags.h"
#include "rtl.h"
#include "output.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
void
init_search
();
extern
struct
obstack
*
current_obstack
;
extern
tree
abort_fndecl
;
#include "stack.h"
...
...
@@ -2626,6 +2628,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, t, vbase_offsets)
current_fndecl
=
FNADDR_FROM_VTABLE_ENTRY
(
current_fndecl
);
current_fndecl
=
TREE_OPERAND
(
current_fndecl
,
0
);
if
(
current_fndecl
&&
current_fndecl
!=
abort_fndecl
&&
(
vc
=
virtual_context
(
current_fndecl
,
t
,
vbase
))
!=
vbase
)
{
/* This may in fact need a runtime fixup. */
...
...
gcc/cp/tree.c
View file @
e8abc66f
...
...
@@ -153,7 +153,7 @@ lvalue_p (ref)
return
1
;
case
CALL_EXPR
:
if
(
TREE_ADDRESSABL
E
(
TREE_TYPE
(
ref
)))
if
(
IS_AGGR_TYP
E
(
TREE_TYPE
(
ref
)))
return
1
;
break
;
...
...
@@ -217,9 +217,13 @@ build_cplus_new (type, init, with_cleanup_p)
tree
init
;
int
with_cleanup_p
;
{
tree
slot
=
build
(
VAR_DECL
,
type
);
tree
rval
=
build
(
NEW_EXPR
,
type
,
TREE_OPERAND
(
init
,
0
),
TREE_OPERAND
(
init
,
1
),
slot
);
tree
slot
;
tree
rval
;
slot
=
build
(
VAR_DECL
,
type
);
layout_decl
(
slot
,
0
);
rval
=
build
(
NEW_EXPR
,
type
,
TREE_OPERAND
(
init
,
0
),
TREE_OPERAND
(
init
,
1
),
slot
);
TREE_SIDE_EFFECTS
(
rval
)
=
1
;
TREE_ADDRESSABLE
(
rval
)
=
1
;
rval
=
build
(
TARGET_EXPR
,
type
,
slot
,
rval
,
0
);
...
...
gcc/cp/typeck.c
View file @
e8abc66f
...
...
@@ -37,6 +37,7 @@ extern void warning ();
#include "rtl.h"
#include "cp-tree.h"
#include "flags.h"
#include "output.h"
int
mark_addressable
();
static
tree
convert_for_assignment
();
...
...
@@ -2665,8 +2666,7 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
/* Convert `float' to `double'. */
result
=
tree_cons
(
NULL_TREE
,
convert
(
double_type_node
,
val
),
result
);
else
if
(
TYPE_LANG_SPECIFIC
(
TREE_TYPE
(
val
))
&&
(
!
TYPE_HAS_INIT_REF
(
TREE_TYPE
(
val
))
||
TYPE_HAS_COMPLEX_INIT_REF
(
TREE_TYPE
(
val
))))
&&
!
TYPE_HAS_TRIVIAL_INIT_REF
(
TREE_TYPE
(
val
)))
{
cp_warning
(
"cannot pass objects of type `%T' through `...'"
,
TREE_TYPE
(
val
));
...
...
@@ -5454,6 +5454,26 @@ init_noncopied_parts (lhs, list)
return
parts
;
}
tree
expand_target_expr
(
t
)
tree
t
;
{
tree
xval
=
make_node
(
RTL_EXPR
);
rtx
rtxval
;
do_pending_stack_adjust
();
start_sequence_for_rtl_expr
(
xval
);
emit_note
(
0
,
-
1
);
rtxval
=
expand_expr
(
t
,
NULL
,
VOIDmode
,
0
);
do_pending_stack_adjust
();
TREE_SIDE_EFFECTS
(
xval
)
=
1
;
RTL_EXPR_SEQUENCE
(
xval
)
=
get_insns
();
end_sequence
();
RTL_EXPR_RTL
(
xval
)
=
rtxval
;
TREE_TYPE
(
xval
)
=
TREE_TYPE
(
t
);
return
xval
;
}
/* Build an assignment expression of lvalue LHS from value RHS.
MODIFYCODE is the code for a binary operator that we use
to combine the old value of LHS with RHS to get the new value.
...
...
@@ -5586,7 +5606,7 @@ build_modify_expr (lhs, modifycode, rhs)
/* Do the default thing */
;
else
if
(
!
TYPE_HAS_CONSTRUCTOR
(
lhstype
))
cp_error
(
"`%T' has no constructors"
,
lhstype
);
else
if
(
!
TYPE_NEEDS_CONSTRUCTING
(
lhstype
)
else
if
(
TYPE_HAS_TRIVIAL_INIT_REF
(
lhstype
)
&&
TYPE_MAIN_VARIANT
(
lhstype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
newrhs
)))
/* Do the default thing */
;
else
...
...
@@ -5607,8 +5627,7 @@ build_modify_expr (lhs, modifycode, rhs)
/* Do the default thing */
;
else
if
(
!
TYPE_HAS_ASSIGNMENT
(
lhstype
))
cp_error
(
"`%T' does not define operator="
,
lhstype
);
else
if
(
!
TYPE_HAS_REAL_ASSIGNMENT
(
lhstype
)
&&
!
TYPE_HAS_COMPLEX_ASSIGN_REF
(
lhstype
)
else
if
(
TYPE_HAS_TRIVIAL_ASSIGN_REF
(
lhstype
)
&&
TYPE_MAIN_VARIANT
(
lhstype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
newrhs
)))
/* Do the default thing */
;
else
...
...
@@ -6002,28 +6021,12 @@ build_modify_expr (lhs, modifycode, rhs)
&&
TYPE_NEEDS_CONSTRUCTING
(
lhstype
))
newrhs
=
build_cplus_new
(
lhstype
,
newrhs
,
0
);
/* Can't initialize directly from a TARGET_EXPR, since that would
cause the lhs to be constructed twice. So we force the
TARGET_EXPR to be expanded. expand_expr should really do this
by itself. */
if
(
TREE_CODE
(
newrhs
)
==
TARGET_EXPR
)
{
/* Can't initialize directly from a TARGET_EXPR, since that would
cause the lhs to be constructed twice. So we force the
TARGET_EXPR to be expanded. expand_expr should really do this
by itself. */
tree
xval
=
make_node
(
RTL_EXPR
);
rtx
rtxval
;
do_pending_stack_adjust
();
start_sequence_for_rtl_expr
(
xval
);
emit_note
(
0
,
-
1
);
rtxval
=
expand_expr
(
newrhs
,
NULL
,
VOIDmode
,
0
);
do_pending_stack_adjust
();
TREE_SIDE_EFFECTS
(
xval
)
=
1
;
RTL_EXPR_SEQUENCE
(
xval
)
=
get_insns
();
end_sequence
();
RTL_EXPR_RTL
(
xval
)
=
rtxval
;
TREE_TYPE
(
xval
)
=
lhstype
;
newrhs
=
xval
;
}
newrhs
=
expand_target_expr
(
newrhs
);
}
if
(
TREE_CODE
(
newrhs
)
==
ERROR_MARK
)
...
...
@@ -6964,6 +6967,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
rhs
=
build_cplus_new
(
type
,
TREE_OPERAND
(
rhs
,
0
),
0
);
return
rhs
;
}
else
if
(
TYPE_HAS_TRIVIAL_INIT_REF
(
type
))
return
rhs
;
}
if
(
TYPE_MAIN_VARIANT
(
type
)
==
TYPE_MAIN_VARIANT
(
rhstype
)
||
(
IS_AGGR_TYPE
(
rhstype
)
&&
UNIQUELY_DERIVED_FROM_P
(
type
,
rhstype
)))
...
...
@@ -7227,6 +7232,13 @@ c_expand_return (retval)
(3) If an X(X&) constructor is defined, the return
value must be returned via that. */
/* If we're returning in a register, we can't initialize the
return value from a TARGET_EXPR. */
if
(
TREE_CODE
(
retval
)
==
TARGET_EXPR
&&
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
retval
))
==
TYPE_MAIN_VARIANT
(
valtype
)
&&
!
current_function_returns_struct
)
retval
=
expand_target_expr
(
retval
);
if
(
retval
==
result
/* Watch out for constructors, which "return" aggregates
via initialization, but which otherwise "return" a pointer. */
...
...
@@ -7243,12 +7255,8 @@ c_expand_return (retval)
use_temp
=
obey_regdecls
;
}
}
else
if
(
IS_AGGR_TYPE
(
valtype
)
&&
TYPE_NEEDS_CONSTRUCTING
(
valtype
)
)
else
if
(
IS_AGGR_TYPE
(
valtype
)
&&
current_function_returns_struct
)
{
/* Throw away the cleanup that `build_functional_cast' gave us. */
if
(
TREE_CODE
(
retval
)
==
WITH_CLEANUP_EXPR
&&
TREE_CODE
(
TREE_OPERAND
(
retval
,
0
))
==
TARGET_EXPR
)
retval
=
TREE_OPERAND
(
retval
,
0
);
expand_aggr_init
(
result
,
retval
,
0
,
LOOKUP_ONLYCONVERTING
);
expand_cleanups_to
(
NULL_TREE
);
DECL_INITIAL
(
result
)
=
NULL_TREE
;
...
...
gcc/cp/typeck2.c
View file @
e8abc66f
...
...
@@ -540,11 +540,12 @@ store_init_value (decl, init)
/* Take care of C++ business up here. */
type
=
TYPE_MAIN_VARIANT
(
type
);
/* implicitly tests if IS_AGGR_TYPE. */
if
(
TYPE_NEEDS_CONSTRUCTING
(
type
)
&&
TREE_CODE
(
init
)
!=
CONSTRUCTOR
)
my_friendly_abort
(
109
);
else
if
(
IS_AGGR_TYPE
(
type
))
if
(
IS_AGGR_TYPE
(
type
))
{
if
(
!
TYPE_HAS_TRIVIAL_INIT_REF
(
type
)
&&
TREE_CODE
(
init
)
!=
CONSTRUCTOR
)
my_friendly_abort
(
109
);
/* Although we are not allowed to declare variables of signature
type, we complain about a possible constructor call in such a
declaration as well. */
...
...
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