diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-07-26 20:10:43 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-07-26 20:10:43 +0000 |
commit | d145d8d59b4e67d69e610d8664788abba73af3d1 (patch) | |
tree | 9feb5c92f6ca92e0e155d86992b0be0d7a2f82a6 /gcc | |
parent | 7b469a92baa0e3b84e21a8f8ccb3294a1aa737f6 (diff) | |
download | gcc-d145d8d59b4e67d69e610d8664788abba73af3d1.tar.gz |
* function.c (assign_parms): Handle frontend-directed pass by
invisible reference.
cp/
* call.c (build_over_call): Likewise.
(cp_convert_parm_for_inlining): New fn.
(convert_for_arg_passing): New fn.
(convert_default_arg, build_over_call): Use it.
(type_passed_as): New fn.
* pt.c (tsubst_decl): Use it.
* decl2.c (cp_build_parm_decl): New fn.
(build_artificial_parm): Use it.
(start_static_storage_duration_function): Likewise.
* decl.c (start_cleanup_fn, grokdeclarater): Likewise.
(grokparms): Don't mess with DECL_ARG_TYPE.
* typeck.c (convert_arguments): Use convert_for_arg_passing.
* cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
Define.
* cp-tree.h: Declare new fns.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55781 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/cp/call.c | 58 | ||||
-rw-r--r-- | gcc/cp/cp-lang.c | 3 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 19 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 29 | ||||
-rw-r--r-- | gcc/cp/init.c | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 9 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 6 | ||||
-rw-r--r-- | gcc/function.c | 9 |
11 files changed, 118 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 18e8f1cdd15..138d317e41f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-07-26 Jason Merrill <jason@redhat.com> + + * function.c (assign_parms): Handle frontend-directed pass by + invisible reference. + 2002-07-26 Neil Booth <neil@daikokuya.co.uk> * doc/cppopts.texi: Update. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8fd963b3ead..8fc09b11d22 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,21 @@ +2002-07-26 Jason Merrill <jason@redhat.com> + + * call.c (build_over_call): Likewise. + (cp_convert_parm_for_inlining): New fn. + (convert_for_arg_passing): New fn. + (convert_default_arg, build_over_call): Use it. + (type_passed_as): New fn. + * pt.c (tsubst_decl): Use it. + * decl2.c (cp_build_parm_decl): New fn. + (build_artificial_parm): Use it. + (start_static_storage_duration_function): Likewise. + * decl.c (start_cleanup_fn, grokdeclarater): Likewise. + (grokparms): Don't mess with DECL_ARG_TYPE. + * typeck.c (convert_arguments): Use convert_for_arg_passing. + * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): + Define. + * cp-tree.h: Declare new fns. + 2002-07-26 Neil Booth <neil@daikokuya.co.uk> * cp-tree.h (flag_operator_names): Remove. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 141c7ac2537..1599d0b993f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4128,15 +4128,60 @@ convert_default_arg (type, arg, fn, parmnum) arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, "default argument", fn, parmnum); - if (PROMOTE_PROTOTYPES - && INTEGRAL_TYPE_P (type) - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - arg = default_conversion (arg); + arg = convert_for_arg_passing (type, arg); } return arg; } +/* Returns the type which will really be used for passing an argument of + type TYPE. */ + +tree +type_passed_as (type) + tree type; +{ + /* Pass classes with copy ctors by invisible reference. */ + if (TREE_ADDRESSABLE (type)) + type = build_reference_type (type); + else if (PROMOTE_PROTOTYPES + && INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + type = integer_type_node; + + return type; +} + +/* Actually perform the appropriate conversion. */ + +tree +convert_for_arg_passing (type, val) + tree type, val; +{ + /* Pass classes with copy ctors by invisible reference. */ + if (TREE_ADDRESSABLE (type)) + val = build1 (ADDR_EXPR, build_reference_type (type), val); + else if (PROMOTE_PROTOTYPES + && INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + val = default_conversion (val); + return val; +} + +/* Convert VALUE for assignment into inlined parameter PARM. */ + +tree +cp_convert_parm_for_inlining (parm, value, fn) + tree parm, value; + tree fn ATTRIBUTE_UNUSED; +{ + /* When inlining, we don't need to mess with invisible references, so + undo the ADDR_EXPR. */ + if (TREE_ADDRESSABLE (TREE_TYPE (parm))) + value = build_indirect_ref (value, NULL); + return value; +} + /* Subroutine of the various build_*_call functions. Overload resolution has chosen a winning candidate CAND; build up a CALL_EXPR accordingly. ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a @@ -4222,10 +4267,7 @@ build_over_call (cand, args, flags) val = convert_like_with_context (conv, TREE_VALUE (arg), fn, i - is_method); - if (PROMOTE_PROTOTYPES - && INTEGRAL_TYPE_P (type) - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - val = default_conversion (val); + val = convert_for_arg_passing (type, val); converted_args = tree_cons (NULL_TREE, val, converted_args); } diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index f482582c8c7..a44d4b6b8a1 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -120,6 +120,9 @@ static bool cxx_warn_unused_global_decl PARAMS ((tree)); #undef LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING #define LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING \ cp_copy_res_decl_for_inlining +#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING +#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \ + cp_convert_parm_for_inlining #undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P #define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p #undef LANG_HOOKS_TREE_INLINING_START_INLINING diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6a2bda39dab..ae88df2c8ce 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3679,6 +3679,9 @@ extern tree convert_default_arg PARAMS ((tree, tree, tree, int)) extern tree convert_arg_to_ellipsis PARAMS ((tree)); extern tree build_x_va_arg PARAMS ((tree, tree)); extern tree cxx_type_promotes_to PARAMS ((tree)); +extern tree type_passed_as PARAMS ((tree)); +extern tree convert_for_arg_passing PARAMS ((tree, tree)); +extern tree cp_convert_parm_for_inlining PARAMS ((tree, tree, tree)); extern int is_properly_derived_from PARAMS ((tree, tree)); extern tree initialize_reference PARAMS ((tree, tree)); extern tree strip_top_quals PARAMS ((tree)); @@ -3958,6 +3961,7 @@ extern void mark_used PARAMS ((tree)); extern tree handle_class_head (enum tag_types, tree, tree, tree, int, int *); extern tree lookup_arg_dependent PARAMS ((tree, tree, tree)); extern void finish_static_data_member_decl PARAMS ((tree, tree, tree, int)); +extern tree cp_build_parm_decl PARAMS ((tree, tree)); extern tree build_artificial_parm PARAMS ((tree, tree)); extern tree get_guard PARAMS ((tree)); extern tree get_guard_cond PARAMS ((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 337107baf62..14021a411d1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8518,9 +8518,8 @@ start_cleanup_fn () { tree parmdecl; - parmdecl = build_decl (PARM_DECL, NULL_TREE, ptr_type_node); + parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node); DECL_CONTEXT (parmdecl) = fndecl; - DECL_ARG_TYPE (parmdecl) = ptr_type_node; TREE_USED (parmdecl) = 1; DECL_ARGUMENTS (fndecl) = parmdecl; } @@ -11366,7 +11365,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args)) { - tree decl = build_decl (PARM_DECL, NULL_TREE, TREE_VALUE (args)); + tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args)); TREE_CHAIN (decl) = decls; decls = decl; @@ -11510,17 +11509,10 @@ friend declaration requires class-key, i.e. `friend %#T'", if (decl_context == PARM) { - decl = build_decl (PARM_DECL, declarator, type); + decl = cp_build_parm_decl (declarator, type); bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); - - /* Compute the type actually passed in the parmlist, - for the case where there is no prototype. - (For example, shorts and chars are passed as ints.) - When there is a prototype, this is overridden later. */ - - DECL_ARG_TYPE (decl) = type_promotes_to (type); } else if (decl_context == FIELD) { @@ -12206,11 +12198,6 @@ grokparms (first_parm) decl, ptr ? "pointer" : "reference", t); } - DECL_ARG_TYPE (decl) = TREE_TYPE (decl); - if (PROMOTE_PROTOTYPES - && INTEGRAL_TYPE_P (type) - && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (decl) = integer_type_node; if (!any_error && init) init = check_default_argument (decl, init); else diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 08fd777db39..0a2da36c5b0 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -795,6 +795,19 @@ grok_x_components (specs) finish_member_declaration (build_decl (FIELD_DECL, NULL_TREE, t)); } +/* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE + appropriately. */ + +tree +cp_build_parm_decl (name, type) + tree name; + tree type; +{ + tree parm = build_decl (PARM_DECL, name, type); + DECL_ARG_TYPE (parm) = type_passed_as (type); + return parm; +} + /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the indicated NAME. */ @@ -803,14 +816,11 @@ build_artificial_parm (name, type) tree name; tree type; { - tree parm; - - parm = build_decl (PARM_DECL, name, type); + tree parm = cp_build_parm_decl (name, type); DECL_ARTIFICIAL (parm) = 1; /* All our artificial parms are implicitly `const'; they cannot be assigned to. */ TREE_READONLY (parm) = 1; - DECL_ARG_TYPE (parm) = type; return parm; } @@ -2853,16 +2863,13 @@ start_static_storage_duration_function () VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl); /* Create the argument list. */ - initialize_p_decl = build_decl (PARM_DECL, - get_identifier (INITIALIZE_P_IDENTIFIER), - integer_type_node); + initialize_p_decl = cp_build_parm_decl + (get_identifier (INITIALIZE_P_IDENTIFIER), integer_type_node); DECL_CONTEXT (initialize_p_decl) = ssdf_decl; - DECL_ARG_TYPE (initialize_p_decl) = integer_type_node; TREE_USED (initialize_p_decl) = 1; - priority_decl = build_decl (PARM_DECL, get_identifier (PRIORITY_IDENTIFIER), - integer_type_node); + priority_decl = cp_build_parm_decl + (get_identifier (PRIORITY_IDENTIFIER), integer_type_node); DECL_CONTEXT (priority_decl) = ssdf_decl; - DECL_ARG_TYPE (priority_decl) = integer_type_node; TREE_USED (priority_decl) = 1; TREE_CHAIN (initialize_p_decl) = priority_decl; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 31c1505afa6..3b99c95ee3e 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2494,7 +2494,9 @@ build_new_1 (exp) constructor, that would fix the nesting problem and we could do away with this complexity. But that would complicate other things; in particular, it would make it difficult to bail out - if the allocation function returns null. */ + if the allocation function returns null. Er, no, it wouldn't; + we just don't run the constructor. The standard says it's + unspecified whether or not the args are evaluated. */ if (cleanup) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 565b75fdfed..ca8b2c2225a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6012,7 +6012,7 @@ tsubst_decl (t, args, type, complain) r = copy_node (t); if (DECL_TEMPLATE_PARM_P (t)) SET_DECL_TEMPLATE_PARM_P (r); - + TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); @@ -6023,10 +6023,9 @@ tsubst_decl (t, args, type, complain) complain, in_decl); DECL_CONTEXT (r) = NULL_TREE; - if (!DECL_TEMPLATE_PARM_P (r) && PROMOTE_PROTOTYPES - && INTEGRAL_TYPE_P (type) - && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (r) = integer_type_node; + + if (!DECL_TEMPLATE_PARM_P (r)) + DECL_ARG_TYPE (r) = type_passed_as (type); if (TREE_CHAIN (t)) TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, complain, TREE_CHAIN (t)); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e333d3e5877..07199d60b41 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3112,11 +3112,7 @@ convert_arguments (typelist, values, fndecl, flags) parmval = convert_for_initialization (NULL_TREE, type, val, flags, "argument passing", fndecl, i); - if (PROMOTE_PROTOTYPES - && INTEGRAL_TYPE_P (type) - && (TYPE_PRECISION (type) - < TYPE_PRECISION (integer_type_node))) - parmval = default_conversion (parmval); + parmval = convert_for_arg_passing (type, parmval); } if (parmval == error_mark_node) diff --git a/gcc/function.c b/gcc/function.c index 2a59d59459b..98c19658708 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4425,6 +4425,15 @@ assign_parms (fndecl) passed_pointer = 1; passed_mode = nominal_mode = Pmode; } + /* See if the frontend wants to pass this by invisible reference. */ + else if (passed_type != nominal_type + && POINTER_TYPE_P (passed_type) + && TREE_TYPE (passed_type) == nominal_type) + { + nominal_type = passed_type; + passed_pointer = 1; + passed_mode = nominal_mode = Pmode; + } promoted_mode = passed_mode; |