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
4ac14744
Commit
4ac14744
authored
May 16, 1996
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
86th Cygnus<->FSF quick merge
From-SVN: r11974
parent
62cb0901
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
535 additions
and
412 deletions
+535
-412
gcc/cp/ChangeLog
+76
-0
gcc/cp/call.c
+92
-46
gcc/cp/class.c
+5
-9
gcc/cp/cp-tree.h
+6
-6
gcc/cp/cvt.c
+171
-9
gcc/cp/decl.c
+29
-28
gcc/cp/decl2.c
+9
-4
gcc/cp/error.c
+3
-2
gcc/cp/init.c
+32
-32
gcc/cp/method.c
+11
-144
gcc/cp/parse.y
+20
-25
gcc/cp/pt.c
+4
-0
gcc/cp/search.c
+1
-1
gcc/cp/sig.c
+9
-8
gcc/cp/tree.c
+2
-2
gcc/cp/typeck.c
+64
-95
gcc/cp/typeck2.c
+1
-1
No files found.
gcc/cp/ChangeLog
View file @
4ac14744
...
...
@@ -3,6 +3,82 @@ Sat May 11 04:33:50 1996 Doug Evans <dje@canuck.cygnus.com>
* decl2.c (finish_vtable_vardecl): Surround DECL_ONE_ONLY with ifdef.
(finish_file): Likewise.
Wed May 15 14:46:14 1996 Mike Stump <mrs@cygnus.com>
* call.c (build_method_call): Allow implicit & on METHOD_TYPEs,
but pedwarn as the code is bogus.
* typeck.c (decay_conversion): Ditto.
(build_function_call_real): Use build_addr_func instead of
default_conversion. Don't allow pointer-to-method functions down
here.
(build_unary_op): Use real pointer-to-member functions instead of
fake ones.
(build_ptrmemfunc): Use build_addr_func instead of build_unary_op.
(convert_for_assignment): Removed some obsolete code.
* decl2.c (reparse_absdcl_as_expr): Pass current_class_ref to
build_x_function_call instead of current_class_ptr. Only call
digest_init once on an initializer, we do this just checking
TREE_TYPE.
(build_expr_from_tree): Pass current_class_ref to
build_x_function_call instead of current_class_ptr.
* init.c (build_member_call): Ditto.
* pase.y: Ditto.
* error.c (dump_expr): Handle OFFSET_REFs better.
* pt.c (unify): Handle pointer-to-member functions better.
* decl.c (finish_function): Clear out current_class_ref just like
we do for current_class_ptr.
* typeck.c (get_delta_difference): Handle virtual bases better.
Tue May 14 16:37:37 1996 Jason Merrill <jason@yorick.cygnus.com>
* sig.c (build_signature_table_constructor): Use the delta for
the original basetype for this virtual function with thunks.
(build_signature_method_call): We still need to adjust 'this'
with thunks.
Tue May 14 16:27:25 1996 Mike Stump <mrs@cygnus.com>
* call.c (build_addr_func): New routine. Used to get the `real'
address of a function or a method. Needed to avoid getting a
pointer-to-member function.
(build_call): New routine to build CALL_EXPRs.
(build_method_call): Use it.
* cvt.c (convert_to_aggr): Ditto.
* typeck.c (build_function_call_real): Ditto.
* sig.c (build_signature_table_constructor): Use build_addr_func.
* cp-tree.h (build_call, build_addr_func): Declare them.
Tue May 14 12:47:47 1996 Mike Stump <mrs@cygnus.com>
* cp-tree.h (LOOKUP_AGGR): Remove, unused.
* parse.y: Remove uses of LOOKUP_AGGR.
Tue May 14 12:07:51 1996 Mike Stump <mrs@cygnus.com>
* *.[chy]: Rename current_class_decl to current_class_ptr, and
C_C_D to current_class_ref.
Mon May 13 16:55:23 1996 Jason Merrill <jason@yorick.cygnus.com>
* call.c (convert_harshness): Tighten up pointer conversions.
Sat May 11 04:33:50 1996 Doug Evans <dje@canuck.cygnus.com>
* decl2.c (finish_vtable_vardecl): Surround DECL_ONE_ONLY with ifdef.
(finish_file): Likewise.
Fri May 10 11:09:57 1996 Jason Merrill <jason@yorick.cygnus.com>
* cvt.c (convert_fn_ptr): We don't use thunks for pmfs.
* method.c (emit_thunk): Set flag_omit_frame_pointer in default
code.
Thu May 9 18:18:30 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c: Turn on thunks by default where supported.
Tue May 7 20:39:57 1996 Mike Stump <mrs@cygnus.com>
* cp-tree.h (build_overload_call_maybe): Removed.
...
...
gcc/cp/call.c
View file @
4ac14744
...
...
@@ -506,12 +506,6 @@ convert_harshness (type, parmtype, parm)
if
(
TREE_CODE
(
ttl
)
!=
VOID_TYPE
&&
(
TREE_CODE
(
ttr
)
!=
VOID_TYPE
||
!
parm
||
!
integer_zerop
(
parm
)))
{
if
(
TREE_UNSIGNED
(
ttl
)
!=
TREE_UNSIGNED
(
ttr
))
{
ttl
=
unsigned_type
(
ttl
);
ttr
=
unsigned_type
(
ttr
);
penalty
=
10
;
}
if
(
comp_target_types
(
type
,
parmtype
,
1
)
<=
0
)
return
EVIL_RETURN
(
h
);
}
...
...
@@ -526,22 +520,18 @@ convert_harshness (type, parmtype, parm)
return
EVIL_RETURN
(
h
);
#endif
if
(
penalty
==
10
||
ttr
==
ttl
)
if
(
ttr
==
ttl
)
{
tree
tmp1
=
TREE_TYPE
(
type
),
tmp2
=
TREE_TYPE
(
parmtype
);
/* If one was unsigned but the other wasn't, then we need to
do a standard conversion from T to unsigned T. */
if
(
penalty
==
10
)
h
.
code
=
PROMO_CODE
;
/* was STD_CODE */
else
h
.
code
=
0
;
h
.
code
=
0
;
/* Note conversion from `T*' to `const T*',
or `T*' to `volatile T*'. */
if
(
ttl
==
ttr
&&
((
TYPE_READONLY
(
tmp1
)
!=
TREE_READONLY
(
tmp2
))
||
(
TYPE_VOLATILE
(
tmp1
)
!=
TYPE_VOLATILE
(
tmp2
))))
if
((
TYPE_READONLY
(
tmp1
)
<
TREE_READONLY
(
tmp2
))
||
(
TYPE_VOLATILE
(
tmp1
)
<
TYPE_VOLATILE
(
tmp2
)))
h
.
code
=
EVIL_CODE
;
else
if
((
TYPE_READONLY
(
tmp1
)
!=
TREE_READONLY
(
tmp2
))
||
(
TYPE_VOLATILE
(
tmp1
)
!=
TYPE_VOLATILE
(
tmp2
)))
h
.
code
|=
QUAL_CODE
;
h
.
distance
=
0
;
...
...
@@ -580,8 +570,11 @@ convert_harshness (type, parmtype, parm)
if
(
ttl
!=
ttr
)
{
tree
tmp1
=
TREE_TYPE
(
type
),
tmp2
=
TREE_TYPE
(
parmtype
);
if
((
TYPE_READONLY
(
tmp1
)
!=
TREE_READONLY
(
tmp2
))
||
(
TYPE_VOLATILE
(
tmp1
)
!=
TYPE_VOLATILE
(
tmp2
)))
if
((
TYPE_READONLY
(
tmp1
)
<
TREE_READONLY
(
tmp2
))
||
(
TYPE_VOLATILE
(
tmp1
)
<
TYPE_VOLATILE
(
tmp2
)))
h
.
code
=
EVIL_CODE
;
else
if
((
TYPE_READONLY
(
tmp1
)
>
TREE_READONLY
(
tmp2
))
||
(
TYPE_VOLATILE
(
tmp1
)
>
TYPE_VOLATILE
(
tmp2
)))
h
.
code
|=
QUAL_CODE
;
}
return
h
;
...
...
@@ -1192,7 +1185,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
{
tree
field
,
instance
;
if
(
instance_ptr
==
current_class_
decl
)
if
(
instance_ptr
==
current_class_
ptr
)
{
/* Check to see if we really have a reference to an instance variable
with `operator()()' overloaded. */
...
...
@@ -1208,7 +1201,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
{
/* If it's a field, try overloading operator (),
or calling if the field is a pointer-to-function. */
instance
=
build_component_ref_1
(
C_C_D
,
field
,
0
);
instance
=
build_component_ref_1
(
current_class_ref
,
field
,
0
);
if
(
instance
==
error_mark_node
)
return
error_mark_node
;
...
...
@@ -1221,7 +1214,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
if
(
TREE_CODE
(
TREE_TYPE
(
TREE_TYPE
(
instance
)))
==
FUNCTION_TYPE
)
return
build_function_call
(
instance
,
parms
);
else
if
(
TREE_CODE
(
TREE_TYPE
(
TREE_TYPE
(
instance
)))
==
METHOD_TYPE
)
return
build_function_call
(
instance
,
tree_cons
(
NULL_TREE
,
current_class_
decl
,
parms
));
return
build_function_call
(
instance
,
tree_cons
(
NULL_TREE
,
current_class_
ptr
,
parms
));
}
}
return
NULL_TREE
;
...
...
@@ -1527,6 +1520,71 @@ print_n_candidates (candidates, n)
cp_error_at
(
" %D"
,
candidates
[
i
].
function
);
}
/* We want the address of a function or method. We avoid creating a
pointer-to-member function. */
tree
build_addr_func
(
function
)
tree
function
;
{
tree
type
=
TREE_TYPE
(
function
);
/* We have to do these by hand to avoid real pointer to member
functions. */
if
(
TREE_CODE
(
type
)
==
METHOD_TYPE
)
{
tree
addr
;
type
=
build_pointer_type
(
type
);
if
(
mark_addressable
(
function
)
==
0
)
return
error_mark_node
;
addr
=
build1
(
ADDR_EXPR
,
type
,
function
);
/* Address of a static or external variable or function counts
as a constant */
if
(
staticp
(
function
))
TREE_CONSTANT
(
addr
)
=
1
;
function
=
addr
;
}
else
function
=
default_conversion
(
function
);
return
function
;
}
/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or
POINTER_TYPE to those. Note, pointer to member function types
(TYPE_PTRMEMFUNC_P) must be handled by our callers. */
tree
build_call
(
function
,
result_type
,
parms
)
tree
function
,
result_type
,
parms
;
{
int
is_constructor
=
0
;
function
=
build_addr_func
(
function
);
if
(
TYPE_PTRMEMFUNC_P
(
TREE_TYPE
(
function
)))
{
sorry
(
"unable to call pointer to member function here"
);
return
error_mark_node
;
}
if
(
TREE_CODE
(
function
)
==
ADDR_EXPR
&&
TREE_CODE
(
TREE_OPERAND
(
function
,
0
))
==
FUNCTION_DECL
&&
DECL_CONSTRUCTOR_P
(
TREE_OPERAND
(
function
,
0
)))
is_constructor
=
1
;
function
=
build_nt
(
CALL_EXPR
,
function
,
parms
,
NULL_TREE
);
TREE_HAS_CONSTRUCTOR
(
function
)
=
is_constructor
;
TREE_TYPE
(
function
)
=
result_type
;
TREE_SIDE_EFFECTS
(
function
)
=
1
;
return
function
;
}
/* Build something of the form ptr->method (args)
or object.method (args). This can also build
calls to constructors, and find friends.
...
...
@@ -1739,11 +1797,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
return
error_mark_node
;
}
}
else
if
(
instance
==
C_C_D
||
instance
==
current_class_decl
)
else
if
(
instance
==
current_class_ref
||
instance
==
current_class_ptr
)
{
/* When doing initialization, we side-effect the TREE_TYPE of
C_C_D
, hence we cannot set up BASETYPE from CURRENT_CLASS_TYPE. */
basetype
=
TREE_TYPE
(
C_C_D
);
current_class_ref
, hence we cannot set up BASETYPE from CURRENT_CLASS_TYPE. */
basetype
=
TREE_TYPE
(
current_class_ref
);
/* Anything manifestly `this' in constructors and destructors
has a known type, so virtual function tables are not needed. */
...
...
@@ -1765,8 +1823,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
else
{
instance
=
C_C_D
;
instance_ptr
=
current_class_
decl
;
instance
=
current_class_ref
;
instance_ptr
=
current_class_
ptr
;
basetype_path
=
TYPE_BINFO
(
current_class_type
);
}
result
=
build_field_call
(
basetype_path
,
instance_ptr
,
name
,
parms
);
...
...
@@ -1940,9 +1998,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
TREE_VALUE
(
parm
)
=
resolve_offset_ref
(
TREE_VALUE
(
parm
));
t
=
TREE_TYPE
(
TREE_VALUE
(
parm
));
}
if
(
TREE_CODE
(
TREE_VALUE
(
parm
))
==
OFFSET_REF
&&
TREE_CODE
(
t
)
==
METHOD_TYPE
)
if
(
TREE_CODE
(
t
)
==
METHOD_TYPE
)
{
cp_pedwarn
(
"assuming & on `%E'"
,
TREE_VALUE
(
parm
));
TREE_VALUE
(
parm
)
=
build_unary_op
(
ADDR_EXPR
,
TREE_VALUE
(
parm
),
0
);
}
#if 0
...
...
@@ -2365,7 +2423,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
type (if it exists) is a pointer to. */
if
(
DECL_ABSTRACT_VIRTUAL_P
(
function
)
&&
instance
==
C_C_D
&&
instance
==
current_class_ref
&&
DECL_CONSTRUCTOR_P
(
current_function_decl
)
&&
!
(
flags
&
LOOKUP_NONVIRTUAL
)
&&
value_member
(
function
,
get_abstract_virtuals
(
basetype
)))
...
...
@@ -2422,7 +2480,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
/* Let's be nasty to the user now, and give reasonable
error messages. */
instance_ptr
=
current_class_
decl
;
instance_ptr
=
current_class_
ptr
;
if
(
instance_ptr
)
{
if
(
basetype
!=
current_class_type
)
...
...
@@ -2540,21 +2598,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
GNU_xref_call
(
current_function_decl
,
IDENTIFIER_POINTER
(
DECL_ASSEMBLER_NAME
(
function
)));
{
int
is_constructor
=
TREE_CODE
(
function
)
==
FUNCTION_DECL
&&
DECL_CONSTRUCTOR_P
(
function
);
function
=
default_conversion
(
function
);
result
=
build_nt
(
CALL_EXPR
,
function
,
parms
,
NULL_TREE
);
TREE_TYPE
(
result
)
=
value_type
;
TREE_SIDE_EFFECTS
(
result
)
=
1
;
TREE_HAS_CONSTRUCTOR
(
result
)
=
is_constructor
;
result
=
convert_from_reference
(
result
);
return
result
;
}
result
=
build_call
(
function
,
value_type
,
parms
);
result
=
convert_from_reference
(
result
);
return
result
;
}
/* Similar to `build_method_call', but for overloaded non-member functions.
...
...
gcc/cp/class.c
View file @
4ac14744
...
...
@@ -72,7 +72,9 @@ struct class_level
int
unused
;
};
tree
current_class_decl
,
C_C_D
;
/* PARM_DECL: the class instance variable */
/* The currect_class_ptr is the pointer to the current class.
current_class_ref is the actual current class. */
tree
current_class_ptr
,
current_class_ref
;
/* The following two can be derived from the previous one */
tree
current_class_name
;
/* IDENTIFIER_NODE: name of current class */
...
...
@@ -434,7 +436,7 @@ build_vtbl_ref (instance, idx)
if
(
TREE_CODE
(
basetype
)
==
REFERENCE_TYPE
)
basetype
=
TREE_TYPE
(
basetype
);
if
(
instance
==
C_C_D
)
if
(
instance
==
current_class_ref
)
vtbl
=
build_indirect_ref
(
build_vfield_ref
(
instance
,
basetype
),
NULL_PTR
);
else
...
...
@@ -4494,7 +4496,7 @@ resolves_to_fixed_type_p (instance, nonnull)
}
else
if
(
nonnull
)
{
if
(
instance
==
current_class_
decl
if
(
instance
==
current_class_
ptr
&&
flag_this_is_variable
<=
0
)
{
/* Some people still use `this = 0' inside destructors. */
...
...
@@ -4941,12 +4943,6 @@ instantiate_type (lhstype, rhs, complain)
tree
elem
,
baselink
,
name
;
int
globals
=
overloaded_globals_p
(
rhs
);
#if 0 /* obsolete */
/* If there's only one function we know about, return that. */
if (globals > 0 && TREE_CHAIN (rhs) == NULL_TREE)
return TREE_VALUE (rhs);
#endif
/* First look for an exact match. Search either overloaded
functions or member functions. May have to undo what
`default_conversion' might do to lhstype. */
...
...
gcc/cp/cp-tree.h
View file @
4ac14744
...
...
@@ -1002,7 +1002,7 @@ struct lang_decl
/* Nonzero for FUNCTION_DECL means that this constructor is known to
not make any assignment to `this', and therefore can be trusted
to return it unchanged. Otherwise, we must re-assign `current_class_
decl
'
to return it unchanged. Otherwise, we must re-assign `current_class_
ptr
'
after performing base initializations. */
#define DECL_PRESERVES_THIS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.preserves_first_arg)
...
...
@@ -1551,7 +1551,8 @@ extern tree current_lang_name, lang_name_cplusplus, lang_name_c;
of CURRENT_FUNCTION_DECL due to overloading */
extern
tree
original_function_name
;
extern
tree
current_class_name
,
current_class_type
,
current_class_decl
,
C_C_D
;
extern
tree
current_class_name
,
current_class_type
;
extern
tree
current_class_ptr
,
current_class_ref
;
/* in init.c */
extern
tree
global_base_init_list
;
...
...
@@ -1820,8 +1821,6 @@ extern int at_eof;
enum
overload_flags
{
NO_SPECIAL
=
0
,
DTOR_FLAG
,
OP_FLAG
,
TYPENAME_FLAG
};
extern
tree
current_class_decl
,
C_C_D
;
/* PARM_DECL: the class instance variable */
/* The following two can be derived from the previous one */
extern
tree
current_class_name
;
/* IDENTIFIER_NODE: name of current class */
extern
tree
current_class_type
;
/* _TYPE: the type of the current class */
...
...
@@ -1838,7 +1837,6 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
LOOKUP_COMPLAIN mean complain if no suitable member function
matching the arguments is found.
LOOKUP_NORMAL is just a combination of these two.
LOOKUP_AGGR requires the instance to be of aggregate type.
LOOKUP_NONVIRTUAL means make a direct call to the member function found
LOOKUP_GLOBAL means search through the space of overloaded functions,
as well as the space of member functions.
...
...
@@ -1858,7 +1856,7 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define LOOKUP_PROTECT (1)
#define LOOKUP_COMPLAIN (2)
#define LOOKUP_NORMAL (3)
#define LOOKUP_AGGR (4)
/* #define LOOKUP_UNUSED (4) */
#define LOOKUP_NONVIRTUAL (8)
#define LOOKUP_GLOBAL (16)
#define LOOKUP_HAS_IN_CHARGE (32)
...
...
@@ -1941,6 +1939,8 @@ extern int get_arglist_len_in_bytes PROTO((tree));
extern
tree
build_vfield_ref
PROTO
((
tree
,
tree
));
extern
tree
find_scoped_type
PROTO
((
tree
,
tree
,
tree
));
extern
tree
resolve_scope_to_name
PROTO
((
tree
,
tree
));
extern
tree
build_call
PROTO
((
tree
,
tree
,
tree
));
extern
tree
build_addr_func
PROTO
((
tree
));
extern
tree
build_scoped_method_call
PROTO
((
tree
,
tree
,
tree
,
tree
));
extern
tree
build_method_call
PROTO
((
tree
,
tree
,
tree
,
tree
,
int
));
extern
tree
build_overload_call_real
PROTO
((
tree
,
tree
,
int
,
struct
candidate
*
,
int
));
...
...
gcc/cp/cvt.c
View file @
4ac14744
...
...
@@ -82,6 +82,7 @@ static tree
convert_fn_ptr
(
type
,
expr
)
tree
type
,
expr
;
{
#if 0 /* We don't use thunks for pmfs. */
if (flag_vtable_thunks)
{
tree intype = TREE_TYPE (expr);
...
...
@@ -104,6 +105,7 @@ convert_fn_ptr (type, expr)
return build1 (NOP_EXPR, type, build_thunk (BINFO_OFFSET (binfo), expr));
}
else
#endif
return
build_ptrmemfunc
(
type
,
expr
,
1
);
}
...
...
@@ -477,7 +479,7 @@ build_up_reference (type, arg, flags, checkconst)
case
PARM_DECL
:
#if 0
if (targ == current_class_
decl
)
if (targ == current_class_
ptr
)
{
error ("address of `this' not available");
/* #if 0 */
...
...
@@ -1056,14 +1058,11 @@ convert_to_aggr (type, expr, msgp, protect)
return
NULL_TREE
;
fntype
=
TREE_TYPE
(
function
);
function
=
default_conversion
(
function
);
result
=
build_nt
(
CALL_EXPR
,
function
,
convert_arguments
(
NULL_TREE
,
TYPE_ARG_TYPES
(
fntype
),
parmlist
,
NULL_TREE
,
LOOKUP_NORMAL
),
NULL_TREE
);
TREE_TYPE
(
result
)
=
TREE_TYPE
(
fntype
);
TREE_SIDE_EFFECTS
(
result
)
=
1
;
parmlist
=
convert_arguments
(
NULL_TREE
,
TYPE_ARG_TYPES
(
fntype
),
parmlist
,
NULL_TREE
,
LOOKUP_NORMAL
);
result
=
build_call
(
function
,
TREE_TYPE
(
fntype
),
parmlist
);
return
result
;
}
...
...
@@ -1809,3 +1808,166 @@ type_promotes_to (type)
return
cp_build_type_variant
(
type
,
constp
,
volatilep
);
}
#if 0
/* Work in progress. Ask jason before removing. */
int
null_ptr_cst (t)
tree t;
{
return (INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t));
}
tree
standard_conversion (to, from, expr)
tree to, from, expr;
{
enum tree_code fcode = TREE_CODE (from);
enum tree_code tcode = TREE_CODE (to);
tree conv;
if (from == to)
return from;
conv = from;
if (fcode == FUNCTION_TYPE)
{
from = build_pointer_type (from);
fcode = TREE_CODE (from);
conv = build1 (LVALUE_CONV, from, conv);
}
else if (fcode == ARRAY_TYPE)
{
from = build_pointer_type (TREE_TYPE (from));
fcode = TREE_CODE (from);
conv = build1 (LVALUE_CONV, from, conv);
}
if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to))
&& expr && null_ptr_cst (expr))
{
conv = build1 (CONV_CONV, to, conv);
}
else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
{
enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
enum tree_code utcode = TREE_CODE (TREE_TYPE (to));
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))),
TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))), 1))
/* OK for now */;
else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE
&& ufcode != FUNCTION_TYPE)
{
from = cp_build_type_variant (void_type_node,
TYPE_READONLY (TREE_TYPE (from)),
TYPE_VOLATILE (TREE_TYPE (from)));
conv = build1 (CONV_CONV, from, conv);
}
else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)
{
tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));
if (DERIVED_FROM_P (tbase, fbase)
&& (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))),
TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))),
1)))
{
from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from)));
conv = build1 (CONV_CONV, from, conv);
}
else
return 0;
}
else if (IS_AGGR_TYPE (TREE_TYPE (from))
&& IS_AGGR_TYPE (TREE_TYPE (to)))
{
if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
{
from = cp_build_type_variant (TREE_TYPE (to),
TYPE_READONLY (TREE_TYPE (from)),
TYPE_VOLATILE (TREE_TYPE (from)));
conv = build1 (CONV_CONV, from, conv);
}
else
return 0;
}
else
return 0;
if (! comptypes (from, to, 1) && comp_ptr_ttypes (to, from))
{
from = to;
conv = build1 (QUAL_CONV, from, conv);
}
}
else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))
{
tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from));
tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
if (! DERIVED_FROM_P (tbase, fbase)
|| ! comptypes (TREE_TYPE (fromfn), TREE_TYPE (tofn), 1)
|| ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
TREE_CHAIN (TYPE_ARG_TYPES (tofn)), 1)
|| TYPE_READONLY (fbase) != TYPE_READONLY (tbase)
|| TYPE_VOLATILE (fbase) != TYPE_VOLATILE (tbase))
return 0;
from = cp_build_type_variant (tbase, TYPE_READONLY (fbase),
TYPE_VOLATILE (fbase));
from = build_cplus_method_type (from, TREE_TYPE (fromfn),
TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
conv = build1 (CONV_CONV, from, conv);
}
else if (tcode == BOOLEAN_TYPE)
{
if (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE
|| fcode == POINTER_TYPE)
return build1 (CONV_CONV, to, conv);
else
return 0;
}
else if (INTEGRAL_CODE_P (tcode) || tcode == REAL_TYPE)
{
if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE))
return 0;
else if (to == type_promotes_to (from))
conv = build1 (PROMO_CONV, to, conv);
else
conv = build1 (CONV_CONV, to, conv);
}
else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
&& DERIVED_FROM_P (to, from))
{
conv = build1 (CONV_CONV, to, conv);
}
else
return 0;
return conv;
}
tree
implicit_conversion (to, from, expr, flags)
tree to, from, expr;
int flags;
{
tree conv = standard_conversion (to, from, expr);
if (conv || (flags & LOOKUP_NO_CONVERSION))
return conv;
flags |= LOOKUP_NO_CONVERSION;
/* try constructors */;
/* try conversion ops */;
return conv;
}
#endif
gcc/cp/decl.c
View file @
4ac14744
...
...
@@ -3275,7 +3275,7 @@ pushdecl (x)
if
(
oldlocal
!=
NULL_TREE
&&
TREE_CODE
(
oldlocal
)
==
PARM_DECL
)
warnstring
=
"declaration of `%s' shadows a parameter"
;
else
if
(
IDENTIFIER_CLASS_VALUE
(
name
)
!=
NULL_TREE
&&
current_class_
decl
&&
current_class_
ptr
&&
!
TREE_STATIC
(
name
))
warnstring
=
"declaration of `%s' shadows a member of `this'"
;
else
if
(
oldlocal
!=
NULL_TREE
)
...
...
@@ -11075,14 +11075,14 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
push_nested_class
(
ctype
,
1
);
/* If we're compiling a friend function, neither of the variables
current_class_
decl
nor current_class_type will have values. */
current_class_
ptr
nor current_class_type will have values. */
if
(
!
doing_friend
)
{
/* We know that this was set up by `grokclassfn'.
We do not wait until `store_parm_decls', since evil
parse errors may never get us to that point. Here
we keep the consistency between `current_class_type'
and `current_class_
decl
'. */
and `current_class_
ptr
'. */
tree
t
=
current_function_parms
;
my_friendly_assert
(
t
!=
NULL_TREE
...
...
@@ -11093,14 +11093,14 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
int
i
=
suspend_momentary
();
/* Fool build_indirect_ref. */
current_class_
decl
=
NULL_TREE
;
C_C_D
=
build_indirect_ref
(
t
,
NULL_PTR
);
current_class_
decl
=
t
;
current_class_
ptr
=
NULL_TREE
;
current_class_ref
=
build_indirect_ref
(
t
,
NULL_PTR
);
current_class_
ptr
=
t
;
resume_momentary
(
i
);
}
else
/* We're having a signature pointer here. */
C_C_D
=
current_class_decl
=
t
;
current_class_ref
=
current_class_ptr
=
t
;
}
}
...
...
@@ -11110,7 +11110,7 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
push_nested_class
(
DECL_CONTEXT
(
decl1
),
2
);
else
push_memoized_context
(
0
,
1
);
current_class_
decl
=
C_C_D
=
NULL_TREE
;
current_class_
ptr
=
current_class_ref
=
NULL_TREE
;
}
pushlevel
(
0
);
...
...
@@ -11502,7 +11502,7 @@ finish_function (lineno, call_poplevel, nested)
if
(
current_function_assigns_this
)
cond
=
build
(
NE_EXPR
,
boolean_type_node
,
current_class_
decl
,
integer_zero_node
);
current_class_
ptr
,
integer_zero_node
);
else
{
int
n_baseclasses
=
CLASSTYPE_N_BASECLASSES
(
current_class_type
);
...
...
@@ -11541,10 +11541,10 @@ finish_function (lineno, call_poplevel, nested)
/* These are two cases where we cannot delegate deletion. */
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
current_class_type
)
||
TYPE_GETS_REG_DELETE
(
current_class_type
))
exprstmt
=
build_delete
(
current_class_type
,
C_C_D
,
integer_zero_node
,
exprstmt
=
build_delete
(
current_class_type
,
current_class_ref
,
integer_zero_node
,
LOOKUP_NONVIRTUAL
|
LOOKUP_DESTRUCTOR
,
0
);
else
exprstmt
=
build_delete
(
current_class_type
,
C_C_D
,
in_charge_node
,
exprstmt
=
build_delete
(
current_class_type
,
current_class_ref
,
in_charge_node
,
LOOKUP_NONVIRTUAL
|
LOOKUP_DESTRUCTOR
,
0
);
/* If we did not assign to this, then `this' is non-zero at
...
...
@@ -11576,7 +11576,7 @@ finish_function (lineno, call_poplevel, nested)
{
if
(
TYPE_NEEDS_DESTRUCTOR
(
BINFO_TYPE
(
vbases
)))
{
tree
ptr
=
convert_pointer_to_vbase
(
BINFO_TYPE
(
vbases
),
current_class_
decl
);
tree
ptr
=
convert_pointer_to_vbase
(
BINFO_TYPE
(
vbases
),
current_class_
ptr
);
expand_expr_stmt
(
build_delete
(
build_pointer_type
(
BINFO_TYPE
(
vbases
)),
ptr
,
integer_zero_node
,
LOOKUP_NONVIRTUAL
|
LOOKUP_DESTRUCTOR
|
LOOKUP_HAS_IN_CHARGE
,
0
));
...
...
@@ -11605,11 +11605,11 @@ finish_function (lineno, call_poplevel, nested)
error_mark_node
),
NULL_PTR
),
ansi_opname
[(
int
)
DELETE_EXPR
],
tree_cons
(
NULL_TREE
,
current_class_
decl
,
tree_cons
(
NULL_TREE
,
current_class_
ptr
,
build_tree_list
(
NULL_TREE
,
virtual_size
)),
NULL_TREE
,
LOOKUP_NORMAL
);
else
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
current_class_type
))
exprstmt
=
build_x_delete
(
ptr_type_node
,
current_class_
decl
,
0
,
exprstmt
=
build_x_delete
(
ptr_type_node
,
current_class_
ptr
,
0
,
virtual_size
);
else
exprstmt
=
NULL_TREE
;
...
...
@@ -11646,16 +11646,16 @@ finish_function (lineno, call_poplevel, nested)
/* Make all virtual function table pointers in non-virtual base
classes point to CURRENT_CLASS_TYPE's virtual function
tables. */
expand_direct_vtbls_init
(
binfo
,
binfo
,
1
,
0
,
current_class_
decl
);
expand_direct_vtbls_init
(
binfo
,
binfo
,
1
,
0
,
current_class_
ptr
);
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
current_class_type
))
expand_indirect_vtbls_init
(
binfo
,
C_C_D
,
current_class_decl
);
expand_indirect_vtbls_init
(
binfo
,
current_class_ref
,
current_class_ptr
);
}
if
(
!
ok_to_optimize_dtor
)
{
cond
=
build_binary_op
(
NE_EXPR
,
current_class_
decl
,
integer_zero_node
,
1
);
current_class_
ptr
,
integer_zero_node
,
1
);
expand_start_cond
(
cond
,
0
);
}
...
...
@@ -11691,7 +11691,7 @@ finish_function (lineno, call_poplevel, nested)
expand_end_bindings
(
decls
,
decls
!=
NULL_TREE
,
0
);
poplevel
(
decls
!=
NULL_TREE
,
0
,
0
);
}
c_expand_return
(
current_class_
decl
);
c_expand_return
(
current_class_
ptr
);
}
else
if
(
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
DECL_RESULT
(
current_function_decl
)))
!=
void_type_node
...
...
@@ -11715,8 +11715,8 @@ finish_function (lineno, call_poplevel, nested)
if
(
flag_this_is_variable
>
0
)
{
cond
=
build_binary_op
(
EQ_EXPR
,
current_class_
decl
,
integer_zero_node
,
1
);
thenclause
=
build_modify_expr
(
current_class_
decl
,
NOP_EXPR
,
current_class_
ptr
,
integer_zero_node
,
1
);
thenclause
=
build_modify_expr
(
current_class_
ptr
,
NOP_EXPR
,
build_new
(
NULL_TREE
,
current_class_type
,
void_type_node
,
0
));
}
...
...
@@ -11769,7 +11769,7 @@ finish_function (lineno, call_poplevel, nested)
poplevel
(
decls
!=
NULL_TREE
,
1
,
0
);
}
c_expand_return
(
current_class_
decl
);
c_expand_return
(
current_class_
ptr
);
current_function_assigns_this
=
0
;
current_function_just_assigned_this
=
0
;
...
...
@@ -11974,7 +11974,8 @@ finish_function (lineno, call_poplevel, nested)
}
named_label_uses
=
NULL_TREE
;
current_class_decl
=
NULL_TREE
;
current_class_ptr
=
NULL_TREE
;
current_class_ref
=
NULL_TREE
;
}
/* Create the FUNCTION_DECL for a function definition.
...
...
@@ -12412,8 +12413,8 @@ struct cp_function
tree
base_init_list
;
tree
member_init_list
;
tree
base_init_expr
;
tree
c
lass_decl
;
tree
C_C_D
;
tree
c
urrent_class_ptr
;
tree
current_class_ref
;
rtx
result_rtx
;
struct
cp_function
*
next
;
struct
binding_level
*
binding_level
;
...
...
@@ -12459,8 +12460,8 @@ push_cp_function_context (context)
p
->
temp_name_counter
=
temp_name_counter
;
p
->
base_init_list
=
current_base_init_list
;
p
->
member_init_list
=
current_member_init_list
;
p
->
c
lass_decl
=
current_class_decl
;
p
->
C_C_D
=
C_C_D
;
p
->
c
urrent_class_ptr
=
current_class_ptr
;
p
->
current_class_ref
=
current_class_ref
;
p
->
eh_context
=
push_eh_context
();
}
...
...
@@ -12502,8 +12503,8 @@ pop_cp_function_context (context)
temp_name_counter
=
p
->
temp_name_counter
;
current_base_init_list
=
p
->
base_init_list
;
current_member_init_list
=
p
->
member_init_list
;
current_class_
decl
=
p
->
class_decl
;
C_C_D
=
p
->
C_C_D
;
current_class_
ptr
=
p
->
current_class_ptr
;
current_class_ref
=
p
->
current_class_ref
;
pop_eh_context
(
p
->
eh_context
);
...
...
gcc/cp/decl2.c
View file @
4ac14744
...
...
@@ -155,9 +155,13 @@ int warn_implicit = 1;
int
warn_ctor_dtor_privacy
=
1
;
/* True if we want to implement vtables using "thunks".
The default is off
now, but will be on later
. */
The default is off
by default, on if explicitly supported
. */
#ifdef ASM_OUTPUT_MI_THUNK
int
flag_vtable_thunks
=
1
;
#else
int
flag_vtable_thunks
;
#endif
/* True if we want to deal with repository information. */
...
...
@@ -3336,7 +3340,7 @@ reparse_absdcl_as_expr (type, decl)
/* recurse */
decl
=
reparse_decl_as_expr
(
type
,
TREE_OPERAND
(
decl
,
0
));
decl
=
build_x_function_call
(
decl
,
NULL_TREE
,
current_class_
decl
);
decl
=
build_x_function_call
(
decl
,
NULL_TREE
,
current_class_
ref
);
if
(
TREE_CODE
(
decl
)
==
CALL_EXPR
&&
TREE_TYPE
(
decl
)
!=
void_type_node
)
decl
=
require_complete_type
(
decl
);
...
...
@@ -3357,7 +3361,8 @@ reparse_absdcl_as_casts (decl, expr)
{
tree
type
;
if
(
TREE_CODE
(
expr
)
==
CONSTRUCTOR
)
if
(
TREE_CODE
(
expr
)
==
CONSTRUCTOR
&&
TREE_TYPE
(
expr
)
==
0
)
{
type
=
groktypename
(
TREE_VALUE
(
TREE_OPERAND
(
decl
,
1
)));
decl
=
TREE_OPERAND
(
decl
,
0
);
...
...
@@ -3556,7 +3561,7 @@ build_expr_from_tree (t)
name
=
build_expr_from_tree
(
name
);
return
build_x_function_call
(
name
,
build_expr_from_tree
(
TREE_OPERAND
(
t
,
1
)),
current_class_
decl
);
current_class_
ref
);
}
case
COND_EXPR
:
...
...
gcc/cp/error.c
View file @
4ac14744
...
...
@@ -1259,8 +1259,9 @@ dump_expr (t, nop)
dump_expr
(
TREE_OPERAND
(
t
,
1
),
0
);
else
{
sorry
(
"operand of OFFSET_REF not understood"
);
goto
error
;
dump_expr
(
TREE_OPERAND
(
t
,
0
),
0
);
OB_PUTS
(
" .* "
);
dump_expr
(
TREE_OPERAND
(
t
,
1
),
0
);
}
break
;
}
...
...
gcc/cp/init.c
View file @
4ac14744
...
...
@@ -174,7 +174,7 @@ perform_member_init (member, name, init, explicit, protect_list)
if
(
init
!=
NULL_TREE
&&
TREE_CODE
(
init
)
!=
TREE_LIST
)
init
=
build_tree_list
(
NULL_TREE
,
init
);
decl
=
build_component_ref
(
C_C_D
,
name
,
NULL_TREE
,
explicit
);
decl
=
build_component_ref
(
current_class_ref
,
name
,
NULL_TREE
,
explicit
);
if
(
explicit
&&
TREE_CODE
(
type
)
==
ARRAY_TYPE
...
...
@@ -220,7 +220,7 @@ perform_member_init (member, name, init, explicit, protect_list)
current_member_init_list. */
if
(
init
||
explicit
)
{
decl
=
build_component_ref
(
C_C_D
,
name
,
NULL_TREE
,
explicit
);
decl
=
build_component_ref
(
current_class_ref
,
name
,
NULL_TREE
,
explicit
);
expand_expr_stmt
(
build_modify_expr
(
decl
,
INIT_EXPR
,
init
));
}
}
...
...
@@ -237,7 +237,7 @@ perform_member_init (member, name, init, explicit, protect_list)
if
(
TYPE_NEEDS_DESTRUCTOR
(
type
))
{
tree
expr
=
build_component_ref
(
C_C_D
,
name
,
NULL_TREE
,
explicit
);
tree
expr
=
build_component_ref
(
current_class_ref
,
name
,
NULL_TREE
,
explicit
);
expr
=
build_delete
(
type
,
expr
,
integer_zero_node
,
LOOKUP_NONVIRTUAL
|
LOOKUP_DESTRUCTOR
,
0
);
...
...
@@ -487,7 +487,7 @@ build_partial_cleanup_for (binfo)
tree
binfo
;
{
tree
expr
=
convert_pointer_to_real
(
binfo
,
build_unary_op
(
ADDR_EXPR
,
C_C_D
,
0
));
build_unary_op
(
ADDR_EXPR
,
current_class_ref
,
0
));
return
build_delete
(
TREE_TYPE
(
expr
),
expr
,
...
...
@@ -561,7 +561,7 @@ emit_base_init (t, immediately)
tree
first_arg
=
TREE_CHAIN
(
DECL_ARGUMENTS
(
current_function_decl
));
expand_start_cond
(
first_arg
,
0
);
expand_aggr_vbase_init
(
t_binfo
,
C_C_D
,
current_class_decl
,
expand_aggr_vbase_init
(
t_binfo
,
current_class_ref
,
current_class_ptr
,
vbase_init_list
);
expand_end_cond
();
}
...
...
@@ -596,7 +596,7 @@ emit_base_init (t, immediately)
push_temp_slots
();
target_temp_slot_level
=
temp_slot_level
;
member
=
convert_pointer_to_real
(
base_binfo
,
current_class_
decl
);
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
);
...
...
@@ -626,11 +626,11 @@ emit_base_init (t, immediately)
/* Initialize all the virtual function table fields that
do come from virtual base classes. */
if
(
TYPE_USES_VIRTUAL_BASECLASSES
(
t
))
expand_indirect_vtbls_init
(
t_binfo
,
C_C_D
,
current_class_decl
);
expand_indirect_vtbls_init
(
t_binfo
,
current_class_ref
,
current_class_ptr
);
/* Initialize all the virtual function table fields that
do not come from virtual base classes. */
expand_direct_vtbls_init
(
t_binfo
,
t_binfo
,
1
,
1
,
current_class_
decl
);
expand_direct_vtbls_init
(
t_binfo
,
t_binfo
,
1
,
1
,
current_class_
ptr
);
for
(
member
=
TYPE_FIELDS
(
t
);
member
;
member
=
TREE_CHAIN
(
member
))
{
...
...
@@ -863,7 +863,7 @@ do_member_init (s_id, name, init)
return
;
}
base
=
convert_pointer_to
(
binfo
,
current_class_
decl
);
base
=
convert_pointer_to
(
binfo
,
current_class_
ptr
);
expand_member_init
(
build_indirect_ref
(
base
,
NULL_PTR
),
name
,
init
);
}
...
...
@@ -1139,8 +1139,9 @@ expand_member_init (exp, name, init)
explaining that such initializations are invalid.
ALIAS_THIS is nonzero iff we are initializing something which is
essentially an alias for C_C_D. In this case, the base constructor
may move it on us, and we must keep track of such deviations.
essentially an alias for current_class_ref. In this case, the base
constructor may move it on us, and we must keep track of such
deviations.
If INIT resolves to a CALL_EXPR which happens to return
something of the type we are looking for, then we know
...
...
@@ -1160,8 +1161,7 @@ expand_member_init (exp, name, init)
initialization.
A constructor or a conversion operator may have to be used to
perform the initialization, but not both, as it would be ambiguous.
*/
perform the initialization, but not both, as it would be ambiguous. */
void
expand_aggr_init
(
exp
,
init
,
alias_this
,
flags
)
...
...
@@ -1318,8 +1318,8 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags)
value is used in the derived class. */
if
((
flag_this_is_variable
&
1
)
&&
alias_this
)
{
TREE_TYPE
(
rval
)
=
TREE_TYPE
(
current_class_
decl
);
expand_assignment
(
current_class_
decl
,
rval
,
0
,
0
);
TREE_TYPE
(
rval
)
=
TREE_TYPE
(
current_class_
ptr
);
expand_assignment
(
current_class_
ptr
,
rval
,
0
,
0
);
}
else
expand_expr_stmt
(
rval
);
...
...
@@ -1676,7 +1676,7 @@ build_member_call (type, name, parmlist)
tree
ns
=
lookup_name
(
type
,
0
);
if
(
ns
&&
TREE_CODE
(
ns
)
==
NAMESPACE_DECL
)
{
return
build_x_function_call
(
build_offset_ref
(
type
,
name
),
parmlist
,
current_class_
decl
);
return
build_x_function_call
(
build_offset_ref
(
type
,
name
),
parmlist
,
current_class_
ref
);
}
}
...
...
@@ -1705,14 +1705,14 @@ build_member_call (type, name, parmlist)
basetype_path
=
TYPE_BINFO
(
type
);
decl
=
build1
(
NOP_EXPR
,
build_pointer_type
(
type
),
error_mark_node
);
}
else
if
(
current_class_
decl
==
0
)
else
if
(
current_class_
ptr
==
0
)
{
dont_use_this
=
1
;
decl
=
build1
(
NOP_EXPR
,
build_pointer_type
(
type
),
error_mark_node
);
}
else
{
tree
olddecl
=
current_class_
decl
;
tree
olddecl
=
current_class_
ptr
;
tree
oldtype
=
TREE_TYPE
(
TREE_TYPE
(
olddecl
));
if
(
oldtype
!=
type
)
{
...
...
@@ -1846,10 +1846,10 @@ build_offset_ref (type, name)
basebinfo
=
TYPE_BINFO
(
type
);
decl
=
build1
(
NOP_EXPR
,
type
,
error_mark_node
);
}
else
if
(
current_class_
decl
==
0
)
else
if
(
current_class_
ptr
==
0
)
decl
=
build1
(
NOP_EXPR
,
type
,
error_mark_node
);
else
decl
=
C_C_D
;
decl
=
current_class_ref
;
if
(
constructor_name
(
BINFO_TYPE
(
basebinfo
))
==
name
)
if
(
dtor
)
...
...
@@ -1978,7 +1978,12 @@ resolve_offset_ref (exp)
if
(
TREE_CODE
(
exp
)
==
TREE_LIST
)
return
build_unary_op
(
ADDR_EXPR
,
exp
,
0
);
if
(
TREE_CODE
(
exp
)
!=
OFFSET_REF
)
if
(
TREE_CODE
(
exp
)
==
OFFSET_REF
)
{
member
=
TREE_OPERAND
(
exp
,
1
);
base
=
TREE_OPERAND
(
exp
,
0
);
}
else
{
my_friendly_assert
(
TREE_CODE
(
type
)
==
OFFSET_TYPE
,
214
);
if
(
TYPE_OFFSET_BASETYPE
(
type
)
!=
current_class_type
)
...
...
@@ -1988,12 +1993,7 @@ resolve_offset_ref (exp)
}
member
=
exp
;
type
=
TREE_TYPE
(
type
);
base
=
C_C_D
;
}
else
{
member
=
TREE_OPERAND
(
exp
,
1
);
base
=
TREE_OPERAND
(
exp
,
0
);
base
=
current_class_ref
;
}
if
((
TREE_CODE
(
member
)
==
VAR_DECL
...
...
@@ -2008,7 +2008,7 @@ resolve_offset_ref (exp)
/* Syntax error can cause a member which should
have been seen as static to be grok'd as non-static. */
if
(
TREE_CODE
(
member
)
==
FIELD_DECL
&&
C_C_D
==
NULL_TREE
)
if
(
TREE_CODE
(
member
)
==
FIELD_DECL
&&
current_class_ref
==
NULL_TREE
)
{
if
(
TREE_ADDRESSABLE
(
member
)
==
0
)
{
...
...
@@ -2022,7 +2022,7 @@ resolve_offset_ref (exp)
/* The first case is really just a reference to a member of `this'. */
if
(
TREE_CODE
(
member
)
==
FIELD_DECL
&&
(
base
==
C_C_D
&&
(
base
==
current_class_ref
||
(
TREE_CODE
(
base
)
==
NOP_EXPR
&&
TREE_OPERAND
(
base
,
0
)
==
error_mark_node
)))
{
...
...
@@ -2033,7 +2033,7 @@ resolve_offset_ref (exp)
else
basetype
=
DECL_CONTEXT
(
member
);
base
=
current_class_
decl
;
base
=
current_class_
ptr
;
if
(
get_base_distance
(
basetype
,
TREE_TYPE
(
TREE_TYPE
(
base
)),
0
,
&
basetype_path
)
<
0
)
{
...
...
@@ -3555,8 +3555,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
addr
=
convert_force
(
build_pointer_type
(
type
),
addr
,
0
);
if
(
TREE_CODE
(
addr
)
==
NOP_EXPR
&&
TREE_OPERAND
(
addr
,
0
)
==
current_class_
decl
)
ref
=
C_C_D
;
&&
TREE_OPERAND
(
addr
,
0
)
==
current_class_
ptr
)
ref
=
current_class_ref
;
else
ref
=
build_indirect_ref
(
addr
,
NULL_PTR
);
ptr
=
0
;
...
...
gcc/cp/method.c
View file @
4ac14744
...
...
@@ -1549,19 +1549,19 @@ hack_identifier (value, name)
type
=
TREE_TYPE
(
value
);
if
(
TREE_CODE
(
value
)
==
FIELD_DECL
)
{
if
(
current_class_
decl
==
NULL_TREE
)
if
(
current_class_
ptr
==
NULL_TREE
)
{
error
(
"request for member `%s' in static member function"
,
IDENTIFIER_POINTER
(
DECL_NAME
(
value
)));
return
error_mark_node
;
}
TREE_USED
(
current_class_
decl
)
=
1
;
TREE_USED
(
current_class_
ptr
)
=
1
;
/* Mark so that if we are in a constructor, and then find that
this field was initialized by a base initializer,
we can emit an error message. */
TREE_USED
(
value
)
=
1
;
value
=
build_component_ref
(
C_C_D
,
name
,
NULL_TREE
,
1
);
value
=
build_component_ref
(
current_class_ref
,
name
,
NULL_TREE
,
1
);
}
else
if
(
really_overloaded_fn
(
value
))
{
...
...
@@ -1653,141 +1653,6 @@ hack_identifier (value, name)
}
#if 0
/* Given an object OF, and a type conversion operator COMPONENT
build a call to the conversion operator, if a call is requested,
or return the address (as a pointer to member function) if one is not.
OF can be a TYPE_DECL or any kind of datum that would normally
be passed to `build_component_ref'. It may also be NULL_TREE,
in which case `current_class_type' and `current_class_decl'
provide default values.
BASETYPE_PATH, if non-null, is the path of basetypes
to go through before we get the the instance of interest.
PROTECT says whether we apply C++ scoping rules or not. */
tree
build_component_type_expr (of, component, basetype_path, protect)
tree of, component, basetype_path;
int protect;
{
tree cname = NULL_TREE;
tree tmp, last;
tree name;
int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN;
if (of)
my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253);
my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254);
tmp = TREE_OPERAND (component, 0);
last = NULL_TREE;
while (tmp)
{
switch (TREE_CODE (tmp))
{
case CALL_EXPR:
if (last)
TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0);
else
TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0);
last = groktypename (build_tree_list (TREE_TYPE (component),
TREE_OPERAND (component, 0)));
name = build_typename_overload (last);
TREE_TYPE (name) = last;
if (TREE_OPERAND (tmp, 0)
&& TREE_OPERAND (tmp, 0) != void_list_node)
{
cp_error ("`operator %T' requires empty parameter list", last);
TREE_OPERAND (tmp, 0) = NULL_TREE;
}
if (of && TREE_CODE (of) != TYPE_DECL)
return build_method_call (of, name, NULL_TREE, NULL_TREE, flags);
else if (of)
{
tree this_this;
if (current_class_decl == NULL_TREE)
{
cp_error ("object required for `operator %T' call",
TREE_TYPE (name));
return error_mark_node;
}
this_this = convert_pointer_to (TREE_TYPE (of),
current_class_decl);
this_this = build_indirect_ref (this_this, NULL_PTR);
return build_method_call (this_this, name, NULL_TREE,
NULL_TREE, flags | LOOKUP_NONVIRTUAL);
}
else if (current_class_decl)
return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags);
cp_error ("object required for `operator %T' call",
TREE_TYPE (name));
return error_mark_node;
case INDIRECT_REF:
case ADDR_EXPR:
case ARRAY_REF:
break;
case SCOPE_REF:
my_friendly_assert (cname == 0, 255);
cname = TREE_OPERAND (tmp, 0);
tmp = TREE_OPERAND (tmp, 1);
break;
default:
my_friendly_abort (77);
}
last = tmp;
tmp = TREE_OPERAND (tmp, 0);
}
last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0)));
name = build_typename_overload (last);
TREE_TYPE (name) = last;
if (of && TREE_CODE (of) == TYPE_DECL)
{
if (cname == NULL_TREE)
{
cname = DECL_NAME (of);
of = NULL_TREE;
}
else my_friendly_assert (cname == DECL_NAME (of), 256);
}
if (of)
{
tree this_this;
if (current_class_decl == NULL_TREE)
{
cp_error ("object required for `operator %T' call",
TREE_TYPE (name));
return error_mark_node;
}
this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
return build_component_ref (this_this, name, NULL_TREE, protect);
}
else if (cname)
return build_offset_ref (cname, name);
else if (current_class_name)
return build_offset_ref (current_class_name, name);
cp_error ("object required for `operator %T' member reference",
TREE_TYPE (name));
return error_mark_node;
}
#endif
static
char
*
thunk_printable_name
(
decl
)
tree
decl
;
...
...
@@ -1863,6 +1728,7 @@ emit_thunk (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
];
...
...
@@ -1892,6 +1758,8 @@ emit_thunk (thunk_fndecl)
ASM_OUTPUT_MI_THUNK
(
asm_out_file
,
thunk_fndecl
,
delta
,
function
);
assemble_end_function
(
thunk_fndecl
,
fnname
);
#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
);
...
...
@@ -2063,13 +1931,12 @@ emit_thunk (thunk_fndecl)
final
(
insns
,
asm_out_file
,
optimize
,
0
);
assemble_end_function
(
thunk_fndecl
,
fnname
);
exit_rest_of_compilation
:
reload_completed
=
0
;
/* Cancel the effect of rtl_in_current_obstack. */
permanent_allocation
(
1
);
flag_omit_frame_pointer
=
save_ofp
;
#endif
/* ASM_OUTPUT_MI_THUNK */
decl_printable_name
=
save_decl_printable_name
;
...
...
@@ -2112,7 +1979,7 @@ do_build_copy_constructor (fndecl)
if
(
TYPE_HAS_TRIVIAL_INIT_REF
(
current_class_type
))
{
t
=
build
(
INIT_EXPR
,
void_type_node
,
C_C_D
,
parm
);
t
=
build
(
INIT_EXPR
,
void_type_node
,
current_class_ref
,
parm
);
TREE_SIDE_EFFECTS
(
t
)
=
1
;
cplus_expand_expr_stmt
(
t
);
}
...
...
@@ -2202,7 +2069,7 @@ do_build_assign_ref (fndecl)
if
(
TYPE_HAS_TRIVIAL_ASSIGN_REF
(
current_class_type
))
{
tree
t
=
build
(
MODIFY_EXPR
,
void_type_node
,
C_C_D
,
parm
);
tree
t
=
build
(
MODIFY_EXPR
,
void_type_node
,
current_class_ref
,
parm
);
TREE_SIDE_EFFECTS
(
t
)
=
1
;
cplus_expand_expr_stmt
(
t
);
}
...
...
@@ -2253,13 +2120,13 @@ do_build_assign_ref (fndecl)
else
continue
;
comp
=
build
(
COMPONENT_REF
,
TREE_TYPE
(
field
),
C_C_D
,
field
);
comp
=
build
(
COMPONENT_REF
,
TREE_TYPE
(
field
),
current_class_ref
,
field
);
init
=
build
(
COMPONENT_REF
,
TREE_TYPE
(
field
),
parm
,
field
);
expand_expr_stmt
(
build_modify_expr
(
comp
,
NOP_EXPR
,
init
));
}
}
c_expand_return
(
C_C_D
);
c_expand_return
(
current_class_ref
);
pop_momentary
();
}
...
...
gcc/cp/parse.y
View file @
4ac14744
...
...
@@ -782,22 +782,22 @@ member_init: '(' nonnull_exprlist ')'
{
if (current_class_name && !flag_traditional)
pedwarn ("anachronistic old style base class initializer");
expand_member_init (
C_C_D
, NULL_TREE, $2);
expand_member_init (
current_class_ref
, NULL_TREE, $2);
}
| LEFT_RIGHT
{
if (current_class_name && !flag_traditional)
pedwarn ("anachronistic old style base class initializer");
expand_member_init (
C_C_D
, NULL_TREE, void_type_node);
expand_member_init (
current_class_ref
, NULL_TREE, void_type_node);
}
| notype_identifier '(' nonnull_exprlist ')'
{ expand_member_init (
C_C_D
, $1, $3); }
{ expand_member_init (
current_class_ref
, $1, $3); }
| notype_identifier LEFT_RIGHT
{ expand_member_init (
C_C_D
, $1, void_type_node); }
{ expand_member_init (
current_class_ref
, $1, void_type_node); }
| complete_type_name '(' nonnull_exprlist ')'
{ expand_member_init (
C_C_D
, $1, $3); }
{ expand_member_init (
current_class_ref
, $1, $3); }
| complete_type_name LEFT_RIGHT
{ expand_member_init (
C_C_D
, $1, void_type_node); }
{ expand_member_init (
current_class_ref
, $1, void_type_node); }
/* GNU extension */
| notype_qualified_id '(' nonnull_exprlist ')'
{
...
...
@@ -1046,12 +1046,7 @@ nonnull_exprlist:
unary_expr:
primary %prec UNARY
{
#if 0
if (TREE_CODE ($$) == TYPE_EXPR)
$$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1);
#endif
}
{ $$ = $1; }
/* __extension__ turns off -pedantic for following primary. */
| EXTENSION
{ $<itype>1 = pedantic;
...
...
@@ -1362,14 +1357,14 @@ primary:
}
| primary '(' nonnull_exprlist ')'
{
$$ = build_x_function_call ($1, $3, current_class_
decl
);
$$ = build_x_function_call ($1, $3, current_class_
ref
);
if (TREE_CODE ($$) == CALL_EXPR
&& TREE_TYPE ($$) != void_type_node)
$$ = require_complete_type ($$);
}
| primary LEFT_RIGHT
{
$$ = build_x_function_call ($$, NULL_TREE, current_class_
decl
);
$$ = build_x_function_call ($$, NULL_TREE, current_class_
ref
);
if (TREE_CODE ($$) == CALL_EXPR
&& TREE_TYPE ($$) != void_type_node)
$$ = require_complete_type ($$);
...
...
@@ -1391,12 +1386,12 @@ primary:
$$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }
/* C++ extensions */
| THIS
{ if (current_class_
decl
)
{ if (current_class_
ptr
)
{
#ifdef WARNING_ABOUT_CCD
TREE_USED (current_class_
decl
) = 1;
TREE_USED (current_class_
ptr
) = 1;
#endif
$$ = current_class_
decl
;
$$ = current_class_
ptr
;
}
else if (current_function_decl
&& DECL_STATIC_FUNCTION_P (current_function_decl))
...
...
@@ -1516,13 +1511,13 @@ primary:
/* This is a future direction of this code, but because
build_x_function_call cannot always undo what is done
in build_component_ref entirely yet, we cannot do this. */
$$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4,
$$
);
$$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4,
current_class_ref
);
if (TREE_CODE ($$) == CALL_EXPR
&& TREE_TYPE ($$) != void_type_node)
$$ = require_complete_type ($$);
#else
$$ = build_method_call ($$, $2, $4, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR)
);
LOOKUP_NORMAL
);
#endif
}
| object unqualified_id LEFT_RIGHT
...
...
@@ -1531,13 +1526,13 @@ primary:
/* This is a future direction of this code, but because
build_x_function_call cannot always undo what is done
in build_component_ref entirely yet, we cannot do this. */
$$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE,
$$
);
$$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE,
current_class_ref
);
if (TREE_CODE ($$) == CALL_EXPR
&& TREE_TYPE ($$) != void_type_node)
$$ = require_complete_type ($$);
#else
$$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR)
);
LOOKUP_NORMAL
);
#endif
}
| object overqualified_id '(' nonnull_exprlist ')'
...
...
@@ -1546,7 +1541,7 @@ primary:
{
warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR)
);
LOOKUP_NORMAL
);
}
else
$$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4);
...
...
@@ -1557,7 +1552,7 @@ primary:
{
warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR)
);
LOOKUP_NORMAL
);
}
else
$$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), NULL_TREE);
...
...
@@ -1605,9 +1600,9 @@ primary_no_id:
pedwarn ("ANSI C++ forbids braced-groups within expressions");
$$ = expand_end_stmt_expr ($<ttype>2); }
| primary_no_id '(' nonnull_exprlist ')'
{ $$ = build_x_function_call ($$, $3, current_class_
decl
); }
{ $$ = build_x_function_call ($$, $3, current_class_
ref
); }
| primary_no_id LEFT_RIGHT
{ $$ = build_x_function_call ($$, NULL_TREE, current_class_
decl
); }
{ $$ = build_x_function_call ($$, NULL_TREE, current_class_
ref
); }
| primary_no_id '[' expr ']'
{ goto do_array; }
| primary_no_id PLUSPLUS
...
...
gcc/cp/pt.c
View file @
4ac14744
...
...
@@ -2581,6 +2581,10 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return
0
;
case
POINTER_TYPE
:
if
(
TREE_CODE
(
arg
)
==
RECORD_TYPE
&&
TYPE_PTRMEMFUNC_FLAG
(
arg
))
return
unify
(
tparms
,
targs
,
ntparms
,
parm
,
TYPE_PTRMEMFUNC_FN_TYPE
(
arg
),
nsubsts
);
if
(
TREE_CODE
(
arg
)
!=
POINTER_TYPE
)
return
1
;
return
unify
(
tparms
,
targs
,
ntparms
,
TREE_TYPE
(
parm
),
TREE_TYPE
(
arg
),
...
...
gcc/cp/search.c
View file @
4ac14744
...
...
@@ -769,7 +769,7 @@ lookup_field_1 (type, name)
itself inside a class, we need decls to go into the fn's decls (our
second case below). But if we're in a class and the class itself is
inside a function, we need decls to go into the decls for the class. To
achieve this last goal, we must see if, when both current_class_
decl
and
achieve this last goal, we must see if, when both current_class_
ptr
and
current_function_decl are set, the class was declared inside that
function. If so, we know to put the decls into the class's scope. */
...
...
gcc/cp/sig.c
View file @
4ac14744
...
...
@@ -573,7 +573,7 @@ build_signature_table_constructor (sig_ty, rhs)
vb_off
=
build_unary_op
(
NEGATE_EXPR
,
integer_one_node
,
0
);
delta
=
integer_zero_node
;
index
=
integer_zero_node
;
pfn
=
build_
unary_op
(
ADDR_EXPR
,
rhs_method
,
0
);
pfn
=
build_
addr_func
(
rhs_method
);
TREE_SYMBOL_REFERENCED
(
DECL_ASSEMBLER_NAME
(
rhs_method
))
=
1
;
TREE_TYPE
(
pfn
)
=
ptr_type_node
;
TREE_ADDRESSABLE
(
rhs_method
)
=
1
;
...
...
@@ -584,8 +584,12 @@ build_signature_table_constructor (sig_ty, rhs)
/* virtual member function */
tag
=
integer_one_node
;
vb_off
=
build_unary_op
(
NEGATE_EXPR
,
integer_one_node
,
0
);
delta
=
BINFO_OFFSET
(
get_binfo
(
DECL_CLASS_CONTEXT
(
rhs_method
),
rhstype
,
1
));
if
(
flag_vtable_thunks
)
delta
=
BINFO_OFFSET
(
get_binfo
(
DECL_CONTEXT
(
rhs_method
),
rhstype
,
1
));
else
delta
=
BINFO_OFFSET
(
get_binfo
(
DECL_CLASS_CONTEXT
(
rhs_method
),
rhstype
,
1
));
index
=
DECL_VINDEX
(
rhs_method
);
vt_off
=
get_vfield_offset
(
get_binfo
(
DECL_CONTEXT
(
rhs_method
),
rhstype
,
0
));
...
...
@@ -598,7 +602,7 @@ build_signature_table_constructor (sig_ty, rhs)
delta
=
BINFO_OFFSET
(
get_binfo
(
DECL_CLASS_CONTEXT
(
rhs_method
),
rhstype
,
1
));
index
=
integer_zero_node
;
pfn
=
build_
unary_op
(
ADDR_EXPR
,
rhs_method
,
0
);
pfn
=
build_
addr_func
(
rhs_method
);
TREE_SYMBOL_REFERENCED
(
DECL_ASSEMBLER_NAME
(
rhs_method
))
=
1
;
TREE_TYPE
(
pfn
)
=
ptr_type_node
;
TREE_ADDRESSABLE
(
rhs_method
)
=
1
;
...
...
@@ -985,10 +989,7 @@ build_signature_method_call (basetype, instance, function, parms)
TREE_TYPE
(
vfn
)
=
build_pointer_type
(
TREE_TYPE
(
function
));
if
(
flag_vtable_thunks
)
virtual_call
=
build_function_call
(
vfn
,
parms
);
else
virtual_call
=
build_function_call
(
vfn
,
new_parms
);
virtual_call
=
build_function_call
(
vfn
,
new_parms
);
}
/* Undo the cast, make `this' a signature pointer again. */
...
...
gcc/cp/tree.c
View file @
4ac14744
...
...
@@ -48,7 +48,7 @@ real_lvalue_p (ref)
if
(
TREE_CODE
(
TREE_TYPE
(
ref
))
==
REFERENCE_TYPE
)
return
1
;
if
(
ref
==
current_class_
decl
&&
flag_this_is_variable
<=
0
)
if
(
ref
==
current_class_
ptr
&&
flag_this_is_variable
<=
0
)
return
0
;
switch
(
TREE_CODE
(
ref
))
...
...
@@ -118,7 +118,7 @@ lvalue_p (ref)
if
(
TREE_CODE
(
TREE_TYPE
(
ref
))
==
REFERENCE_TYPE
)
return
1
;
if
(
ref
==
current_class_
decl
&&
flag_this_is_variable
<=
0
)
if
(
ref
==
current_class_
ptr
&&
flag_this_is_variable
<=
0
)
return
0
;
switch
(
TREE_CODE
(
ref
))
...
...
gcc/cp/typeck.c
View file @
4ac14744
This diff is collapsed.
Click to expand it.
gcc/cp/typeck2.c
View file @
4ac14744
...
...
@@ -1341,7 +1341,7 @@ build_m_component_ref (datum, component)
{
component
=
build_indirect_ref
(
component
,
NULL_PTR
);
type
=
TREE_TYPE
(
component
);
rettype
=
TREE_TYPE
(
TREE_TYPE
(
component
)
);
rettype
=
TREE_TYPE
(
type
);
}
if
(
datum
==
error_mark_node
||
component
==
error_mark_node
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment