Message ID | 20110523135324.GA13949@nightcrawler |
---|---|
State | New |
Headers | show |
On Mon, May 23, 2011 at 3:53 PM, Nathan Froyd <froydnj@codesourcery.com> wrote: > Various places in the compiler grab TYPE_ARG_TYPES and grovel through it > when what they're really trying to do is index into the list of argument > types. The patch below introduces nth_arg_type for such situatiosn and > changes a hodgepodge of places to use it. You could, of course, use > function_args_iterator, but I think this approach is somewhat clearer. > > Tested on x86_64-unknown-linux-gnu. OK to commit? See below > -Nathan > > gcc/ > * tree.h (nth_arg_type): Declare. > * tree.c (nth_arg_type): Define. > * dbxout.c (dbxout_type_method_1): Call it. > * dwarf2out.c (decl_class_context): Likewise. > * tree-ssa-math-opts.c (execute_optimize_bswap): Likewise. > > gcc/cp/ > * cp-tree.h (DECL_CONST_MEMFUNC_P): Call nth_arg_type. > (DECL_VOLATILE_MEMFUNC_P, type_of_this_parm): Likewise. > > gcc/fortran/ > * trans-decl.c (create_main_function): Call nth_arg_type. > > gcc/objc/ > * objc-next-runtime-abi-01.c (next_sjlj_build_enter_and_setjmp): > Call nth_arg_type. > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index ada01fb..53848c3 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -2256,15 +2256,13 @@ struct GTY((variable_size)) lang_decl { > has `this' as const X *const. */ > #define DECL_CONST_MEMFUNC_P(NODE) \ > (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ > - && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE \ > - (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) > + && CP_TYPE_CONST_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0)))) > > /* Nonzero for FUNCTION_DECL means that this member function > has `this' as volatile X *const. */ > #define DECL_VOLATILE_MEMFUNC_P(NODE) \ > (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ > - && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE \ > - (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) > + && CP_TYPE_VOLATILE_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0)))) > > /* Nonzero for a DECL means that this member is a non-static member. */ > #define DECL_NONSTATIC_MEMBER_P(NODE) \ > @@ -4660,10 +4658,8 @@ struct GTY(()) tinst_level { > static inline tree > type_of_this_parm (const_tree fntype) > { > - function_args_iterator iter; > gcc_assert (TREE_CODE (fntype) == METHOD_TYPE); > - function_args_iter_init (&iter, fntype); > - return function_args_iter_cond (&iter); > + return nth_arg_type (fntype, 0); > } > > /* Return the class of the `this' parameter of FNTYPE. */ > diff --git a/gcc/dbxout.c b/gcc/dbxout.c > index 3190803..f5e985e 100644 > --- a/gcc/dbxout.c > +++ b/gcc/dbxout.c > @@ -1585,7 +1585,7 @@ dbxout_type_method_1 (tree decl) > c2 = '?'; > else /* it's a METHOD_TYPE. */ > { > - tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))); > + tree firstarg = nth_arg_type (TREE_TYPE (decl), 0); > /* A for normal functions. > B for `const' member functions. > C for `volatile' member functions. > diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c > index b85a55e..d95c3f4 100644 > --- a/gcc/dwarf2out.c > +++ b/gcc/dwarf2out.c > @@ -7484,7 +7484,7 @@ decl_class_context (tree decl) > context = DECL_CONTEXT (decl); > else > context = TYPE_MAIN_VARIANT > - (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))))); > + (TREE_TYPE (nth_arg_type (TREE_TYPE (decl), 0))); > > if (context && !TYPE_P (context)) > context = NULL_TREE; > diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c > index d771484..19d3e03 100644 > --- a/gcc/fortran/trans-decl.c > +++ b/gcc/fortran/trans-decl.c > @@ -4518,7 +4518,7 @@ create_main_function (tree fndecl) > { > tree old_context; > tree ftn_main; > - tree tmp, decl, result_decl, argc, argv, typelist, arglist; > + tree tmp, decl, result_decl, argc, argv, fntype, arglist; > stmtblock_t body; > > old_context = current_function_decl; > @@ -4559,21 +4559,20 @@ create_main_function (tree fndecl) > /* Get the arguments. */ > > arglist = NULL_TREE; > - typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main)); > + fntype = TREE_TYPE (ftn_main); > > - tmp = TREE_VALUE (typelist); > + tmp = nth_arg_type (fntype, 0); > argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp); > DECL_CONTEXT (argc) = ftn_main; > - DECL_ARG_TYPE (argc) = TREE_VALUE (typelist); > + DECL_ARG_TYPE (argc) = tmp; > TREE_READONLY (argc) = 1; > gfc_finish_decl (argc); > arglist = chainon (arglist, argc); > > - typelist = TREE_CHAIN (typelist); > - tmp = TREE_VALUE (typelist); > + tmp = nth_arg_type (fntype, 1); > argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp); > DECL_CONTEXT (argv) = ftn_main; > - DECL_ARG_TYPE (argv) = TREE_VALUE (typelist); > + DECL_ARG_TYPE (argv) = tmp; > TREE_READONLY (argv) = 1; > DECL_BY_REFERENCE (argv) = 1; > gfc_finish_decl (argv); > diff --git a/gcc/objc/objc-next-runtime-abi-01.c b/gcc/objc/objc-next-runtime-abi-01.c > index d5b795f..37b2b10 100644 > --- a/gcc/objc/objc-next-runtime-abi-01.c > +++ b/gcc/objc/objc-next-runtime-abi-01.c > @@ -2584,7 +2584,7 @@ next_sjlj_build_enter_and_setjmp (struct objc_try_context **ctcp) > #ifdef OBJCPLUS > /* Convert _setjmp argument to type that is expected. */ > if (prototype_p (TREE_TYPE (objc_setjmp_decl))) > - t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t); > + t = convert (nth_arg_type (TREE_TYPE (objc_setjmp_decl), 0), t); > else > t = convert (ptr_type_node, t); > #else > diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c > index b9f631e..5e6feb1 100644 > --- a/gcc/tree-ssa-math-opts.c > +++ b/gcc/tree-ssa-math-opts.c > @@ -1181,13 +1181,13 @@ execute_optimize_bswap (void) > if (bswap32_p) > { > tree fndecl = built_in_decls[BUILT_IN_BSWAP32]; > - bswap32_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); > + bswap32_type = nth_arg_type (TREE_TYPE (fndecl), 0); > } > > if (bswap64_p) > { > tree fndecl = built_in_decls[BUILT_IN_BSWAP64]; > - bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); > + bswap64_type = nth_arg_type (TREE_TYPE (fndecl), 0); > } > > memset (&bswap_stats, 0, sizeof (bswap_stats)); > diff --git a/gcc/tree.c b/gcc/tree.c > index 3357d84..2925e13 100644 > --- a/gcc/tree.c > +++ b/gcc/tree.c > @@ -10704,6 +10704,29 @@ prototype_p (tree fntype) > return (t != NULL_TREE); > } > > +/* Return the Nth argument type from FNTYPE. */ > + > +tree > +nth_arg_type (const_tree fntype, int n) > +{ > + function_args_iterator iter; > + tree t; > + int i; > + > + gcc_assert (fntype != NULL_TREE); > + gcc_assert (n >= 0); Please merge the asserts and do s/gcc_assert/gcc_checking_assert/ And if n should be >= 0 why not pass it in as unsigned? The patch is ok with both changes. Thanks, Richard. > + i = 0; > + FOREACH_FUNCTION_ARGS (fntype, t, iter) > + { > + if (n == i) > + return t; > + i++; > + } > + > + gcc_unreachable (); > +} > + > /* If BLOCK is inlined from an __attribute__((__artificial__)) > routine, return pointer to location from where it has been > called. */ > diff --git a/gcc/tree.h b/gcc/tree.h > index 805fe06..9788071 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -5074,6 +5074,7 @@ extern tree create_artificial_label (location_t); > extern const char *get_name (tree); > extern bool stdarg_p (const_tree); > extern bool prototype_p (tree); > +extern tree nth_arg_type (const_tree, int); > extern bool is_typedef_decl (tree x); > extern bool typedef_variant_p (tree); > extern bool auto_var_in_fn_p (const_tree, const_tree); >
On 05/23/2011 10:05 AM, Richard Guenther wrote: > On Mon, May 23, 2011 at 3:53 PM, Nathan Froyd <froydnj@codesourcery.com> wrote: >> +/* Return the Nth argument type from FNTYPE. */ >> + >> +tree >> +nth_arg_type (const_tree fntype, int n) >> +{ >> + function_args_iterator iter; >> + tree t; >> + int i; >> + >> + gcc_assert (fntype != NULL_TREE); >> + gcc_assert (n >= 0); > > Please merge the asserts and do s/gcc_assert/gcc_checking_assert/ Ack. > And if n should be >= 0 why not pass it in as unsigned? Consistency with all the other interfaces where n is logically unsigned but passed in as int? > The patch is ok with both changes. Thanks for the review. -Nathan
On 05/23/2011 09:53 AM, Nathan Froyd wrote: > #define DECL_CONST_MEMFUNC_P(NODE) \ > (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ > -&& CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE \ > - (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) > +&& CP_TYPE_CONST_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0)))) This should use class_of_this_parm. > /* Nonzero for FUNCTION_DECL means that this member function > has `this' as volatile X *const. */ > #define DECL_VOLATILE_MEMFUNC_P(NODE) \ > (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ > -&& CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE \ > - (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) > +&& CP_TYPE_VOLATILE_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0)))) As should this. Jason
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ada01fb..53848c3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2256,15 +2256,13 @@ struct GTY((variable_size)) lang_decl { has `this' as const X *const. */ #define DECL_CONST_MEMFUNC_P(NODE) \ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ - && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE \ - (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) + && CP_TYPE_CONST_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0)))) /* Nonzero for FUNCTION_DECL means that this member function has `this' as volatile X *const. */ #define DECL_VOLATILE_MEMFUNC_P(NODE) \ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ - && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE \ - (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) + && CP_TYPE_VOLATILE_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0)))) /* Nonzero for a DECL means that this member is a non-static member. */ #define DECL_NONSTATIC_MEMBER_P(NODE) \ @@ -4660,10 +4658,8 @@ struct GTY(()) tinst_level { static inline tree type_of_this_parm (const_tree fntype) { - function_args_iterator iter; gcc_assert (TREE_CODE (fntype) == METHOD_TYPE); - function_args_iter_init (&iter, fntype); - return function_args_iter_cond (&iter); + return nth_arg_type (fntype, 0); } /* Return the class of the `this' parameter of FNTYPE. */ diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 3190803..f5e985e 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -1585,7 +1585,7 @@ dbxout_type_method_1 (tree decl) c2 = '?'; else /* it's a METHOD_TYPE. */ { - tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))); + tree firstarg = nth_arg_type (TREE_TYPE (decl), 0); /* A for normal functions. B for `const' member functions. C for `volatile' member functions. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index b85a55e..d95c3f4 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -7484,7 +7484,7 @@ decl_class_context (tree decl) context = DECL_CONTEXT (decl); else context = TYPE_MAIN_VARIANT - (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))))); + (TREE_TYPE (nth_arg_type (TREE_TYPE (decl), 0))); if (context && !TYPE_P (context)) context = NULL_TREE; diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index d771484..19d3e03 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -4518,7 +4518,7 @@ create_main_function (tree fndecl) { tree old_context; tree ftn_main; - tree tmp, decl, result_decl, argc, argv, typelist, arglist; + tree tmp, decl, result_decl, argc, argv, fntype, arglist; stmtblock_t body; old_context = current_function_decl; @@ -4559,21 +4559,20 @@ create_main_function (tree fndecl) /* Get the arguments. */ arglist = NULL_TREE; - typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main)); + fntype = TREE_TYPE (ftn_main); - tmp = TREE_VALUE (typelist); + tmp = nth_arg_type (fntype, 0); argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp); DECL_CONTEXT (argc) = ftn_main; - DECL_ARG_TYPE (argc) = TREE_VALUE (typelist); + DECL_ARG_TYPE (argc) = tmp; TREE_READONLY (argc) = 1; gfc_finish_decl (argc); arglist = chainon (arglist, argc); - typelist = TREE_CHAIN (typelist); - tmp = TREE_VALUE (typelist); + tmp = nth_arg_type (fntype, 1); argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp); DECL_CONTEXT (argv) = ftn_main; - DECL_ARG_TYPE (argv) = TREE_VALUE (typelist); + DECL_ARG_TYPE (argv) = tmp; TREE_READONLY (argv) = 1; DECL_BY_REFERENCE (argv) = 1; gfc_finish_decl (argv); diff --git a/gcc/objc/objc-next-runtime-abi-01.c b/gcc/objc/objc-next-runtime-abi-01.c index d5b795f..37b2b10 100644 --- a/gcc/objc/objc-next-runtime-abi-01.c +++ b/gcc/objc/objc-next-runtime-abi-01.c @@ -2584,7 +2584,7 @@ next_sjlj_build_enter_and_setjmp (struct objc_try_context **ctcp) #ifdef OBJCPLUS /* Convert _setjmp argument to type that is expected. */ if (prototype_p (TREE_TYPE (objc_setjmp_decl))) - t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t); + t = convert (nth_arg_type (TREE_TYPE (objc_setjmp_decl), 0), t); else t = convert (ptr_type_node, t); #else diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index b9f631e..5e6feb1 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1181,13 +1181,13 @@ execute_optimize_bswap (void) if (bswap32_p) { tree fndecl = built_in_decls[BUILT_IN_BSWAP32]; - bswap32_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); + bswap32_type = nth_arg_type (TREE_TYPE (fndecl), 0); } if (bswap64_p) { tree fndecl = built_in_decls[BUILT_IN_BSWAP64]; - bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); + bswap64_type = nth_arg_type (TREE_TYPE (fndecl), 0); } memset (&bswap_stats, 0, sizeof (bswap_stats)); diff --git a/gcc/tree.c b/gcc/tree.c index 3357d84..2925e13 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10704,6 +10704,29 @@ prototype_p (tree fntype) return (t != NULL_TREE); } +/* Return the Nth argument type from FNTYPE. */ + +tree +nth_arg_type (const_tree fntype, int n) +{ + function_args_iterator iter; + tree t; + int i; + + gcc_assert (fntype != NULL_TREE); + gcc_assert (n >= 0); + + i = 0; + FOREACH_FUNCTION_ARGS (fntype, t, iter) + { + if (n == i) + return t; + i++; + } + + gcc_unreachable (); +} + /* If BLOCK is inlined from an __attribute__((__artificial__)) routine, return pointer to location from where it has been called. */ diff --git a/gcc/tree.h b/gcc/tree.h index 805fe06..9788071 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5074,6 +5074,7 @@ extern tree create_artificial_label (location_t); extern const char *get_name (tree); extern bool stdarg_p (const_tree); extern bool prototype_p (tree); +extern tree nth_arg_type (const_tree, int); extern bool is_typedef_decl (tree x); extern bool typedef_variant_p (tree); extern bool auto_var_in_fn_p (const_tree, const_tree);