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
73aad9b9
Commit
73aad9b9
authored
Aug 13, 1996
by
Jason Merrill
Committed by
Mike Stump
Aug 13, 1996
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
87th Cygnus<->FSF quick merge
From-SVN: r12630
parent
c8c2dcdc
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
448 additions
and
99 deletions
+448
-99
gcc/cp/ChangeLog
+46
-0
gcc/cp/call.c
+29
-40
gcc/cp/cp-tree.h
+5
-2
gcc/cp/decl.c
+4
-1
gcc/cp/decl2.c
+21
-5
gcc/cp/errfn.c
+6
-5
gcc/cp/parse.y
+10
-0
gcc/cp/pt.c
+298
-36
gcc/cp/tree.c
+29
-2
gcc/cp/typeck.c
+0
-8
No files found.
gcc/cp/ChangeLog
View file @
73aad9b9
Mon Aug 12 00:09:18 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (end_template_decl): If we don't actually have parms, return.
* parse.y (template_header): Accept 'template <>'.
* errfn.c: Allow 5 args.
Sun Aug 11 15:20:58 1996 Jason Merrill <jason@yorick.cygnus.com>
* tree.c (make_temp_vec): New fn.
* pt.c (push_template_decl): Handle partial specs.
(instantiate_class_template): Ditto.
(more_specialized): Use get_bindings.
(more_specialized_class): New fn.
(get_class_bindings): New fn.
(most_specialized_class): New fn.
(do_function_instantiation): List candidates for ambiguous case.
* decl.c (duplicate_decls): Lose reference to DECL_TEMPLATE_MEMBERS.
(shadow_tag): Call push_template_decl for partial specializations.
* parse.y: Ditto.
* cp-tree.h (DECL_TEMPLATE_SPECIALIZATIONS): Replaces
DECL_TEMPLATE_MEMBERS.
* call.c (print_z_candidates): Reduce duplication.
Fri Aug 9 14:36:08 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c (lang_decode_option): Allow -fansi-overloading.
Thu Aug 8 17:04:18 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (get_bindings): New fn.
(most_specialized): Ditto.
(do_function_instantiation): Use them.
(add_maybe_template): New fn.
* cp-tree.h (DECL_MAYBE_TEMPLATE): New macro.
* call.c (build_new_op): Handle guiding decls.
(build_new_function_call): Ditto.
* decl2.c (finish_file): Ditto.
* decl2.c (mark_used): Do synthesis here.
* call.c (build_method_call): Not here.
(build_over_call): Or here.
* typeck.c (build_function_call_real): Or here.
* tree.c (bot_manip): Call mark_used on functions used in default
args.
Thu Aug 8 17:48:16 1996 Michael Meissner <meissner@tiktok.cygnus.com>
* decl2.c (import_export_vtable): Delete code that disabled vtable
...
...
gcc/cp/call.c
View file @
73aad9b9
...
...
@@ -2468,12 +2468,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
function
=
DECL_MAIN_VARIANT
(
function
);
mark_used
(
function
);
/* Is it a synthesized method that needs to be synthesized? */
if
(
DECL_ARTIFICIAL
(
function
)
&&
!
DECL_INITIAL
(
function
)
/* Kludge: don't synthesize for default args. */
&&
current_function_decl
)
synthesize_method
(
function
);
if
(
pedantic
&&
DECL_THIS_INLINE
(
function
)
&&
!
DECL_ARTIFICIAL
(
function
)
&&
!
DECL_INITIAL
(
function
)
&&
!
DECL_PENDING_INLINE_INFO
(
function
)
&&
!
(
DECL_TEMPLATE_INFO
(
function
)
...
...
@@ -4157,48 +4151,27 @@ static void
print_z_candidates
(
candidates
)
struct
z_candidate
*
candidates
;
{
if
(
!
candidates
)
return
;
if
(
TREE_CODE
(
candidates
->
fn
)
==
IDENTIFIER_NODE
)
{
if
(
candidates
->
fn
==
ansi_opname
[
COND_EXPR
])
cp_error
(
"candidates are: %D(%T, %T, %T) <builtin>"
,
candidates
->
fn
,
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
0
)),
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
1
)),
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
2
)));
else
if
(
TREE_VEC_LENGTH
(
candidates
->
convs
)
==
2
)
cp_error
(
"candidates are: %D(%T, %T) <builtin>"
,
candidates
->
fn
,
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
0
)),
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
1
)));
else
cp_error
(
"candidates are: %D(%T) <builtin>"
,
candidates
->
fn
,
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
0
)));
}
else
cp_error_at
(
"candidates are: %D"
,
candidates
->
fn
);
candidates
=
candidates
->
next
;
char
*
str
=
"candidates are:"
;
for
(;
candidates
;
candidates
=
candidates
->
next
)
{
if
(
TREE_CODE
(
candidates
->
fn
)
==
IDENTIFIER_NODE
)
{
if
(
candidates
->
fn
==
ansi_opname
[
COND_EXPR
])
cp_error
(
" %D(%T, %T, %T) <builtin>"
,
candidates
->
fn
,
cp_error
(
"%s %D(%T, %T, %T) <builtin>"
,
str
,
candidates
->
fn
,
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
0
)),
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
1
)),
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
2
)));
else
if
(
TREE_VEC_LENGTH
(
candidates
->
convs
)
==
2
)
cp_error
(
"
%D(%T, %T) <builtin>"
,
candidates
->
fn
,
cp_error
(
"
%s %D(%T, %T) <builtin>"
,
str
,
candidates
->
fn
,
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
0
)),
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
1
)));
else
cp_error
(
"
%D(%T) <builtin>"
,
candidates
->
fn
,
cp_error
(
"
%s %D(%T) <builtin>"
,
str
,
candidates
->
fn
,
TREE_TYPE
(
TREE_VEC_ELT
(
candidates
->
convs
,
0
)));
}
else
cp_error_at
(
" %D"
,
candidates
->
fn
);
cp_error_at
(
"%s %+D"
,
str
,
candidates
->
fn
);
str
=
" "
;
}
}
...
...
@@ -4334,6 +4307,7 @@ build_new_function_call (fn, args, obj)
if
(
obj
==
NULL_TREE
&&
TREE_CODE
(
fn
)
==
TREE_LIST
)
{
tree
t
;
tree
templates
=
NULL_TREE
;
for
(
t
=
args
;
t
;
t
=
TREE_CHAIN
(
t
))
if
(
TREE_VALUE
(
t
)
==
error_mark_node
)
...
...
@@ -4342,8 +4316,11 @@ build_new_function_call (fn, args, obj)
for
(
t
=
TREE_VALUE
(
fn
);
t
;
t
=
DECL_CHAIN
(
t
))
{
if
(
TREE_CODE
(
t
)
==
TEMPLATE_DECL
)
{
templates
=
decl_tree_cons
(
NULL_TREE
,
t
,
templates
);
candidates
=
add_template_candidate
(
candidates
,
t
,
args
,
LOOKUP_NORMAL
);
}
else
candidates
=
add_function_candidate
(
candidates
,
t
,
args
,
LOOKUP_NORMAL
);
...
...
@@ -4369,6 +4346,12 @@ build_new_function_call (fn, args, obj)
return
error_mark_node
;
}
/* Pedantically, it is ill-formed to define a function that could
also be a template instantiation, but we won't implement that
until things settle down. */
if
(
templates
&&
!
cand
->
template
&&
!
DECL_INITIAL
(
cand
->
fn
))
add_maybe_template
(
cand
->
fn
,
templates
);
return
build_over_call
(
cand
->
fn
,
cand
->
convs
,
args
,
LOOKUP_NORMAL
);
}
...
...
@@ -4482,6 +4465,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
struct
z_candidate
*
candidates
=
0
,
*
cand
;
tree
fns
,
mem_arglist
,
arglist
,
fnname
,
*
p
;
enum
tree_code
code2
=
NOP_EXPR
;
tree
templates
=
NULL_TREE
;
if
(
arg1
==
error_mark_node
)
return
error_mark_node
;
...
...
@@ -4602,7 +4586,11 @@ build_new_op (code, flags, arg1, arg2, arg3)
for
(;
fns
;
fns
=
DECL_CHAIN
(
fns
))
{
if
(
TREE_CODE
(
fns
)
==
TEMPLATE_DECL
)
candidates
=
add_template_candidate
(
candidates
,
fns
,
arglist
,
flags
);
{
templates
=
decl_tree_cons
(
NULL_TREE
,
fns
,
templates
);
candidates
=
add_template_candidate
(
candidates
,
fns
,
arglist
,
flags
);
}
else
candidates
=
add_function_candidate
(
candidates
,
fns
,
arglist
,
flags
);
}
...
...
@@ -4715,6 +4703,13 @@ build_new_op (code, flags, arg1, arg2, arg3)
if
(
DECL_FUNCTION_MEMBER_P
(
cand
->
fn
))
enforce_access
(
cand
->
basetype_path
,
cand
->
fn
);
/* Pedantically, it is ill-formed to define a function that could
also be a template instantiation, but we won't implement that
until things settle down. */
if
(
templates
&&
!
cand
->
template
&&
!
DECL_INITIAL
(
cand
->
fn
)
&&
TREE_CODE
(
TREE_TYPE
(
cand
->
fn
))
!=
METHOD_TYPE
)
add_maybe_template
(
cand
->
fn
,
templates
);
return
build_over_call
(
cand
->
fn
,
cand
->
convs
,
TREE_CODE
(
TREE_TYPE
(
cand
->
fn
))
==
METHOD_TYPE
...
...
@@ -4999,12 +4994,6 @@ build_over_call (fn, convs, args, flags)
converted_args
=
nreverse
(
converted_args
);
mark_used
(
fn
);
/* Is it a synthesized method that needs to be synthesized? */
if
(
DECL_ARTIFICIAL
(
fn
)
&&
!
DECL_INITIAL
(
fn
)
&&
DECL_CLASS_CONTEXT
(
fn
)
/* Kludge: don't synthesize for default args. */
&&
current_function_decl
)
synthesize_method
(
fn
);
if
(
pedantic
&&
DECL_THIS_INLINE
(
fn
)
&&
!
DECL_ARTIFICIAL
(
fn
)
&&
!
DECL_INITIAL
(
fn
)
&&
!
DECL_PENDING_INLINE_INFO
(
fn
)
...
...
gcc/cp/cp-tree.h
View file @
73aad9b9
...
...
@@ -1135,7 +1135,7 @@ struct lang_decl
#if 0 /* UNUSED */
/* Nonzero in IDENTIFIER_NODE means that this name is overloaded, and
should be looked up in a non-standard way. */
#define DECL_OVERLOADED(NODE) (
DECL_LANG_FLAG_4 (NODE)
)
#define DECL_OVERLOADED(NODE) (
FOO
)
#endif
/* Nonzero if this (non-TYPE)_DECL has its virtual attribute set.
...
...
@@ -1331,7 +1331,7 @@ extern int flag_new_for_scope;
/* Accessor macros for C++ template decl nodes. */
#define DECL_TEMPLATE_PARMS(NODE) DECL_ARGUMENTS(NODE)
/* For class templates. */
#define DECL_TEMPLATE_
MEMBER
S(NODE) DECL_SIZE(NODE)
#define DECL_TEMPLATE_
SPECIALIZATION
S(NODE) DECL_SIZE(NODE)
/* For function, method, class-data templates. */
#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE)
#define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX(NODE)
...
...
@@ -1380,6 +1380,8 @@ extern int flag_new_for_scope;
#define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
(CLASSTYPE_USE_TEMPLATE(NODE) = 3)
/* This function may be a guiding decl for a template. */
#define DECL_MAYBE_TEMPLATE(NODE) DECL_LANG_FLAG_4 (NODE)
/* We know what we're doing with this decl now. */
#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE)
...
...
@@ -2308,6 +2310,7 @@ extern tree instantiate_decl PROTO((tree));
extern
tree
classtype_mangled_name
PROTO
((
tree
));
extern
tree
lookup_nested_type_by_name
PROTO
((
tree
,
tree
));
extern
tree
do_poplevel
PROTO
((
void
));
extern
tree
*
get_bindings
PROTO
((
tree
,
tree
));
/* in search.c */
extern
void
push_memoized_context
PROTO
((
tree
,
int
));
...
...
gcc/cp/decl.c
View file @
73aad9b9
...
...
@@ -2869,7 +2869,6 @@ duplicate_decls (newdecl, olddecl)
if
(
TREE_CODE
(
newdecl
)
==
TEMPLATE_DECL
)
{
DECL_TEMPLATE_MEMBERS
(
newdecl
)
=
DECL_TEMPLATE_MEMBERS
(
olddecl
);
DECL_TEMPLATE_INSTANTIATIONS
(
newdecl
)
=
DECL_TEMPLATE_INSTANTIATIONS
(
olddecl
);
if
(
DECL_CHAIN
(
newdecl
)
==
NULL_TREE
)
...
...
@@ -5646,7 +5645,11 @@ shadow_tag (declspecs)
{
if
(
CLASSTYPE_IMPLICIT_INSTANTIATION
(
value
)
&&
TYPE_SIZE
(
value
)
==
NULL_TREE
)
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION
(
value
);
if
(
current_template_parms
)
push_template_decl
(
TYPE_MAIN_DECL
(
value
));
}
else
if
(
CLASSTYPE_TEMPLATE_INSTANTIATION
(
value
))
cp_error
(
"specialization after instantiation of `%T'"
,
value
);
}
...
...
gcc/cp/decl2.c
View file @
73aad9b9
...
...
@@ -498,11 +498,6 @@ lang_decode_option (p)
flag_alt_external_templates
=
0
;
found
=
1
;
}
else
if
(
!
strcmp
(
p
,
"ansi-overloading"
))
{
warning
(
"-fansi-overloading is no longer meaningful"
);
found
=
1
;
}
else
if
(
!
strcmp
(
p
,
"repo"
))
{
flag_use_repository
=
1
;
...
...
@@ -2876,6 +2871,7 @@ build_cleanup (decl)
extern
int
parse_time
,
varconst_time
;
extern
tree
pending_templates
;
extern
tree
maybe_templates
;
#define TIMEVAR(VAR, BODY) \
do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
...
...
@@ -2952,6 +2948,20 @@ finish_file ()
instantiate_decl
(
decl
);
}
for
(
fnname
=
maybe_templates
;
fnname
;
fnname
=
TREE_CHAIN
(
fnname
))
{
tree
*
args
,
fn
,
decl
=
TREE_VALUE
(
fnname
);
if
(
DECL_INITIAL
(
decl
))
continue
;
fn
=
TREE_PURPOSE
(
fnname
);
args
=
get_bindings
(
fn
,
decl
);
fn
=
instantiate_template
(
fn
,
args
);
free
(
args
);
instantiate_decl
(
fn
);
}
/* Push into C language context, because that's all
we'll need here. */
push_lang_context
(
lang_name_c
);
...
...
@@ -3848,6 +3858,12 @@ mark_used (decl)
if
(
current_template_parms
)
return
;
assemble_external
(
decl
);
/* Is it a synthesized method that needs to be synthesized? */
if
(
TREE_CODE
(
decl
)
==
FUNCTION_DECL
&&
DECL_CLASS_CONTEXT
(
decl
)
&&
DECL_ARTIFICIAL
(
decl
)
&&
!
DECL_INITIAL
(
decl
)
/* Kludge: don't synthesize for default args. */
&&
current_function_decl
)
synthesize_method
(
decl
);
if
(
DECL_LANG_SPECIFIC
(
decl
)
&&
DECL_TEMPLATE_INFO
(
decl
))
instantiate_decl
(
decl
);
}
gcc/cp/errfn.c
View file @
73aad9b9
...
...
@@ -44,11 +44,12 @@ extern int cp_line_of PROTO((tree));
#define STRDUP(f) (ap = (char *) alloca (strlen (f) +1), strcpy (ap, (f)), ap)
#define NARGS 4
#define arglist a1, a2, a3, a4
#define arglist_dcl HOST_WIDE_INT a1, a2, a3, a4;
#define ARGSINIT args[0] = a1; args[1] = a2; args[2] = a3; args[3] = a4;
#define ARGSLIST args[0], args[1], args[2], args[3]
#define NARGS 5
#define arglist a1, a2, a3, a4, a5
#define arglist_dcl HOST_WIDE_INT a1, a2, a3, a4, a5;
#define ARGSINIT \
args[0] = a1; args[1] = a2; args[2] = a3; args[3] = a4; args[4] = a5;
#define ARGSLIST args[0], args[1], args[2], args[3], args[4]
static
void
cp_thing
(
errfn
,
atarg1
,
format
,
arglist
)
...
...
gcc/cp/parse.y
View file @
73aad9b9
...
...
@@ -418,6 +418,8 @@ template_header:
{ begin_template_parm_list (); }
template_parm_list '>'
{ $$ = end_template_parm_list ($4); }
| TEMPLATE '<' '>'
{ $$ = NULL_TREE; }
;
template_parm_list:
...
...
@@ -2321,7 +2323,11 @@ named_class_head:
{
if (CLASSTYPE_IMPLICIT_INSTANTIATION ($$)
&& TYPE_SIZE ($$) == NULL_TREE)
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$);
if (current_template_parms)
push_template_decl (TYPE_MAIN_DECL ($$));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$))
cp_error ("specialization after instantiation of `%T'", $$);
}
...
...
@@ -2525,7 +2531,11 @@ left_curly: '{'
{
if (CLASSTYPE_IMPLICIT_INSTANTIATION (t)
&& TYPE_SIZE (t) == NULL_TREE)
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t);
if (current_template_parms)
push_template_decl (TYPE_MAIN_DECL (t));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
cp_error ("specialization after instantiation of `%T'", t);
}
...
...
gcc/cp/pt.c
View file @
73aad9b9
...
...
@@ -53,6 +53,9 @@ HOST_WIDE_INT processing_template_decl;
tree
pending_templates
;
static
tree
*
template_tail
=
&
pending_templates
;
tree
maybe_templates
;
static
tree
*
maybe_template_tail
=
&
maybe_templates
;
int
minimal_parse_mode
;
#define obstack_chunk_alloc xmalloc
...
...
@@ -65,6 +68,9 @@ void pop_template_decls ();
tree
classtype_mangled_name
();
static
char
*
mangle_class_name_for_template
();
tree
tsubst_expr_values
();
tree
most_specialized_class
PROTO
((
tree
,
tree
));
tree
get_class_bindings
PROTO
((
tree
,
tree
,
tree
));
tree
make_temp_vec
PROTO
((
int
));
/* We've got a template header coming up; push to a new level for storing
the parms. */
...
...
@@ -181,6 +187,9 @@ end_template_parm_list (parms)
void
end_template_decl
()
{
if
(
!
current_template_parms
)
return
;
/* This matches the pushlevel in begin_template_parm_list. */
poplevel
(
0
,
0
,
0
);
...
...
@@ -229,6 +238,30 @@ push_template_decl (decl)
args
=
nreverse
(
args
);
args
=
TREE_VALUE
(
args
);
/* Partial specialization. */
if
(
TREE_CODE
(
decl
)
==
TYPE_DECL
&&
CLASSTYPE_TEMPLATE_SPECIALIZATION
(
TREE_TYPE
(
decl
)))
{
tree
type
=
TREE_TYPE
(
decl
);
tree
maintmpl
=
CLASSTYPE_TI_TEMPLATE
(
type
);
tree
mainargs
=
CLASSTYPE_TI_ARGS
(
type
);
tree
spec
=
DECL_TEMPLATE_SPECIALIZATIONS
(
maintmpl
);
for
(;
spec
;
spec
=
TREE_CHAIN
(
spec
))
{
/* purpose: args to main template
value: spec template */
if
(
comp_template_args
(
TREE_PURPOSE
(
spec
),
mainargs
))
return
;
}
DECL_TEMPLATE_SPECIALIZATIONS
(
maintmpl
)
=
perm_tree_cons
(
mainargs
,
TREE_VALUE
(
current_template_parms
),
DECL_TEMPLATE_SPECIALIZATIONS
(
maintmpl
));
TREE_TYPE
(
DECL_TEMPLATE_SPECIALIZATIONS
(
maintmpl
))
=
type
;
return
;
}
if
(
!
ctx
||
TYPE_BEING_DEFINED
(
ctx
))
{
tmpl
=
build_lang_decl
(
TEMPLATE_DECL
,
DECL_NAME
(
decl
),
NULL_TREE
);
...
...
@@ -237,6 +270,9 @@ push_template_decl (decl)
}
else
{
if
(
CLASSTYPE_TEMPLATE_INSTANTIATION
(
ctx
))
cp_error
(
"must specialize `%#T' before defining member `%#D'"
,
ctx
,
decl
);
if
(
TREE_CODE
(
decl
)
==
TYPE_DECL
)
tmpl
=
CLASSTYPE_TI_TEMPLATE
(
TREE_TYPE
(
decl
));
else
if
(
!
DECL_TEMPLATE_INFO
(
decl
))
...
...
@@ -1004,11 +1040,36 @@ instantiate_class_template (type)
template
=
TI_TEMPLATE
(
template_info
);
my_friendly_assert
(
TREE_CODE
(
template
)
==
TEMPLATE_DECL
,
279
);
args
=
TI_ARGS
(
template_info
);
t
=
most_specialized_class
(
DECL_TEMPLATE_SPECIALIZATIONS
(
template
),
args
);
if
(
t
==
error_mark_node
)
{
char
*
str
=
"candidates are:"
;
cp_error
(
"ambiguous class template instantiation for `%#T'"
,
type
);
for
(
t
=
DECL_TEMPLATE_SPECIALIZATIONS
(
template
);
t
;
t
=
TREE_CHAIN
(
t
))
{
if
(
get_class_bindings
(
TREE_VALUE
(
t
),
TREE_PURPOSE
(
t
),
args
))
{
cp_error_at
(
"%s %+#T"
,
str
,
TREE_TYPE
(
t
));
str
=
" "
;
}
}
TYPE_BEING_DEFINED
(
type
)
=
1
;
return
;
}
else
if
(
t
)
pattern
=
TREE_TYPE
(
t
);
else
pattern
=
TREE_TYPE
(
template
);
if
(
TYPE_SIZE
(
pattern
)
==
NULL_TREE
)
return
type
;
if
(
t
)
args
=
get_class_bindings
(
TREE_VALUE
(
t
),
TREE_PURPOSE
(
t
),
args
);
TYPE_BEING_DEFINED
(
type
)
=
1
;
if
(
!
push_tinst_level
(
type
))
...
...
@@ -2785,34 +2846,207 @@ int
more_specialized
(
pat1
,
pat2
)
tree
pat1
,
pat2
;
{
int
ntparms
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
pat1
));
tree
*
targs
=
(
tree
*
)
malloc
(
sizeof
(
tree
)
*
ntparms
);
int
i
,
dummy
=
0
,
winner
=
0
;
i
=
type_unification
(
DECL_TEMPLATE_PARMS
(
pat1
),
targs
,
TYPE_ARG_TYPES
(
TREE_TYPE
(
pat1
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
pat2
)),
&
dummy
,
0
,
1
);
tree
*
targs
;
int
winner
=
0
;
targs
=
get_bindings
(
pat1
,
pat2
);
if
(
targs
)
{
free
(
targs
);
if
(
i
==
0
)
--
winner
;
}
ntparms
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
pat2
));
targs
=
(
tree
*
)
malloc
(
sizeof
(
tree
)
*
ntparms
);
targs
=
get_bindings
(
pat2
,
pat1
);
if
(
targs
)
{
free
(
targs
);
++
winner
;
}
i
=
type_unification
(
DECL_TEMPLATE_PARMS
(
pat2
),
targs
,
TYPE_ARG_TYPES
(
TREE_TYPE
(
pat2
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
pat1
)),
&
dummy
,
0
,
1
);
return
winner
;
}
free
(
targs
);
if
(
i
==
0
)
/* Given two class template specialization list nodes PAT1 and PAT2, return:
1 if PAT1 is more specialized than PAT2 as described in [temp.class.order].
-1 if PAT2 is more specialized than PAT1.
0 if neither is more specialized. */
int
more_specialized_class
(
pat1
,
pat2
)
tree
pat1
,
pat2
;
{
tree
targs
;
int
winner
=
0
;
targs
=
get_class_bindings
(
TREE_VALUE
(
pat1
),
TREE_PURPOSE
(
pat1
),
TREE_PURPOSE
(
pat2
));
if
(
targs
)
--
winner
;
targs
=
get_class_bindings
(
TREE_VALUE
(
pat2
),
TREE_PURPOSE
(
pat2
),
TREE_PURPOSE
(
pat1
));
if
(
targs
)
++
winner
;
return
winner
;
}
/* Return the template arguments that will produce the function signature
DECL from the function template FN. */
tree
*
get_bindings
(
fn
,
decl
)
tree
fn
,
decl
;
{
int
ntparms
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
fn
));
tree
*
targs
=
(
tree
*
)
malloc
(
sizeof
(
tree
)
*
ntparms
);
int
i
,
dummy
=
0
;
i
=
type_unification
(
DECL_TEMPLATE_PARMS
(
fn
),
targs
,
TYPE_ARG_TYPES
(
TREE_TYPE
(
fn
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)),
&
dummy
,
0
,
1
);
if
(
i
==
0
)
return
targs
;
free
(
targs
);
return
0
;
}
tree
get_class_bindings
(
tparms
,
parms
,
args
)
tree
tparms
,
parms
,
args
;
{
int
i
,
dummy
,
ntparms
=
TREE_VEC_LENGTH
(
tparms
);
tree
vec
=
make_temp_vec
(
ntparms
);
for
(
i
=
0
;
i
<
TREE_VEC_LENGTH
(
parms
);
++
i
)
{
switch
(
unify
(
tparms
,
&
TREE_VEC_ELT
(
vec
,
0
),
ntparms
,
TREE_VEC_ELT
(
parms
,
i
),
TREE_VEC_ELT
(
args
,
i
),
&
dummy
,
1
))
{
case
0
:
break
;
case
1
:
return
NULL_TREE
;
}
}
for
(
i
=
0
;
i
<
ntparms
;
++
i
)
if
(
!
TREE_VEC_ELT
(
vec
,
i
))
return
NULL_TREE
;
return
vec
;
}
/* Return the most specialized of the list of templates in FNS that can
produce an instantiation matching DECL. */
tree
most_specialized
(
fns
,
decl
)
tree
fns
,
decl
;
{
tree
fn
,
champ
,
*
args
,
*
p
;
int
fate
;
for
(
p
=
&
fns
;
*
p
;
)
{
args
=
get_bindings
(
TREE_VALUE
(
*
p
),
decl
);
if
(
args
)
{
free
(
args
);
p
=
&
TREE_CHAIN
(
*
p
);
}
else
*
p
=
TREE_CHAIN
(
*
p
);
}
if
(
!
fns
)
return
NULL_TREE
;
fn
=
fns
;
champ
=
TREE_VALUE
(
fn
);
fn
=
TREE_CHAIN
(
fn
);
for
(;
fn
;
fn
=
TREE_CHAIN
(
fn
))
{
fate
=
more_specialized
(
champ
,
TREE_VALUE
(
fn
));
if
(
fate
==
1
)
;
else
{
if
(
fate
==
0
)
{
fn
=
TREE_CHAIN
(
fn
);
if
(
!
fn
)
return
error_mark_node
;
}
champ
=
TREE_VALUE
(
fn
);
}
}
for
(
fn
=
fns
;
fn
&&
TREE_VALUE
(
fn
)
!=
champ
;
fn
=
TREE_CHAIN
(
fn
))
{
fate
=
more_specialized
(
champ
,
TREE_VALUE
(
fn
));
if
(
fate
!=
1
)
return
error_mark_node
;
}
return
champ
;
}
/* Return the most specialized of the class template specializations in
SPECS that can produce an instantiation matching ARGS. */
tree
most_specialized_class
(
specs
,
mainargs
)
tree
specs
,
mainargs
;
{
tree
list
=
NULL_TREE
,
t
,
args
,
champ
;
int
fate
;
for
(
t
=
specs
;
t
;
t
=
TREE_CHAIN
(
t
))
{
args
=
get_class_bindings
(
TREE_VALUE
(
t
),
TREE_PURPOSE
(
t
),
mainargs
);
if
(
args
)
{
list
=
decl_tree_cons
(
TREE_PURPOSE
(
t
),
TREE_VALUE
(
t
),
list
);
TREE_TYPE
(
list
)
=
TREE_TYPE
(
t
);
}
}
if
(
!
list
)
return
NULL_TREE
;
t
=
list
;
champ
=
t
;
t
=
TREE_CHAIN
(
t
);
for
(;
t
;
t
=
TREE_CHAIN
(
t
))
{
fate
=
more_specialized_class
(
champ
,
t
);
if
(
fate
==
1
)
;
else
{
if
(
fate
==
0
)
{
t
=
TREE_CHAIN
(
t
);
if
(
!
t
)
return
error_mark_node
;
}
champ
=
t
;
}
}
for
(
t
=
list
;
t
&&
t
!=
champ
;
t
=
TREE_CHAIN
(
t
))
{
fate
=
more_specialized
(
champ
,
t
);
if
(
fate
!=
1
)
return
error_mark_node
;
}
return
champ
;
}
/* called from the parser. */
void
...
...
@@ -2844,6 +3078,7 @@ do_function_instantiation (declspecs, declarator, storage)
}
else
if
(
name
=
DECL_NAME
(
decl
),
fn
=
IDENTIFIER_GLOBAL_VALUE
(
name
),
fn
)
{
tree
templates
=
NULL_TREE
;
for
(
fn
=
get_first_fn
(
fn
);
fn
;
fn
=
DECL_CHAIN
(
fn
))
if
(
decls_match
(
fn
,
decl
)
&&
DECL_DEFER_OUTPUT
(
fn
))
...
...
@@ -2852,30 +3087,29 @@ do_function_instantiation (declspecs, declarator, storage)
break
;
}
else
if
(
TREE_CODE
(
fn
)
==
TEMPLATE_DECL
)
templates
=
decl_tree_cons
(
NULL_TREE
,
fn
,
templates
);
if
(
!
result
)
{
int
ntparms
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
fn
));
tree
*
targs
=
(
tree
*
)
malloc
(
sizeof
(
tree
)
*
ntparms
);
int
i
,
dummy
=
0
;
i
=
type_unification
(
DECL_TEMPLATE_PARMS
(
fn
),
targs
,
TYPE_ARG_TYPES
(
TREE_TYPE
(
fn
)),
TYPE_ARG_TYPES
(
TREE_TYPE
(
decl
)),
&
dummy
,
0
,
1
);
if
(
i
==
0
)
{
if
(
result
)
tree
*
args
;
result
=
most_specialized
(
templates
,
decl
);
if
(
result
==
error_mark_node
)
{
int
win
=
more_specialized
(
DECL_TI_TEMPLATE
(
result
),
fn
);
if
(
win
==
0
)
char
*
str
=
"candidates are:"
;
cp_error
(
"ambiguous template instantiation for `%D' requested"
,
decl
);
else
if
(
win
==
-
1
)
result
=
instantiate_template
(
fn
,
targs
);
/* else keep current winner */
for
(
fn
=
templates
;
fn
;
fn
=
TREE_CHAIN
(
fn
))
{
cp_error_at
(
"%s %+#D"
,
str
,
TREE_VALUE
(
fn
));
str
=
" "
;
}
else
result
=
instantiate_template
(
fn
,
targs
);
return
;
}
else
if
(
result
)
{
args
=
get_bindings
(
result
,
decl
);
result
=
instantiate_template
(
result
,
args
);
free
(
args
);
}
free
(
targs
);
}
}
if
(
!
result
)
...
...
@@ -3195,3 +3429,31 @@ add_tree (t)
{
last_tree
=
TREE_CHAIN
(
last_tree
)
=
t
;
}
/* D is an undefined function declaration in the presence of templates with
the same name, listed in FNS. If one of them can produce D as an
instantiation, remember this so we can instantiate it at EOF if D has
not been defined by that time. */
void
add_maybe_template
(
d
,
fns
)
tree
d
,
fns
;
{
tree
t
;
if
(
DECL_MAYBE_TEMPLATE
(
d
))
return
;
t
=
most_specialized
(
fns
,
d
);
if
(
!
t
)
return
;
if
(
t
==
error_mark_node
)
{
cp_error
(
"ambiguous template instantiation for `%D'"
,
d
);
return
;
}
*
maybe_template_tail
=
perm_tree_cons
(
t
,
d
,
NULL_TREE
);
maybe_template_tail
=
&
TREE_CHAIN
(
*
maybe_template_tail
);
DECL_MAYBE_TEMPLATE
(
d
)
=
1
;
}
gcc/cp/tree.c
View file @
73aad9b9
...
...
@@ -1772,8 +1772,21 @@ bot_manip (t)
if
(
TREE_CODE
(
t
)
!=
TREE_LIST
&&
!
TREE_SIDE_EFFECTS
(
t
))
return
t
;
else
if
(
TREE_CODE
(
t
)
==
TARGET_EXPR
)
return
build_cplus_new
(
TREE_TYPE
(
t
),
break_out_target_exprs
(
TREE_OPERAND
(
t
,
1
)));
{
if
(
TREE_CODE
(
TREE_OPERAND
(
t
,
1
))
==
NEW_EXPR
)
{
mark_used
(
TREE_OPERAND
(
TREE_OPERAND
(
TREE_OPERAND
(
t
,
1
),
0
),
0
));
return
build_cplus_new
(
TREE_TYPE
(
t
),
break_out_target_exprs
(
TREE_OPERAND
(
t
,
1
)));
}
t
=
copy_node
(
t
);
TREE_OPERAND
(
t
,
0
)
=
build
(
VAR_DECL
,
TREE_TYPE
(
t
));
layout_decl
(
TREE_OPERAND
(
t
,
0
),
0
);
return
t
;
}
else
if
(
TREE_CODE
(
t
)
==
CALL_EXPR
)
mark_used
(
TREE_OPERAND
(
TREE_OPERAND
(
t
,
0
),
0
));
return
NULL_TREE
;
}
...
...
@@ -2078,3 +2091,17 @@ cp_tree_equal (t1, t2)
return
-
1
;
}
/* Similar to make_tree_vec, but build on a temporary obstack. */
tree
make_temp_vec
(
len
)
int
len
;
{
register
tree
node
;
push_obstacks_nochange
();
resume_temporary_allocation
();
node
=
make_tree_vec
(
len
);
pop_obstacks
();
return
node
;
}
gcc/cp/typeck.c
View file @
73aad9b9
...
...
@@ -2545,15 +2545,7 @@ build_function_call_real (function, params, require_complete, flags)
needs to be separately compiled). */
if
(
DECL_INLINE
(
function
))
{
/* Is it a synthesized method that needs to be synthesized? */
if
(
DECL_ARTIFICIAL
(
function
)
&&
!
DECL_INITIAL
(
function
)
/* Kludge: don't synthesize for default args. */
&&
current_function_decl
)
synthesize_method
(
function
);
function
=
inline_conversion
(
function
);
}
else
function
=
build_addr_func
(
function
);
}
...
...
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