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
eb66be0e
Commit
eb66be0e
authored
Apr 23, 1997
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
91th Cygnus<->FSF merge
From-SVN: r13971
parent
2ec43107
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
314 additions
and
667 deletions
+314
-667
gcc/cp/ChangeLog
+0
-0
gcc/cp/Make-lang.in
+1
-1
gcc/cp/call.c
+59
-27
gcc/cp/class.c
+4
-2
gcc/cp/cp-tree.h
+2
-0
gcc/cp/cvt.c
+14
-233
gcc/cp/decl.c
+42
-58
gcc/cp/decl2.c
+8
-18
gcc/cp/except.c
+86
-38
gcc/cp/exception.cc
+7
-12
gcc/cp/init.c
+19
-57
gcc/cp/lang-options.h
+0
-2
gcc/cp/method.c
+40
-203
gcc/cp/pt.c
+3
-0
gcc/cp/spew.c
+3
-5
gcc/cp/tinfo2.cc
+1
-1
gcc/cp/tree.c
+15
-0
gcc/cp/typeck.c
+10
-10
No files found.
gcc/cp/ChangeLog
View file @
eb66be0e
This diff is collapsed.
Click to expand it.
gcc/cp/Make-lang.in
View file @
eb66be0e
...
...
@@ -144,7 +144,7 @@ tinfo2.o: cc1plus $(srcdir)/cp/tinfo2.cc
-c
$(srcdir)
/cp/tinfo2.cc
exception.o
:
cc1plus $(srcdir)/cp/exception.cc
$(GCC_FOR_TARGET)
$(LIBGCC2_CFLAGS)
$(INCLUDES)
\
-c
-
O0
-
fexceptions
$(srcdir)
/cp/exception.cc
-c
-fexceptions
$(srcdir)
/cp/exception.cc
new.o
:
cc1plus $(srcdir)/cp/new.cc
$(GCC_FOR_TARGET)
$(LIBGCC2_CFLAGS)
$(INCLUDES)
\
-c
$(srcdir)
/cp/new.cc
...
...
gcc/cp/call.c
View file @
eb66be0e
...
...
@@ -3187,13 +3187,18 @@ reference_binding (rto, rfrom, expr, flags)
int
lvalue
=
1
;
tree
to
=
TREE_TYPE
(
rto
);
tree
from
=
rfrom
;
int
related
;
if
(
TREE_CODE
(
from
)
==
REFERENCE_TYPE
)
from
=
TREE_TYPE
(
from
);
else
if
(
!
expr
||
!
real_lvalue_p
(
expr
))
lvalue
=
0
;
if
(
lvalue
related
=
(
TYPE_MAIN_VARIANT
(
to
)
==
TYPE_MAIN_VARIANT
(
from
)
||
(
IS_AGGR_TYPE
(
to
)
&&
IS_AGGR_TYPE
(
from
)
&&
DERIVED_FROM_P
(
to
,
from
)));
if
(
lvalue
&&
related
&&
TYPE_READONLY
(
to
)
>=
TYPE_READONLY
(
from
)
&&
TYPE_VOLATILE
(
to
)
>=
TYPE_VOLATILE
(
from
))
{
...
...
@@ -3201,14 +3206,11 @@ reference_binding (rto, rfrom, expr, flags)
if
(
TYPE_MAIN_VARIANT
(
to
)
==
TYPE_MAIN_VARIANT
(
from
))
conv
=
build_conv
(
REF_BIND
,
rto
,
conv
);
else
if
(
IS_AGGR_TYPE
(
to
)
&&
IS_AGGR_TYPE
(
from
)
&&
DERIVED_FROM_P
(
to
,
from
))
else
{
conv
=
build_conv
(
REF_BIND
,
rto
,
conv
);
ICS_STD_RANK
(
conv
)
=
STD_RANK
;
}
else
conv
=
NULL_TREE
;
}
else
conv
=
NULL_TREE
;
...
...
@@ -3225,8 +3227,15 @@ reference_binding (rto, rfrom, expr, flags)
if
(
TREE_CODE
(
TREE_OPERAND
(
conv
,
0
))
==
BASE_CONV
)
TREE_OPERAND
(
conv
,
0
)
=
TREE_OPERAND
(
TREE_OPERAND
(
conv
,
0
),
0
);
}
if
(
conv
&&
!
(
TYPE_READONLY
(
to
)
&&
!
TYPE_VOLATILE
(
to
)
&&
(
flags
&
LOOKUP_NO_TEMP_BIND
)
==
0
))
if
(
conv
&&
((
!
(
TYPE_READONLY
(
to
)
&&
!
TYPE_VOLATILE
(
to
)
&&
(
flags
&
LOOKUP_NO_TEMP_BIND
)
==
0
))
/* If T1 is reference-related to T2, cv1 must be the same
cv-qualification as, or greater cv-qualification than,
cv2; otherwise, the program is ill-formed. */
||
(
related
&&
(
TYPE_READONLY
(
to
)
<
TYPE_READONLY
(
from
)
||
TYPE_VOLATILE
(
to
)
<
TYPE_VOLATILE
(
from
)))))
ICS_BAD_FLAG
(
conv
)
=
1
;
}
...
...
@@ -3265,7 +3274,12 @@ implicit_conversion (to, from, expr, flags)
||
IS_AGGR_TYPE
(
non_reference
(
to
)))
&&
(
flags
&
LOOKUP_NO_CONVERSION
)
==
0
)
{
if
(
TREE_CODE
(
to
)
==
REFERENCE_TYPE
cand
=
build_user_type_conversion_1
(
to
,
expr
,
LOOKUP_ONLYCONVERTING
);
if
(
cand
)
conv
=
cand
->
second_conv
;
if
((
!
conv
||
ICS_BAD_FLAG
(
conv
))
&&
TREE_CODE
(
to
)
==
REFERENCE_TYPE
&&
TYPE_READONLY
(
TREE_TYPE
(
to
))
&&
!
TYPE_VOLATILE
(
TREE_TYPE
(
to
))
&&
(
flags
&
LOOKUP_NO_TEMP_BIND
)
==
0
)
...
...
@@ -3275,13 +3289,6 @@ implicit_conversion (to, from, expr, flags)
if
(
cand
)
conv
=
build_conv
(
REF_BIND
,
to
,
cand
->
second_conv
);
}
else
{
cand
=
build_user_type_conversion_1
(
to
,
expr
,
LOOKUP_ONLYCONVERTING
);
if
(
cand
)
conv
=
cand
->
second_conv
;
}
}
return
conv
;
...
...
@@ -4181,7 +4188,10 @@ print_z_candidates (candidates)
}
/* Returns the best overload candidate to perform the requested
conversion. */
conversion. This function is used for three the overloading situations
described in [over.match.copy], [over.match.conv], and [over.match.ref].
If TOTYPE is a REFERENCE_TYPE, we're trying to find an lvalue binding as
per [dcl.init.ref], so we ignore temporary bindings. */
static
struct
z_candidate
*
build_user_type_conversion_1
(
totype
,
expr
,
flags
)
...
...
@@ -4229,9 +4239,22 @@ build_user_type_conversion_1 (totype, expr, flags)
for
(;
convs
;
convs
=
TREE_CHAIN
(
convs
))
{
tree
fn
=
TREE_VALUE
(
convs
);
tree
ics
=
implicit_conversion
(
totype
,
TREE_TYPE
(
TREE_TYPE
(
fn
)),
0
,
LOOKUP_NO_CONVERSION
);
if
(
ics
)
int
convflags
=
LOOKUP_NO_CONVERSION
;
tree
ics
;
/* If we are called to convert to a reference type, we are trying to
find an lvalue binding, so don't even consider temporaries. If
we don't find an lvalue binding, the caller will try again to
look for a temporary binding. */
if
(
TREE_CODE
(
totype
)
==
REFERENCE_TYPE
)
convflags
|=
LOOKUP_NO_TEMP_BIND
;
ics
=
implicit_conversion
(
totype
,
TREE_TYPE
(
TREE_TYPE
(
fn
)),
0
,
convflags
);
if
(
TREE_CODE
(
totype
)
==
REFERENCE_TYPE
&&
ics
&&
ICS_BAD_FLAG
(
ics
))
/* ignore the near match. */
;
else
if
(
ics
)
for
(;
fn
;
fn
=
DECL_CHAIN
(
fn
))
{
candidates
=
add_function_candidate
(
candidates
,
fn
,
args
,
flags
);
...
...
@@ -4348,9 +4371,10 @@ build_new_function_call (fn, args, obj)
{
if
(
candidates
&&
!
candidates
->
next
)
return
build_function_call
(
candidates
->
fn
,
args
);
else
cp_error
(
"no matching function for call to `%D (%A)'"
,
TREE_PURPOSE
(
fn
),
args
);
cp_error
(
"no matching function for call to `%D (%A)'"
,
TREE_PURPOSE
(
fn
),
args
);
if
(
candidates
)
print_z_candidates
(
candidates
);
return
error_mark_node
;
}
candidates
=
splice_viable
(
candidates
);
...
...
@@ -5037,11 +5061,12 @@ build_over_call (fn, convs, args, flags)
is_method
=
1
;
}
for
(;
conv
=
TREE_VEC_ELT
(
convs
,
i
),
arg
&&
parm
;
for
(;
arg
&&
parm
;
parm
=
TREE_CHAIN
(
parm
),
arg
=
TREE_CHAIN
(
arg
),
++
i
)
{
tree
type
=
TREE_VALUE
(
parm
);
conv
=
TREE_VEC_ELT
(
convs
,
i
);
if
(
ICS_BAD_FLAG
(
conv
))
{
tree
t
=
conv
;
...
...
@@ -5118,17 +5143,24 @@ build_over_call (fn, convs, args, flags)
&&
TREE_VEC_LENGTH
(
convs
)
==
1
&&
copy_args_p
(
fn
))
{
tree
targ
=
NULL_TREE
;
tree
targ
;
arg
=
TREE_VALUE
(
TREE_CHAIN
(
converted_args
));
/* Pull out the real argument, disregarding const-correctness. */
if
(
TREE_CODE
(
arg
)
==
ADDR_EXPR
)
{
targ
=
TREE_OPERAND
(
arg
,
0
);
targ
=
arg
;
while
(
TREE_CODE
(
targ
)
==
NOP_EXPR
||
TREE_CODE
(
targ
)
==
NON_LVALUE_EXPR
||
TREE_CODE
(
targ
)
==
CONVERT_EXPR
)
targ
=
TREE_OPERAND
(
targ
,
0
);
if
(
TREE_CODE
(
targ
)
==
ADDR_EXPR
)
{
targ
=
TREE_OPERAND
(
targ
,
0
);
if
(
!
comptypes
(
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
TREE_TYPE
(
arg
))),
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
targ
)),
1
))
targ
=
NULL_TREE
;
}
else
targ
=
NULL_TREE
;
if
(
targ
)
arg
=
targ
;
...
...
gcc/cp/class.c
View file @
eb66be0e
...
...
@@ -2809,6 +2809,7 @@ check_for_override (decl, ctype)
}
virtualp
=
1
;
#if 0 /* The signature of an overriding function is not changed. */
{
/* The argument types may have changed... */
tree type = TREE_TYPE (decl);
...
...
@@ -2823,9 +2824,10 @@ check_for_override (decl, ctype)
if (raises)
type = build_exception_variant (type, raises);
TREE_TYPE (decl) = type;
DECL_VINDEX
(
decl
)
=
tree_cons
(
NULL_TREE
,
tmp
,
DECL_VINDEX
(
decl
));
}
#endif
DECL_VINDEX
(
decl
)
=
tree_cons
(
NULL_TREE
,
tmp
,
DECL_VINDEX
(
decl
));
break
;
}
}
...
...
gcc/cp/cp-tree.h
View file @
eb66be0e
...
...
@@ -1195,10 +1195,12 @@ extern int flag_new_for_scope;
#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
&& CONSTRUCTOR_ELTS (NODE) == NULL_TREE)
#if 0
/* Indicates that a NON_LVALUE_EXPR came from a C++ reference.
Used to generate more helpful error message in case somebody
tries to take its address. */
#define TREE_REFERENCE_EXPR(NODE) (TREE_LANG_FLAG_3(NODE))
#endif
/* Nonzero for _TYPE means that the _TYPE defines a destructor. */
#define TYPE_HAS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_2(NODE))
...
...
gcc/cp/cvt.c
View file @
eb66be0e
...
...
@@ -371,232 +371,24 @@ convert_to_pointer_force (type, expr)
value we have to begin with is in ARG.
FLAGS controls how we manage access checking.
DIRECT_BIND in FLAGS controls how any temporarys are generated.
CHECKCONST controls if we report error messages on const subversion. */
DIRECT_BIND in FLAGS controls how any temporaries are generated. */
static
tree
build_up_reference
(
type
,
arg
,
flags
,
checkconst
)
tree
type
,
arg
;
int
flags
,
checkconst
;
{
tree
rval
,
targ
;
int
literal_flag
=
0
;
tree
rval
;
tree
argtype
=
TREE_TYPE
(
arg
);
tree
target_type
=
TREE_TYPE
(
type
);
tree
binfo
=
NULL_TREE
;
my_friendly_assert
(
TREE_CODE
(
type
)
==
REFERENCE_TYPE
,
187
);
if
((
flags
&
LOOKUP_PROTECT
)
&&
TYPE_MAIN_VARIANT
(
argtype
)
!=
TYPE_MAIN_VARIANT
(
target_type
)
&&
IS_AGGR_TYPE
(
argtype
)
&&
IS_AGGR_TYPE
(
target_type
))
{
binfo
=
get_binfo
(
target_type
,
argtype
,
1
);
if
(
binfo
==
error_mark_node
)
return
error_mark_node
;
if
(
binfo
==
NULL_TREE
)
return
error_not_base_type
(
target_type
,
argtype
);
}
/* Pass along const and volatile down into the type. */
if
(
TYPE_READONLY
(
type
)
||
TYPE_VOLATILE
(
type
))
target_type
=
cp_build_type_variant
(
target_type
,
TYPE_READONLY
(
type
),
TYPE_VOLATILE
(
type
));
targ
=
arg
;
if
(
TREE_CODE
(
targ
)
==
SAVE_EXPR
)
targ
=
TREE_OPERAND
(
targ
,
0
);
while
(
TREE_CODE
(
targ
)
==
NOP_EXPR
&&
(
TYPE_MAIN_VARIANT
(
argtype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
TREE_OPERAND
(
targ
,
0
)))))
targ
=
TREE_OPERAND
(
targ
,
0
);
switch
(
TREE_CODE
(
targ
))
{
case
INDIRECT_REF
:
/* This is a call to a constructor which did not know what it was
initializing until now: it needs to initialize a temporary. */
if
(
TREE_HAS_CONSTRUCTOR
(
targ
))
{
tree
temp
=
build_cplus_new
(
argtype
,
TREE_OPERAND
(
targ
,
0
));
TREE_HAS_CONSTRUCTOR
(
targ
)
=
0
;
return
build_up_reference
(
type
,
temp
,
flags
,
1
);
}
/* Let &* cancel out to simplify resulting code.
Also, throw away intervening NOP_EXPRs. */
arg
=
TREE_OPERAND
(
targ
,
0
);
if
(
TREE_CODE
(
arg
)
==
NOP_EXPR
||
TREE_CODE
(
arg
)
==
NON_LVALUE_EXPR
||
(
TREE_CODE
(
arg
)
==
CONVERT_EXPR
&&
TREE_REFERENCE_EXPR
(
arg
)))
arg
=
TREE_OPERAND
(
arg
,
0
);
/* in doing a &*, we have to get rid of the const'ness on the pointer
value. Haven't thought about volatile here. Pointers come to mind
here. */
if
(
TREE_READONLY
(
arg
))
{
arg
=
copy_node
(
arg
);
TREE_READONLY
(
arg
)
=
0
;
}
rval
=
build1
(
CONVERT_EXPR
,
type
,
arg
);
TREE_REFERENCE_EXPR
(
rval
)
=
1
;
/* propagate the const flag on something like:
class Base {
public:
int foo;
};
class Derived : public Base {
public:
int bar;
};
void func(Base&);
void func2(const Derived& d) {
func(d);
}
on the d parameter. The below could have been avoided, if the flags
were down in the tree, not sure why they are not. (mrs) */
/* The below code may have to be propagated to other parts of this
switch. */
if
(
TREE_READONLY
(
targ
)
&&
!
TREE_READONLY
(
arg
)
&&
(
TREE_CODE
(
arg
)
==
PARM_DECL
||
TREE_CODE
(
arg
)
==
VAR_DECL
)
&&
TREE_CODE
(
TREE_TYPE
(
arg
))
==
REFERENCE_TYPE
&&
(
TYPE_READONLY
(
target_type
)
&&
checkconst
))
{
arg
=
copy_node
(
arg
);
TREE_READONLY
(
arg
)
=
TREE_READONLY
(
targ
);
}
literal_flag
=
TREE_CONSTANT
(
arg
);
goto
done
;
/* Get this out of a register if we happened to be in one by accident.
Also, build up references to non-lvalues it we must. */
/* For &x[y], return (&) x+y */
case
ARRAY_REF
:
if
(
mark_addressable
(
TREE_OPERAND
(
targ
,
0
))
==
0
)
return
error_mark_node
;
rval
=
build_binary_op
(
PLUS_EXPR
,
TREE_OPERAND
(
targ
,
0
),
TREE_OPERAND
(
targ
,
1
),
1
);
TREE_TYPE
(
rval
)
=
type
;
if
(
TREE_CONSTANT
(
TREE_OPERAND
(
targ
,
1
))
&&
staticp
(
TREE_OPERAND
(
targ
,
0
)))
TREE_CONSTANT
(
rval
)
=
1
;
goto
done
;
case
SCOPE_REF
:
/* Could be a reference to a static member. */
{
tree
field
=
TREE_OPERAND
(
targ
,
1
);
if
(
TREE_STATIC
(
field
))
{
rval
=
build1
(
ADDR_EXPR
,
type
,
field
);
literal_flag
=
1
;
goto
done
;
}
}
/* We should have farmed out member pointers above. */
my_friendly_abort
(
188
);
case
COMPONENT_REF
:
rval
=
build_component_addr
(
targ
,
build_pointer_type
(
argtype
),
"attempt to make a reference to bit-field structure member `%s'"
);
TREE_TYPE
(
rval
)
=
type
;
literal_flag
=
staticp
(
TREE_OPERAND
(
targ
,
0
));
goto
done
;
/* Anything not already handled and not a true memory reference
needs to have a reference built up. Do so silently for
things like integers and return values from function,
but complain if we need a reference to something declared
as `register'. */
case
PARM_DECL
:
/* 'this' is not an lvalue. */
if
(
targ
==
current_class_ptr
&&
!
flag_this_is_variable
)
break
;
case
RESULT_DECL
:
case
VAR_DECL
:
case
CONST_DECL
:
if
(
staticp
(
targ
))
literal_flag
=
1
;
/* Fall through. */
case
TARGET_EXPR
:
mark_addressable
(
targ
);
break
;
case
COMPOUND_EXPR
:
{
tree
real_reference
=
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
1
),
flags
,
checkconst
);
rval
=
build
(
COMPOUND_EXPR
,
type
,
TREE_OPERAND
(
targ
,
0
),
real_reference
);
TREE_CONSTANT
(
rval
)
=
staticp
(
TREE_OPERAND
(
targ
,
1
));
return
rval
;
}
case
PREINCREMENT_EXPR
:
case
PREDECREMENT_EXPR
:
case
MODIFY_EXPR
:
case
INIT_EXPR
:
{
tree
real_reference
=
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
0
),
flags
,
checkconst
);
rval
=
build
(
COMPOUND_EXPR
,
type
,
arg
,
real_reference
);
TREE_CONSTANT
(
rval
)
=
staticp
(
TREE_OPERAND
(
targ
,
0
));
return
rval
;
}
case
COND_EXPR
:
return
build
(
COND_EXPR
,
type
,
TREE_OPERAND
(
targ
,
0
),
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
1
),
flags
,
checkconst
),
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
2
),
flags
,
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
),
flags
,
checkconst
),
build_up_reference
(
type
,
TREE_OPERAND
(
targ
,
1
),
flags
,
checkconst
));
case
BIND_EXPR
:
arg
=
TREE_OPERAND
(
targ
,
1
);
if
(
arg
==
NULL_TREE
)
{
compiler_error
(
"({ ... }) expression not expanded when needed for reference"
);
return
error_mark_node
;
}
rval
=
build1
(
ADDR_EXPR
,
type
,
arg
);
TREE_REFERENCE_EXPR
(
rval
)
=
1
;
return
rval
;
default
:
break
;
}
if
((
flags
&
DIRECT_BIND
)
&&
!
real_lvalue_p
(
targ
))
if
((
flags
&
DIRECT_BIND
)
&&
!
real_lvalue_p
(
arg
))
{
tree
targ
=
arg
;
if
(
toplevel_bindings_p
())
{
arg
=
get_temp_name
(
argtype
,
1
);
literal_flag
=
1
;
}
arg
=
get_temp_name
(
argtype
,
1
);
else
{
arg
=
pushdecl
(
build_decl
(
VAR_DECL
,
NULL_TREE
,
argtype
));
...
...
@@ -605,7 +397,7 @@ build_up_reference (type, arg, flags, checkconst)
DECL_INITIAL
(
arg
)
=
targ
;
cp_finish_decl
(
arg
,
targ
,
NULL_TREE
,
0
,
LOOKUP_ONLYCONVERTING
);
}
else
if
(
TREE_ADDRESSABLE
(
targ
)
==
0
&&
!
(
flags
&
DIRECT_BIND
))
else
if
(
!
(
flags
&
DIRECT_BIND
)
&&
!
lvalue_p
(
arg
))
{
tree
slot
=
build_decl
(
VAR_DECL
,
NULL_TREE
,
argtype
);
arg
=
build
(
TARGET_EXPR
,
argtype
,
slot
,
arg
,
NULL_TREE
,
NULL_TREE
);
...
...
@@ -614,25 +406,14 @@ build_up_reference (type, arg, flags, checkconst)
/* If we had a way to wrap this up, and say, if we ever needed it's
address, transform all occurrences of the register, into a memory
reference we could win better. */
mark_addressable
(
arg
);
rval
=
build1
(
ADDR_EXPR
,
type
,
arg
);
done
:
if
(
TYPE_USES_COMPLEX_INHERITANCE
(
argtype
)
||
TYPE_USES_COMPLEX_INHERITANCE
(
target_type
))
{
TREE_TYPE
(
rval
)
=
build_pointer_type
(
argtype
);
if
(
flags
&
LOOKUP_PROTECT
)
rval
=
convert_pointer_to
(
target_type
,
rval
);
else
rval
=
convert_to_pointer_force
(
build_pointer_type
(
target_type
),
rval
);
TREE_TYPE
(
rval
)
=
type
;
if
(
TREE_CODE
(
rval
)
==
PLUS_EXPR
||
TREE_CODE
(
rval
)
==
MINUS_EXPR
)
TREE_TYPE
(
TREE_OPERAND
(
rval
,
0
))
=
TREE_TYPE
(
TREE_OPERAND
(
rval
,
1
))
=
type
;
}
TREE_CONSTANT
(
rval
)
=
literal_flag
;
rval
=
build_unary_op
(
ADDR_EXPR
,
arg
,
1
);
if
(
flags
&
LOOKUP_PROTECT
)
rval
=
convert_pointer_to
(
target_type
,
rval
);
else
rval
=
convert_to_pointer_force
(
build_pointer_type
(
target_type
),
rval
);
rval
=
build1
(
CONVERT_EXPR
,
type
,
rval
);
TREE_CONSTANT
(
rval
)
=
TREE_CONSTANT
(
TREE_OPERAND
(
rval
,
0
));
return
rval
;
}
...
...
gcc/cp/decl.c
View file @
eb66be0e
...
...
@@ -49,8 +49,6 @@ extern struct obstack permanent_obstack;
extern
int
current_class_depth
;
extern
tree
cleanups_this_call
;
extern
tree
static_ctors
,
static_dtors
;
/* Stack of places to restore the search obstack back to. */
...
...
@@ -5012,6 +5010,18 @@ init_decl_processing ()
BUILT_IN_NEXT_ARG
,
NULL_PTR
);
builtin_function
(
"__builtin_args_info"
,
int_ftype_int
,
BUILT_IN_ARGS_INFO
,
NULL_PTR
);
builtin_function
(
"__builtin_setjmp"
,
build_function_type
(
integer_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
endlink
)),
BUILT_IN_SETJMP
,
NULL_PTR
);
builtin_function
(
"__builtin_longjmp"
,
build_function_type
(
integer_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
tree_cons
(
NULL_TREE
,
integer_type_node
,
endlink
))),
BUILT_IN_LONGJMP
,
NULL_PTR
);
/* Untyped call and return. */
builtin_function
(
"__builtin_apply_args"
,
ptr_ftype
,
...
...
@@ -6569,11 +6579,6 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
}
else
if
(
!
toplev
)
{
extern
int
temp_slot_level
;
extern
int
target_temp_slot_level
;
tree
old_cleanups
=
cleanups_this_call
;
int
old_temp_level
=
target_temp_slot_level
;
/* This is a declared decl which must live until the
end of the binding contour. It may need a cleanup. */
...
...
@@ -6654,9 +6659,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
}
}
push_temp_slots
();
push_temp_slots
();
target_temp_slot_level
=
temp_slot_level
;
expand_start_target_temps
();
if
(
DECL_SIZE
(
decl
)
&&
type
!=
error_mark_node
)
{
...
...
@@ -6679,11 +6682,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
&&
DECL_NAME
(
decl
))
TREE_USED
(
decl
)
=
0
;
}
/* Cleanup any temporaries needed for the initial value. */
expand_cleanups_to
(
old_cleanups
);
pop_temp_slots
();
pop_temp_slots
();
target_temp_slot_level
=
old_temp_level
;
expand_end_target_temps
();
if
(
DECL_SIZE
(
decl
)
&&
type
!=
error_mark_node
)
{
...
...
@@ -6777,11 +6778,6 @@ expand_static_init (decl, init)
/* Emit code to perform this initialization but once. */
tree
temp
;
extern
int
temp_slot_level
;
extern
int
target_temp_slot_level
;
tree
old_cleanups
;
int
old_temp_level
;
/* Remember this information until end of file. */
push_obstacks
(
&
permanent_obstack
,
&
permanent_obstack
);
...
...
@@ -6790,11 +6786,7 @@ expand_static_init (decl, init)
rest_of_decl_compilation
(
temp
,
NULL_PTR
,
0
,
0
);
expand_start_cond
(
build_binary_op
(
EQ_EXPR
,
temp
,
integer_zero_node
,
1
),
0
);
old_cleanups
=
cleanups_this_call
;
old_temp_level
=
target_temp_slot_level
;
push_temp_slots
();
push_temp_slots
();
target_temp_slot_level
=
temp_slot_level
;
expand_start_target_temps
();
expand_assignment
(
temp
,
integer_one_node
,
0
,
0
);
if
(
TYPE_NEEDS_CONSTRUCTING
(
TREE_TYPE
(
decl
))
...
...
@@ -6807,10 +6799,7 @@ expand_static_init (decl, init)
expand_assignment
(
decl
,
init
,
0
,
0
);
/* Cleanup any temporaries needed for the initial value. */
expand_cleanups_to
(
old_cleanups
);
pop_temp_slots
();
pop_temp_slots
();
target_temp_slot_level
=
old_temp_level
;
expand_end_target_temps
();
if
(
TYPE_NEEDS_DESTRUCTOR
(
TREE_TYPE
(
decl
)))
{
...
...
@@ -9195,9 +9184,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
/* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */
publicp
=
(
!
friendp
||
RIDBIT_SETP
(
RID_EXTERN
,
specbits
)
||
!
(
funcdef_flag
<
0
||
inlinep
));
publicp
=
(
!
friendp
||
!
staticp
);
decl
=
grokfndecl
(
ctype
,
type
,
declarator
,
virtualp
,
flags
,
quals
,
raises
,
attrlist
,
friendp
?
-
1
:
0
,
publicp
,
inlinep
,
...
...
@@ -9395,11 +9382,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type
=
build_cplus_method_type
(
build_type_variant
(
ctype
,
constp
,
volatilep
),
TREE_TYPE
(
type
),
TYPE_ARG_TYPES
(
type
));
/* Record presence of `static'.
In C++, `inline' implies `static'.
*/
/* Record presence of `static'. */
publicp
=
(
ctype
!=
NULL_TREE
||
RIDBIT_SETP
(
RID_EXTERN
,
specbits
)
||
(
!
RIDBIT_SETP
(
RID_STATIC
,
specbits
)
&&
!
RIDBIT_SETP
(
RID_INLINE
,
specbits
)));
||
!
RIDBIT_SETP
(
RID_STATIC
,
specbits
));
decl
=
grokfndecl
(
ctype
,
type
,
original_name
,
virtualp
,
flags
,
quals
,
raises
,
attrlist
,
...
...
@@ -11281,6 +11267,7 @@ store_parm_decls ()
register
tree
fndecl
=
current_function_decl
;
register
tree
parm
;
int
parms_have_cleanups
=
0
;
tree
cleanups
=
NULL_TREE
;
/* This is either a chain of PARM_DECLs (when a prototype is used). */
tree
specparms
=
current_function_parms
;
...
...
@@ -11355,10 +11342,10 @@ store_parm_decls ()
&&
(
cleanup
=
maybe_build_cleanup
(
parm
),
cleanup
))
{
expand_decl
(
parm
);
if
(
!
expand_decl_cleanup
(
parm
,
cleanup
))
cp_error
(
"parser lost in parsing declaration of `%D'"
,
parm
);
parms_have_cleanups
=
1
;
/* Keep track of the cleanups. */
cleanups
=
tree_cons
(
parm
,
cleanup
,
cleanups
);
}
}
else
...
...
@@ -11392,6 +11379,20 @@ store_parm_decls ()
if
(
!
processing_template_decl
)
expand_function_start
(
fndecl
,
parms_have_cleanups
);
/* Now that we have initialized the parms, we can start their
cleanups. We cannot do this before, since expand_decl_cleanup
should not be called before the parm can be used. */
if
(
parms_have_cleanups
&&
!
processing_template_decl
)
{
for
(
cleanups
=
nreverse
(
cleanups
);
cleanups
;
cleanups
=
TREE_CHAIN
(
cleanups
))
{
if
(
!
expand_decl_cleanup
(
TREE_PURPOSE
(
cleanups
),
TREE_VALUE
(
cleanups
)))
cp_error
(
"parser lost in parsing declaration of `%D'"
,
TREE_PURPOSE
(
cleanups
));
}
}
/* Create a binding contour which can be used to catch
cleanup-generated temporaries. Also, if the return value needs or
has initialization, deal with that now. */
...
...
@@ -12329,9 +12330,6 @@ maybe_build_cleanup_1 (decl, auto_delete)
rval
=
build_compound_expr
(
tree_cons
(
NULL_TREE
,
rval
,
build_tree_list
(
NULL_TREE
,
build_vbase_delete
(
type
,
decl
))));
/* Since this is a cleanup, UNSAVE it now. */
rval
=
unsave_expr
(
rval
);
if
(
TREE_CODE
(
decl
)
!=
PARM_DECL
)
resume_momentary
(
temp
);
...
...
@@ -12372,20 +12370,15 @@ void
cplus_expand_expr_stmt
(
exp
)
tree
exp
;
{
extern
int
temp_slot_level
;
extern
int
target_temp_slot_level
;
tree
old_cleanups
=
cleanups_this_call
;
int
old_temp_level
=
target_temp_slot_level
;
push_temp_slots
();
push_temp_slots
();
target_temp_slot_level
=
temp_slot_level
;
if
(
processing_template_decl
)
{
add_tree
(
build_min_nt
(
EXPR_STMT
,
exp
));
return
;
}
/* Arrange for all temps to disappear. */
expand_start_target_temps
();
if
(
TREE_TYPE
(
exp
)
==
unknown_type_node
)
{
if
(
TREE_CODE
(
exp
)
==
ADDR_EXPR
||
TREE_CODE
(
exp
)
==
TREE_LIST
)
...
...
@@ -12415,16 +12408,7 @@ cplus_expand_expr_stmt (exp)
/* Clean up any pending cleanups. This happens when a function call
returns a cleanup-needing value that nobody uses. */
expand_cleanups_to
(
old_cleanups
);
pop_temp_slots
();
pop_temp_slots
();
target_temp_slot_level
=
old_temp_level
;
/* There might something left from building the trees. */
if
(
cleanups_this_call
)
{
expand_cleanups_to
(
NULL_TREE
);
}
free_temp_slots
();
expand_end_target_temps
();
}
/* When a stmt has been parsed, this function is called.
...
...
gcc/cp/decl2.c
View file @
eb66be0e
...
...
@@ -38,7 +38,6 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
extern
tree
get_file_function_name
();
extern
tree
cleanups_this_call
;
static
void
grok_function_init
PROTO
((
tree
,
tree
));
void
import_export_decl
();
extern
int
current_class_depth
;
...
...
@@ -420,7 +419,6 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{
"huge-objects"
,
&
flag_huge_objects
,
1
},
{
"conserve-space"
,
&
flag_conserve_space
,
1
},
{
"vtable-thunks"
,
&
flag_vtable_thunks
,
1
},
{
"short-temps"
,
&
flag_short_temps
,
1
},
{
"access-control"
,
&
flag_access_control
,
1
},
{
"nonansi-builtins"
,
&
flag_no_nonansi_builtin
,
0
},
{
"gnu-keywords"
,
&
flag_no_gnu_keywords
,
0
},
...
...
@@ -2919,15 +2917,8 @@ finish_file ()
while
(
vars
)
{
extern
int
temp_slot_level
;
extern
int
target_temp_slot_level
;
tree
decl
=
TREE_VALUE
(
vars
);
tree
init
=
TREE_PURPOSE
(
vars
);
tree
old_cleanups
=
cleanups_this_call
;
int
old_temp_level
=
target_temp_slot_level
;
push_temp_slots
();
push_temp_slots
();
target_temp_slot_level
=
temp_slot_level
;
/* If this was a static attribute within some function's scope,
then don't initialize it here. Also, don't bother
...
...
@@ -2940,9 +2931,9 @@ finish_file ()
if
(
TREE_CODE
(
decl
)
==
VAR_DECL
)
{
int
protect
=
(
TREE_PUBLIC
(
decl
)
&&
(
DECL_COMMON
(
decl
)
||
DECL_ONE_ONLY
(
decl
)
||
DECL_WEAK
(
decl
)));
int
protect
=
(
TREE_PUBLIC
(
decl
)
&&
(
DECL_COMMON
(
decl
)
||
DECL_ONE_ONLY
(
decl
)
||
DECL_WEAK
(
decl
)));
/* Set these global variables so that GDB at least puts
us near the declaration which required the initialization. */
...
...
@@ -2964,6 +2955,8 @@ finish_file ()
expand_start_cond
(
sentry
,
0
);
}
expand_start_target_temps
();
if
(
IS_AGGR_TYPE
(
TREE_TYPE
(
decl
))
||
TREE_CODE
(
TREE_TYPE
(
decl
))
==
ARRAY_TYPE
)
expand_aggr_init
(
decl
,
init
,
0
,
0
);
...
...
@@ -2977,6 +2970,9 @@ finish_file ()
else
expand_assignment
(
decl
,
init
,
0
,
0
);
/* Cleanup any temporaries needed for the initial value. */
expand_end_target_temps
();
if
(
protect
)
expand_end_cond
();
...
...
@@ -2987,13 +2983,7 @@ finish_file ()
;
else
my_friendly_abort
(
22
);
/* Cleanup any temporaries needed for the initial value. */
expand_cleanups_to
(
old_cleanups
);
next_mess
:
pop_temp_slots
();
pop_temp_slots
();
target_temp_slot_level
=
old_temp_level
;
vars
=
TREE_CHAIN
(
vars
);
}
...
...
gcc/cp/except.c
View file @
eb66be0e
...
...
@@ -35,12 +35,12 @@ Boston, MA 02111-1307, USA. */
rtx
expand_builtin_return_addr
PROTO
((
enum
built_in_function
,
int
,
rtx
));
/*
holds the fndecl for __builtin_return_address ()
*/
/*
Holds the fndecl for __builtin_return_address.
*/
tree
builtin_return_address_fndecl
;
/* A couple of backend routines from m88k.c */
/*
used to cache a call to __builtin_return_address ()
*/
/*
Used to cache a call to __builtin_return_address.
*/
static
tree
BuiltinReturnAddress
;
...
...
@@ -163,18 +163,17 @@ extern rtx gen_nop PROTO(());
/* local globals for function calls
====================================================================== */
/*
used to cache "terminate ()", "unexpected ()", "set_terminate ()
", and
"set_unexpected
()
" after default_conversion. (lib-except.c) */
/*
Used to cache "terminate", "unexpected", "set_terminate
", and
"set_unexpected" after default_conversion. (lib-except.c) */
static
tree
Terminate
,
Unexpected
,
SetTerminate
,
SetUnexpected
,
CatchMatch
;
/* used to cache __find_first_exception_table_match ()
for throw (lib-except.c) */
/* Used to cache __find_first_exception_table_match for throw. */
static
tree
FirstExceptionMatch
;
/*
used to cache a call to __unwind_function () (lib-except.c)
*/
/*
Used to cache a call to __unwind_function.
*/
static
tree
Unwind
;
/*
holds a ready to emit call to "terminate ()
". */
/*
Holds a ready to emit call to "terminate
". */
static
tree
TerminateFunctionCall
;
static
tree
empty_fndecl
;
...
...
@@ -245,8 +244,8 @@ init_exception_processing ()
tree
PFV
=
build_pointer_type
(
build_function_type
(
void_type_node
,
void_list_node
));
/*
arg list for the build_function_type call for set_terminate ()
and
set_unexpected
()
*/
/*
Arg list for the build_function_type call for set_terminate
and
set_unexpected
.
*/
tree
pfvlist
=
tree_cons
(
NULL_TREE
,
PFV
,
void_list_node
);
/* void (*pfvtype (void (*) ()))() */
...
...
@@ -343,6 +342,10 @@ init_exception_processing ()
DECL_COMMON
(
d
)
=
1
;
cp_finish_decl
(
d
,
NULL_TREE
,
NULL_TREE
,
1
,
0
);
saved_in_catch
=
lookup_name
(
get_identifier
(
"__eh_in_catch"
),
0
);
/* If we use setjmp/longjmp EH, arrange for all cleanup actions to
be protected with __terminate. */
protect_cleanup_actions_with_terminate
=
1
;
}
/* Build a type value for use at runtime for a type that is matched
...
...
@@ -448,6 +451,8 @@ expand_start_catch_block (declspecs, declarator)
false_label_rtx
=
gen_label_rtx
();
push_label_entry
(
&
false_label_stack
,
false_label_rtx
,
NULL_TREE
);
emit_line_note
(
input_filename
,
lineno
);
if
(
declspecs
)
{
tree
exp
;
...
...
@@ -460,8 +465,11 @@ expand_start_catch_block (declspecs, declarator)
{
error
(
"invalid catch parameter"
);
/* This is cheap, but we want to maintain the data structures. */
/* This is cheap, but we want to maintain the data
structures. */
expand_eh_region_start
();
return
;
}
...
...
@@ -513,11 +521,17 @@ expand_start_catch_block (declspecs, declarator)
emit_move_insn
(
DECL_RTL
(
saved_in_catch
),
const1_rtx
);
/* Because we are reordered out of line, we arrange
to rethrow in the outer context, should we encounter
an exception in the catch handler.
/* If we are not doing setjmp/longjmp EH, because we are reordered
out of line, we arrange to rethrow in the outer context so as to
skip through the terminate region we are nested in, should we
encounter an exception in the catch handler.
Matches the end in expand_end_catch_block (). */
If we are doing setjmp/longjmp EH, we need to skip through the EH
object cleanup region. This isn't quite right, as we really need
to clean the object up, but we cannot do that until we track
multiple EH objects.
Matches the end in expand_end_catch_block. */
expand_eh_region_start
();
emit_line_note
(
input_filename
,
lineno
);
...
...
@@ -539,23 +553,42 @@ expand_end_catch_block ()
if
(
!
doing_eh
(
1
))
return
;
/* Fall to outside the try statement when done executing handler and
we fall off end of handler. This is jump Lresume in the
documentation. */
expand_goto
(
top_label_entry
(
&
caught_return_label_stack
));
t
=
make_node
(
RTL_EXPR
);
TREE_TYPE
(
t
)
=
void_type_node
;
RTL_EXPR_RTL
(
t
)
=
const0_rtx
;
TREE_SIDE_EFFECTS
(
t
)
=
1
;
start_sequence_for_rtl_expr
(
t
);
expand_internal_throw
(
DECL_RTL
(
top_label_entry
(
&
caught_return_label_stack
)));
if
(
exceptions_via_longjmp
)
{
/* If we are doing setjmp/longjmp EH, we need to skip through
the EH object cleanup region. This isn't quite right, as we
really need to clean the object up, but we cannot do that
until we track multiple EH objects. */
emit_library_call
(
sjpopnthrow_libfunc
,
0
,
VOIDmode
,
0
);
emit_barrier
();
}
else
{
/* If we are not doing setjmp/longjmp EH, we need an extra
region around the whole catch block to skip through the
terminate region we are nested in. */
expand_internal_throw
(
DECL_RTL
(
top_label_entry
(
&
caught_return_label_stack
)));
}
RTL_EXPR_SEQUENCE
(
t
)
=
get_insns
();
end_sequence
();
/* Matches the start in expand_start_catch_block
()
. */
/* Matches the start in expand_start_catch_block. */
expand_eh_region_end
(
t
);
/* Fall to outside the try statement when done executing handler and
we fall off end of handler. This is jump Lresume in the
documentation. */
expand_goto
(
top_label_entry
(
&
caught_return_label_stack
));
expand_leftover_cleanups
();
/* Cleanup the EH parameter. */
...
...
@@ -580,7 +613,7 @@ do_unwind (inner_throw_label)
rtx
return_val_rtx
;
rtx
temp
;
/*
call to __builtin_return_address ()
*/
/*
Call to __builtin_return_address.
*/
params
=
tree_cons
(
NULL_TREE
,
integer_zero_node
,
NULL_TREE
);
fcall
=
build_function_call
(
BuiltinReturnAddress
,
params
);
return_val_rtx
=
expand_expr
(
fcall
,
NULL_RTX
,
Pmode
,
0
);
...
...
@@ -633,7 +666,7 @@ do_unwind (inner_throw_label)
#if 0
/* I would like to do this here, but the move below doesn't seem to work. */
/*
call to __builtin_return_address ()
*/
/*
Call to __builtin_return_address.
*/
params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
fcall = build_function_call (BuiltinReturnAddress, params);
return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0);
...
...
@@ -651,7 +684,7 @@ do_unwind (inner_throw_label)
}
/*
is called from expand_exception_blocks ()
to generate the code in a function
/*
Is called from expand_exception_blocks
to generate the code in a function
to "throw" if anything in the function needs to perform a throw.
expands "throw" as the following pseudo code:
...
...
@@ -731,7 +764,7 @@ expand_builtin_throw ()
/* code to deal with unwinding and looking for it again */
emit_label
(
gotta_rethrow_it
);
/*
call to __builtin_return_address ()
*/
/*
Call to __builtin_return_address.
*/
#if defined (ARM_FRAME_RTX)
/* was __arm */
/* This should be moved into arm.h:RETURN_ADDR_RTX */
/* This replaces a 'call' to __builtin_return_address */
...
...
@@ -743,7 +776,7 @@ expand_builtin_throw ()
return_val_rtx
=
expand_expr
(
fcall
,
NULL_RTX
,
Pmode
,
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
,
GET_MODE
(
return_val_rtx
),
0
,
0
);
...
...
@@ -837,6 +870,7 @@ expand_end_eh_spec (raises)
do_function_call
(
Unexpected
,
NULL_TREE
,
NULL_TREE
);
assemble_external
(
TREE_OPERAND
(
Unexpected
,
0
));
emit_barrier
();
expand_eh_region_end
(
second_try
);
emit_label
(
check
);
...
...
@@ -890,7 +924,6 @@ expand_exception_blocks ()
funcend
=
gen_label_rtx
();
emit_jump
(
funcend
);
/* expand_null_return (); */
start_sequence
();
...
...
@@ -931,12 +964,22 @@ expand_exception_blocks ()
if
(
insns
)
{
/* Is this necessary? */
assemble_external
(
TREE_OPERAND
(
Terminate
,
0
));
/* We cannot protect n regions this way if we must flow into the
EH region through the top of the region, as we have to with
the setjmp/longjmp approach. */
if
(
exceptions_via_longjmp
==
0
)
{
/* Is this necessary? */
assemble_external
(
TREE_OPERAND
(
Terminate
,
0
));
expand_eh_region_start
();
}
expand_eh_region_start
();
emit_insns
(
insns
);
expand_eh_region_end
(
TerminateFunctionCall
);
if
(
exceptions_via_longjmp
==
0
)
expand_eh_region_end
(
TerminateFunctionCall
);
expand_leftover_cleanups
();
}
...
...
@@ -1125,13 +1168,18 @@ expand_throw (exp)
/* This part is easy, as we don't have to do anything else. */
}
/* This is the label that represents where in the code we were, when
we got an exception. This needs to be updated when we rethrow an
exception, so that the matching routine knows to search out. */
label
=
gen_label_rtx
();
emit_label
(
label
);
if
(
exceptions_via_longjmp
)
emit_throw
();
else
{
/* This is the label that represents where in the code we were, when
we got an exception. This needs to be updated when we rethrow an
exception, so that the matching routine knows to search out. */
label
=
gen_label_rtx
();
emit_label
(
label
);
expand_internal_throw
(
label
);
expand_internal_throw
(
label
);
}
}
/* Build a throw expression. */
...
...
gcc/cp/exception.cc
View file @
eb66be0e
...
...
@@ -30,22 +30,23 @@
#include "typeinfo"
#include "exception"
/* terminate (), unexpected (), set_terminate (), set_unexpected () as
well as the default terminate func and default unexpected func */
/* Define terminate, unexpected, set_terminate, set_unexpected as
well as the default terminate func and default unexpected func. */
extern
terminate_handler
__terminate_func
;
void
__default_
terminate
()
terminate
()
{
abort
();
__terminate_func
();
}
void
__default_unexpected
()
{
__default_
terminate
();
terminate
();
}
static
terminate_handler
__terminate_func
=
__default_terminate
;
static
unexpected_handler
__unexpected_func
=
__default_unexpected
;
terminate_handler
...
...
@@ -67,12 +68,6 @@ set_unexpected (unexpected_handler func)
}
void
terminate
()
{
__terminate_func
();
}
void
unexpected
()
{
__unexpected_func
();
...
...
gcc/cp/init.c
View file @
eb66be0e
...
...
@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */
#include "cp-tree.h"
#include "flags.h"
#include "output.h"
#include "except.h"
/* In C++, structures with well-defined constructors are initialized by
those constructors, unasked. CURRENT_BASE_INIT_LIST
...
...
@@ -39,8 +40,6 @@ Boston, MA 02111-1307, USA. */
line. Perhaps this was not intended. */
tree
current_base_init_list
,
current_member_init_list
;
extern
tree
cleanups_this_call
;
void
emit_base_init
();
void
check_base_init
();
static
void
expand_aggr_vbase_init
();
...
...
@@ -153,13 +152,8 @@ perform_member_init (member, name, init, explicit)
{
tree
decl
;
tree
type
=
TREE_TYPE
(
member
);
extern
int
temp_slot_level
;
extern
int
target_temp_slot_level
;
tree
old_cleanups
=
cleanups_this_call
;
int
old_temp_level
=
target_temp_slot_level
;
push_temp_slots
();
push_temp_slots
();
target_temp_slot_level
=
temp_slot_level
;
expand_start_target_temps
();
if
(
TYPE_NEEDS_CONSTRUCTING
(
type
)
||
(
init
&&
TYPE_HAS_CONSTRUCTOR
(
type
)))
...
...
@@ -219,15 +213,8 @@ perform_member_init (member, name, init, explicit)
expand_expr_stmt
(
build_modify_expr
(
decl
,
INIT_EXPR
,
init
));
}
}
expand_cleanups_to
(
old_cleanups
);
pop_temp_slots
();
pop_temp_slots
();
target_temp_slot_level
=
old_temp_level
;
/* There might something left from building the trees. */
if
(
cleanups_this_call
)
{
expand_cleanups_to
(
NULL_TREE
);
}
expand_end_target_temps
();
free_temp_slots
();
if
(
TYPE_NEEDS_DESTRUCTOR
(
type
))
...
...
@@ -589,27 +576,14 @@ emit_base_init (t, immediately)
if
(
init
!=
void_list_node
)
{
extern
int
temp_slot_level
;
extern
int
target_temp_slot_level
;
tree
old_cleanups
=
cleanups_this_call
;
int
old_temp_level
=
target_temp_slot_level
;
push_temp_slots
();
push_temp_slots
();
target_temp_slot_level
=
temp_slot_level
;
expand_start_target_temps
();
member
=
convert_pointer_to_real
(
base_binfo
,
current_class_ptr
);
expand_aggr_init_1
(
base_binfo
,
NULL_TREE
,
build_indirect_ref
(
member
,
NULL_PTR
),
init
,
BINFO_OFFSET_ZEROP
(
base_binfo
),
LOOKUP_NORMAL
);
expand_cleanups_to
(
old_cleanups
);
pop_temp_slots
();
pop_temp_slots
();
target_temp_slot_level
=
old_temp_level
;
/* There might something left from building the trees. */
if
(
cleanups_this_call
)
{
expand_cleanups_to
(
NULL_TREE
);
}
expand_end_target_temps
();
free_temp_slots
();
}
...
...
@@ -796,28 +770,14 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
tree
init
=
purpose_member
(
binfo
,
init_list
);
tree
ref
=
build_indirect_ref
(
addr
,
NULL_PTR
);
extern
int
temp_slot_level
;
extern
int
target_temp_slot_level
;
tree
old_cleanups
=
cleanups_this_call
;
int
old_temp_level
=
target_temp_slot_level
;
push_temp_slots
();
push_temp_slots
();
target_temp_slot_level
=
temp_slot_level
;
expand_start_target_temps
();
if
(
init
)
init
=
TREE_VALUE
(
init
);
/* Call constructors, but don't set up vtables. */
expand_aggr_init_1
(
binfo
,
exp
,
ref
,
init
,
0
,
LOOKUP_COMPLAIN
);
expand_cleanups_to
(
old_cleanups
);
pop_temp_slots
();
pop_temp_slots
();
target_temp_slot_level
=
old_temp_level
;
/* There might something left from building the trees. */
if
(
cleanups_this_call
)
{
expand_cleanups_to
(
NULL_TREE
);
}
expand_end_target_temps
();
free_temp_slots
();
}
...
...
@@ -3109,20 +3069,22 @@ expand_vec_init (decl, base, maxindex, init, from_array)
push_obstacks_nochange
();
resume_temporary_allocation
();
{
tree
e1
,
e2
=
make_node
(
RTL_EXPR
);
TREE_TYPE
(
e2
)
=
void_type_node
;
RTL_EXPR_RTL
(
e2
)
=
const0_rtx
;
TREE_SIDE_EFFECTS
(
e2
)
=
1
;
start_sequence_for_rtl_expr
(
e2
);
tree
e1
,
cleanup
=
make_node
(
RTL_EXPR
);
TREE_TYPE
(
cleanup
)
=
void_type_node
;
RTL_EXPR_RTL
(
cleanup
)
=
const0_rtx
;
TREE_SIDE_EFFECTS
(
cleanup
)
=
1
;
start_sequence_for_rtl_expr
(
cleanup
);
e1
=
build_array_eh_cleanup
(
rval
,
build_binary_op
(
MINUS_EXPR
,
maxindex
,
iterator
,
1
),
type
);
expand_expr
(
e1
,
const0_rtx
,
VOIDmode
,
0
);
RTL_EXPR_SEQUENCE
(
e2
)
=
get_insns
();
RTL_EXPR_SEQUENCE
(
cleanup
)
=
get_insns
();
end_sequence
();
expand_eh_region_end
(
e2
);
cleanup
=
protect_with_terminate
(
cleanup
);
expand_eh_region_end
(
cleanup
);
}
pop_obstacks
();
}
...
...
gcc/cp/lang-options.h
View file @
eb66be0e
...
...
@@ -70,8 +70,6 @@ Boston, MA 02111-1307, USA. */
"-fno-repo"
,
"-fsave-memoized"
,
"-fno-save-memoized"
,
"-fshort-temps"
,
"-fno-short-temps"
,
"-fstats"
,
"-fno-stats"
,
"-fstrict-prototype"
,
...
...
gcc/cp/method.c
View file @
eb66be0e
...
...
@@ -1698,7 +1698,7 @@ make_thunk (function, delta)
}
if
(
thunk
==
NULL_TREE
)
{
thunk
=
build_decl
(
FUNCTION_DECL
,
thunk_id
,
TREE_TYPE
(
func_decl
));
thunk
=
build_
lang_
decl
(
FUNCTION_DECL
,
thunk_id
,
TREE_TYPE
(
func_decl
));
DECL_RESULT
(
thunk
)
=
build_decl
(
RESULT_DECL
,
0
,
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
vtable_entry_type
)));
TREE_READONLY
(
thunk
)
=
TYPE_READONLY
(
TREE_TYPE
(
vtable_entry_type
));
...
...
@@ -1719,27 +1719,9 @@ void
emit_thunk
(
thunk_fndecl
)
tree
thunk_fndecl
;
{
rtx
insns
;
char
buffer
[
250
];
tree
argp
;
struct
args_size
stack_args_size
;
tree
function
=
TREE_OPERAND
(
DECL_INITIAL
(
thunk_fndecl
),
0
);
int
delta
=
THUNK_DELTA
(
thunk_fndecl
);
char
*
fnname
=
XSTR
(
XEXP
(
DECL_RTL
(
thunk_fndecl
),
0
),
0
);
int
tem
;
int
failure
=
0
;
int
save_ofp
;
/* Used to remember which regs we need to emit a USE rtx for. */
rtx
need_use
[
FIRST_PSEUDO_REGISTER
];
int
need_use_count
=
0
;
/* rtx for the 'this' parameter. */
rtx
this_rtx
=
0
,
this_reg_rtx
=
0
,
fixed_this_rtx
;
char
*
(
*
save_decl_printable_name
)
()
=
decl_printable_name
;
/* Data on reg parms scanned so far. */
CUMULATIVE_ARGS
args_so_far
;
if
(
TREE_ASM_WRITTEN
(
thunk_fndecl
))
return
;
...
...
@@ -1749,203 +1731,58 @@ emit_thunk (thunk_fndecl)
TREE_ADDRESSABLE
(
function
)
=
1
;
mark_used
(
function
);
decl_printable_name
=
thunk_printable_name
;
if
(
current_function_decl
)
abort
();
current_function_decl
=
thunk_fndecl
;
TREE_SET_CODE
(
thunk_fndecl
,
FUNCTION_DECL
);
#ifdef ASM_OUTPUT_MI_THUNK
current_function_decl
=
thunk_fndecl
;
temporary_allocation
();
assemble_start_function
(
thunk_fndecl
,
fnname
);
ASM_OUTPUT_MI_THUNK
(
asm_out_file
,
thunk_fndecl
,
delta
,
function
);
assemble_end_function
(
thunk_fndecl
,
fnname
);
permanent_allocation
(
1
);
#else
save_ofp
=
flag_omit_frame_pointer
;
flag_omit_frame_pointer
=
1
;
init_function_start
(
thunk_fndecl
,
input_filename
,
lineno
);
pushlevel
(
0
);
expand_start_bindings
(
1
);
temporary_allocation
();
/* Start updating where the next arg would go. */
INIT_CUMULATIVE_ARGS
(
args_so_far
,
TREE_TYPE
(
function
),
NULL_RTX
,
0
);
stack_args_size
.
constant
=
0
;
stack_args_size
.
var
=
0
;
/* SETUP for possible structure return address FIXME */
/* Now look through all the parameters, make sure that we
don't clobber any registers used for parameters.
Also, pick up an rtx for the first "this" parameter. */
for
(
argp
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
function
));
argp
!=
NULL_TREE
;
argp
=
TREE_CHAIN
(
argp
))
{
tree
passed_type
=
TREE_VALUE
(
argp
);
register
rtx
entry_parm
;
int
named
=
1
;
/* FIXME */
struct
args_size
stack_offset
;
struct
args_size
arg_size
;
if
(
passed_type
==
void_type_node
)
break
;
if
((
TREE_CODE
(
TYPE_SIZE
(
passed_type
))
!=
INTEGER_CST
&&
contains_placeholder_p
(
TYPE_SIZE
(
passed_type
)))
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
||
FUNCTION_ARG_PASS_BY_REFERENCE
(
args_so_far
,
TYPE_MODE
(
passed_type
),
passed_type
,
named
)
#endif
)
passed_type
=
build_pointer_type
(
passed_type
);
entry_parm
=
FUNCTION_ARG
(
args_so_far
,
TYPE_MODE
(
passed_type
),
passed_type
,
named
);
if
(
entry_parm
!=
0
)
need_use
[
need_use_count
++
]
=
entry_parm
;
locate_and_pad_parm
(
TYPE_MODE
(
passed_type
),
passed_type
,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
1
,
#else
entry_parm
!=
0
,
#endif
thunk_fndecl
,
&
stack_args_size
,
&
stack_offset
,
&
arg_size
);
/* REGNO (entry_parm);*/
if
(
this_rtx
==
0
)
{
this_reg_rtx
=
entry_parm
;
if
(
!
entry_parm
)
{
rtx
offset_rtx
=
ARGS_SIZE_RTX
(
stack_offset
);
rtx
internal_arg_pointer
,
stack_parm
;
if
((
ARG_POINTER_REGNUM
==
STACK_POINTER_REGNUM
||
!
(
fixed_regs
[
ARG_POINTER_REGNUM
]
||
ARG_POINTER_REGNUM
==
FRAME_POINTER_REGNUM
)))
internal_arg_pointer
=
copy_to_reg
(
virtual_incoming_args_rtx
);
else
internal_arg_pointer
=
virtual_incoming_args_rtx
;
if
(
offset_rtx
==
const0_rtx
)
entry_parm
=
gen_rtx
(
MEM
,
TYPE_MODE
(
passed_type
),
internal_arg_pointer
);
else
entry_parm
=
gen_rtx
(
MEM
,
TYPE_MODE
(
passed_type
),
gen_rtx
(
PLUS
,
Pmode
,
internal_arg_pointer
,
offset_rtx
));
}
this_rtx
=
entry_parm
;
}
FUNCTION_ARG_ADVANCE
(
args_so_far
,
TYPE_MODE
(
passed_type
),
passed_type
,
named
);
}
fixed_this_rtx
=
plus_constant
(
this_rtx
,
delta
);
if
(
this_rtx
!=
fixed_this_rtx
)
emit_move_insn
(
this_rtx
,
fixed_this_rtx
);
if
(
this_reg_rtx
)
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
this_reg_rtx
));
emit_indirect_jump
(
XEXP
(
DECL_RTL
(
function
),
0
));
while
(
need_use_count
>
0
)
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
need_use
[
--
need_use_count
]));
expand_end_bindings
(
NULL
,
1
,
0
);
poplevel
(
0
,
0
,
1
);
/* From now on, allocate rtl in current_obstack, not in saveable_obstack.
Note that that may have been done above, in save_for_inline_copying.
The call to resume_temporary_allocation near the end of this function
goes back to the usual state of affairs. */
rtl_in_current_obstack
();
insns
=
get_insns
();
/* Copy any shared structure that should not be shared. */
unshare_all_rtl
(
insns
);
/* Instantiate all virtual registers. */
instantiate_virtual_regs
(
current_function_decl
,
get_insns
());
/* We are no longer anticipating cse in this function, at least. */
cse_not_expected
=
1
;
/* Now we choose between stupid (pcc-like) register allocation
(if we got the -noreg switch and not -opt)
and smart register allocation. */
if
(
optimize
>
0
)
/* Stupid allocation probably won't work */
obey_regdecls
=
0
;
/* if optimizations being done. */
regclass_init
();
regclass
(
insns
,
max_reg_num
());
if
(
obey_regdecls
)
{
stupid_life_analysis
(
insns
,
max_reg_num
(),
NULL
);
failure
=
reload
(
insns
,
0
,
NULL
);
}
else
{
/* Do control and data flow analysis,
and write some of the results to dump file. */
flow_analysis
(
insns
,
max_reg_num
(),
NULL
);
local_alloc
();
failure
=
global_alloc
(
NULL
);
}
reload_completed
=
1
;
#ifdef LEAF_REGISTERS
leaf_function
=
0
;
if
(
optimize
>
0
&&
only_leaf_regs_used
()
&&
leaf_function_p
())
leaf_function
=
1
;
#endif
/* If a machine dependent reorganization is needed, call it. */
#ifdef MACHINE_DEPENDENT_REORG
MACHINE_DEPENDENT_REORG
(
insns
);
#endif
/* Now turn the rtl into assembler code. */
assemble_start_function
(
thunk_fndecl
,
fnname
);
final
(
insns
,
asm_out_file
,
optimize
,
0
);
assemble_end_function
(
thunk_fndecl
,
fnname
);
reload_completed
=
0
;
/* Cancel the effect of rtl_in_current_obstack. */
current_function_decl
=
0
;
#else
/* ASM_OUTPUT_MI_THUNK */
if
(
varargs_function_p
(
function
))
cp_error
(
"generic thunk code does not work for variadic function `%#D'"
,
function
);
{
tree
a
,
t
;
permanent_allocation
(
1
);
flag_omit_frame_pointer
=
save_ofp
;
/* Set up clone argument trees for the thunk. */
t
=
NULL_TREE
;
for
(
a
=
DECL_ARGUMENTS
(
function
);
a
;
a
=
TREE_CHAIN
(
a
))
{
tree
x
=
copy_node
(
a
);
TREE_CHAIN
(
x
)
=
t
;
DECL_CONTEXT
(
x
)
=
thunk_fndecl
;
t
=
x
;
}
a
=
nreverse
(
t
);
DECL_ARGUMENTS
(
thunk_fndecl
)
=
a
;
DECL_RESULT
(
thunk_fndecl
)
=
NULL_TREE
;
start_function
(
NULL_TREE
,
thunk_fndecl
,
NULL_TREE
,
1
);
store_parm_decls
();
/* Build up the call to the real function. */
t
=
build_int_2
(
delta
,
-
1
*
(
delta
<
0
));
TREE_TYPE
(
t
)
=
signed_type
(
sizetype
);
t
=
fold
(
build
(
PLUS_EXPR
,
TREE_TYPE
(
a
),
a
,
t
));
t
=
tree_cons
(
NULL_TREE
,
t
,
NULL_TREE
);
for
(
a
=
TREE_CHAIN
(
a
);
a
;
a
=
TREE_CHAIN
(
a
))
t
=
tree_cons
(
NULL_TREE
,
a
,
t
);
t
=
nreverse
(
t
);
t
=
build_call
(
function
,
TREE_TYPE
(
TREE_TYPE
(
function
)),
t
);
c_expand_return
(
t
);
finish_function
(
lineno
,
0
,
0
);
}
#endif
/* ASM_OUTPUT_MI_THUNK */
TREE_SET_CODE
(
thunk_fndecl
,
THUNK_DECL
);
decl_printable_name
=
save_decl_printable_name
;
current_function_decl
=
0
;
TREE_SET_CODE
(
thunk_fndecl
,
THUNK_DECL
);
}
/* Code for synthesizing methods which have default semantics defined. */
...
...
gcc/cp/pt.c
View file @
eb66be0e
...
...
@@ -132,6 +132,9 @@ process_template_parm (list, next)
error
(
" a template type parameter must begin with `class' or `typename'"
);
TREE_TYPE
(
parm
)
=
void_type_node
;
}
else
if
(
pedantic
&&
TREE_CODE
(
TREE_TYPE
(
parm
))
==
REAL_TYPE
)
cp_pedwarn
(
"`%T' is not a valid type for a template constant parameter"
,
TREE_TYPE
(
parm
));
tinfo
=
make_node
(
TEMPLATE_CONST_PARM
);
my_friendly_assert
(
TREE_PERMANENT
(
tinfo
),
260
.
5
);
if
(
TREE_PERMANENT
(
parm
)
==
0
)
...
...
gcc/cp/spew.c
View file @
eb66be0e
...
...
@@ -299,11 +299,9 @@ yylex ()
case
SELFNAME
:
lastiddecl
=
identifier_typedecl_value
(
tmp_token
.
yylval
.
ttype
);
if
(
lastiddecl
!=
trrr
)
{
lastiddecl
=
trrr
;
if
(
got_scope
)
tmp_token
.
yylval
.
ttype
=
trrr
;
}
lastiddecl
=
trrr
;
if
(
got_scope
)
tmp_token
.
yylval
.
ttype
=
trrr
;
break
;
case
IDENTIFIER
:
lastiddecl
=
trrr
;
...
...
gcc/cp/tinfo2.cc
View file @
eb66be0e
...
...
@@ -43,7 +43,7 @@ fast_compare (const char *n1, const char *n2) {
};
bool
type_info
::
before
(
const
type_info
&
arg
)
type_info
::
before
(
const
type_info
&
arg
)
const
{
return
fast_compare
(
name
(),
arg
.
name
())
<
0
;
}
...
...
gcc/cp/tree.c
View file @
eb66be0e
...
...
@@ -108,6 +108,8 @@ real_lvalue_p (ref)
return
0
;
}
/* This differs from real_lvalue_p in that class rvalues are considered
lvalues. */
int
lvalue_p
(
ref
)
tree
ref
;
...
...
@@ -2102,3 +2104,16 @@ error_type (arg)
return
type
;
}
/* Does FUNCTION use a variable-length argument list? */
int
varargs_function_p
(
function
)
tree
function
;
{
tree
parm
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
function
));
for
(;
parm
;
parm
=
TREE_CHAIN
(
parm
))
if
(
TREE_VALUE
(
parm
)
==
void_type_node
)
return
0
;
return
1
;
}
gcc/cp/typeck.c
View file @
eb66be0e
...
...
@@ -1507,7 +1507,7 @@ decay_conversion (exp)
inner
=
build1
(
CONVERT_EXPR
,
build_pointer_type
(
TREE_TYPE
(
TREE_TYPE
(
inner
))),
inner
);
TREE_
REFERENCE_EXPR
(
inner
)
=
1
;
TREE_
CONSTANT
(
inner
)
=
TREE_CONSTANT
(
TREE_OPERAND
(
inner
,
0
))
;
}
return
convert
(
build_pointer_type
(
TREE_TYPE
(
type
)),
inner
);
}
...
...
@@ -4261,8 +4261,10 @@ build_unary_op (code, xarg, noconvert)
argtype
=
TREE_TYPE
(
arg
);
if
(
TREE_CODE
(
argtype
)
==
REFERENCE_TYPE
)
{
arg
=
build1
(
CONVERT_EXPR
,
build_pointer_type
(
TREE_TYPE
(
TREE_TYPE
(
arg
))),
arg
);
TREE_REFERENCE_EXPR
(
arg
)
=
1
;
arg
=
build1
(
CONVERT_EXPR
,
build_pointer_type
(
TREE_TYPE
(
TREE_TYPE
(
arg
))),
arg
);
TREE_CONSTANT
(
arg
)
=
TREE_CONSTANT
(
TREE_OPERAND
(
arg
,
0
));
return
arg
;
}
else
if
(
pedantic
...
...
@@ -4283,16 +4285,12 @@ build_unary_op (code, xarg, noconvert)
if
(
arg
==
current_class_ref
)
return
current_class_ptr
;
/* Keep `default_conversion' from converting if
ARG is of REFERENCE_TYPE. */
arg
=
TREE_OPERAND
(
arg
,
0
);
if
(
TREE_CODE
(
TREE_TYPE
(
arg
))
==
REFERENCE_TYPE
)
{
if
(
TREE_CODE
(
arg
)
==
VAR_DECL
&&
DECL_INITIAL
(
arg
)
&&
!
TREE_SIDE_EFFECTS
(
DECL_INITIAL
(
arg
)))
arg
=
DECL_INITIAL
(
arg
);
arg
=
build1
(
CONVERT_EXPR
,
build_pointer_type
(
TREE_TYPE
(
TREE_TYPE
(
arg
))),
arg
);
TREE_REFERENCE_EXPR
(
arg
)
=
1
;
arg
=
build1
(
CONVERT_EXPR
,
build_pointer_type
(
TREE_TYPE
(
TREE_TYPE
(
arg
))),
arg
);
TREE_CONSTANT
(
arg
)
=
TREE_CONSTANT
(
TREE_OPERAND
(
arg
,
0
));
}
else
if
(
lvalue_p
(
arg
))
...
...
@@ -7148,6 +7146,8 @@ c_expand_return (retval)
if
(
TREE_CODE
(
whats_returned
)
==
ADDR_EXPR
)
whats_returned
=
TREE_OPERAND
(
whats_returned
,
0
);
}
if
(
TREE_CODE
(
whats_returned
)
==
CONVERT_EXPR
)
whats_returned
=
TREE_OPERAND
(
whats_returned
,
0
);
if
(
TREE_CODE
(
whats_returned
)
==
ADDR_EXPR
)
{
whats_returned
=
TREE_OPERAND
(
whats_returned
,
0
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment