[PATCH,c++] introduce {class,type}_of_this functions

2011-05-06 Thread Nathan Froyd
The patch below introduces simple accessors for getting at the class or
the type of the `this' parameter.  It hides a couple of TYPE_ARG_TYPES
usages and makes the code slightly more obvious, I think.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

gcc/cp/
* cp-tree.h (type_of_this, class_of_this): New functions.
* call.c (standard_conversion): Call class_of_this.
* cxx-pretty-print.c (pp_cxx_implicit_parameter_type): Likewise.
(pp_cxx_direct_abstract_declarator): Likewise.
* decl2.c (change_return_type): Likewise.
(cp_reconstruct_complex_type): Likewise.
* error.c (dump_type_suffix, dump_function_decl): Likewise.
* mangle.c (write_function_type): Likewise.
* pt.c (unify): Likewise.
* typeck.c (merge_types, type_memfn_quals): Likewise.
* decl.c (build_this_parm): Call type_of_this.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f5bd521..7ad9279 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1146,8 +1146,8 @@ standard_conversion (tree to, tree from, tree expr, bool 
c_cast_p,
 {
   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)));
+  tree fbase = class_of_this (fromfn);
+  tree tbase = class_of_this (tofn);
 
   if (!DERIVED_FROM_P (fbase, tbase)
  || !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9d13393..d410e02 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4616,6 +4616,24 @@ struct GTY(()) tinst_level {
   bool in_system_header_p;
 };
 
+/* Return the type of the `this' parameter of FNTYPE.  */
+
+static inline tree
+type_of_this (const_tree fntype)
+{
+  function_args_iterator iter;
+  function_args_iter_init (iter, fntype);
+  return function_args_iter_cond (iter);
+}
+
+/* Return the class of the `this' parameter of FNTYPE.  */
+
+static inline tree
+class_of_this (const_tree fntype)
+{
+  return TREE_TYPE (type_of_this (fntype));
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index bd0381b..eeb6d07 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -1363,7 +1363,7 @@ pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
 static inline tree
 pp_cxx_implicit_parameter_type (tree mf)
 {
-  return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf;
+  return class_of_this (TREE_TYPE (mf));
 }
 
 /*
@@ -1652,8 +1652,7 @@ pp_cxx_direct_abstract_declarator (cxx_pretty_printer 
*pp, tree t)
   if (TREE_CODE (t) == METHOD_TYPE)
{
  pp_base (pp)-padding = pp_before;
- pp_cxx_cv_qualifier_seq
-   (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t;
+ pp_cxx_cv_qualifier_seq (pp, class_of_this (t));
}
   pp_cxx_exception_specification (pp, t);
   break;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3622c2c..962dd22 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6924,7 +6924,7 @@ build_this_parm (tree type, cp_cv_quals quals)
   tree parm;
   cp_cv_quals this_quals;
 
-  this_type = TREE_VALUE (TYPE_ARG_TYPES (type));
+  this_type = type_of_this (type);
   /* The `this' parameter is implicitly `const'; it cannot be
  assigned to.  */
   this_quals = (quals  TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index ef8de31..02d9fd9 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -161,8 +161,7 @@ change_return_type (tree new_ret, tree fntype)
 }
   else
 newtype = build_method_type_directly
-  (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
-   new_ret, TREE_CHAIN (args));
+  (class_of_this (fntype), new_ret, TREE_CHAIN (args));
   if (raises)
 newtype = build_exception_variant (newtype, raises);
   if (attrs)
@@ -1249,8 +1248,7 @@ cp_reconstruct_complex_type (tree type, tree bottom)
 so we must compensate by getting rid of it.  */
   outer
= build_method_type_directly
-   (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))),
-inner,
+   (class_of_this (type), inner,
 TREE_CHAIN (TYPE_ARG_TYPES (type)));
 }
   else if (TREE_CODE (type) == OFFSET_TYPE)
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index fce7403..b364824 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -794,8 +794,7 @@ dump_type_suffix (tree t, int flags)
dump_parameters (arg, flags  ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
 
if (TREE_CODE (t) == METHOD_TYPE)
- pp_cxx_cv_qualifier_seq
-   (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t;
+ pp_cxx_cv_qualifier_seq (cxx_pp, class_of_this (t));
else
  

Re: [PATCH,c++] introduce {class,type}_of_this functions

2011-05-06 Thread Jason Merrill

On 05/06/2011 07:49 AM, Nathan Froyd wrote:

The patch below introduces simple accessors for getting at the class or
the type of the `this' parameter.  It hides a couple of TYPE_ARG_TYPES
usages and makes the code slightly more obvious, I think.


Hmm, when I first read the names I expected them to refer to the 'this' 
in the current function.  I think adding _parm to the end of the names 
would help.


The type_ function should also have an assert that fntype is a METHOD_TYPE.

OK with those changes.

Jason