Commit e2537f2c by Mark Mitchell Committed by Mark Mitchell

re PR c++/26912 (friend const member function specialization fails to compile)

	PR c++/26912
	* cp-tree.h (build_this_parm): Declare.
	(grok_method_quals): Remove.
	(build_memfn_type): Declare.
	(build_artificial_parm): Declare.
	(do_friend): Remove quals parameter.
	* decl.c (build_this_parm): New function.
	(grokfndecl): Use it.  Do not pass quals to grokclassfn.
	(grokdeclarator): Rename quals to memfn_quals.  Avoid allocating
	unnecessary TYPE_DECLs.  Correct qualification of member function
	types.  Tidy.
	* method.c (implicitly_declare_fn): Use build_this_parm.
	* friend.c (do_friend): Remove quals parameter.
	* decl2.c (grok_method_quals): Remove.
	(build_memfn_type): New function.
	(build_artificial_parm): Give it external linkage.
	(grokclassfn): Remove quals parameter.  Do not build "this"
	PARM_DECL here.
	PR c++/26912
	* g++.dg/template/friend41.C: New test.

From-SVN: r113213
parent d24b23bb
2006-04-23 Mark Mitchell <mark@codesourcery.com>
PR c++/26912
* cp-tree.h (build_this_parm): Declare.
(grok_method_quals): Remove.
(build_memfn_type): Declare.
(build_artificial_parm): Declare.
(do_friend): Remove quals parameter.
* decl.c (build_this_parm): New function.
(grokfndecl): Use it. Do not pass quals to grokclassfn.
(grokdeclarator): Rename quals to memfn_quals. Avoid allocating
unnecessary TYPE_DECLs. Correct qualification of member function
types. Tidy.
* method.c (implicitly_declare_fn): Use build_this_parm.
* friend.c (do_friend): Remove quals parameter.
* decl2.c (grok_method_quals): Remove.
(build_memfn_type): New function.
(build_artificial_parm): Give it external linkage.
(grokclassfn): Remove quals parameter. Do not build "this"
PARM_DECL here.
PR c++/26534
* cp-tree.h (is_bitfield_expr_with_lowered_type): New function.
* typeck.c (is_bitfield_expr_with_lowered_type): New function.
......
......@@ -3842,6 +3842,7 @@ extern int cp_complete_array_type (tree *, tree, bool);
extern tree build_ptrmemfunc_type (tree);
extern tree build_ptrmem_type (tree, tree);
/* the grokdeclarator prototype is in decl.h */
extern tree build_this_parm (tree, cp_cv_quals);
extern int copy_fn_p (tree);
extern tree get_scope_of_declarator (const cp_declarator *);
extern void grok_special_member_properties (tree);
......@@ -3899,12 +3900,11 @@ extern bool have_extern_spec;
/* in decl2.c */
extern bool check_java_method (tree);
extern cp_cv_quals grok_method_quals (tree, tree, cp_cv_quals);
extern tree build_memfn_type (tree, tree, cp_cv_quals);
extern void maybe_retrofit_in_chrg (tree);
extern void maybe_make_one_only (tree);
extern void grokclassfn (tree, tree,
enum overload_flags,
cp_cv_quals);
enum overload_flags);
extern tree grok_array_decl (tree, tree);
extern tree delete_sanity (tree, tree, bool, int);
extern tree check_classfn (tree, tree, tree);
......@@ -3934,6 +3934,7 @@ extern tree cxx_callgraph_analyze_expr (tree *, int *, tree);
extern void mark_needed (tree);
extern bool decl_needed_p (tree);
extern void note_vague_linkage_fn (tree);
extern tree build_artificial_parm (tree, tree);
/* in error.c */
extern void init_error (void);
......@@ -3966,7 +3967,7 @@ extern tree cplus_expand_constant (tree);
extern int is_friend (tree, tree);
extern void make_friend_class (tree, tree, bool);
extern void add_friend (tree, tree, bool);
extern tree do_friend (tree, tree, tree, tree, enum overload_flags, cp_cv_quals, bool);
extern tree do_friend (tree, tree, tree, tree, enum overload_flags, bool);
/* in init.c */
extern tree expand_member_init (tree);
......
......@@ -103,33 +103,28 @@ tree static_ctors;
tree static_dtors;
/* Incorporate `const' and `volatile' qualifiers for member functions.
FUNCTION is a TYPE_DECL or a FUNCTION_DECL.
QUALS is a list of qualifiers. Returns any explicit
top-level qualifiers of the method's this pointer, anything other than
TYPE_UNQUALIFIED will be an extension. */
int
grok_method_quals (tree ctype, tree function, cp_cv_quals quals)
/* Return a member function type (a METHOD_TYPE), given FNTYPE (a
FUNCTION_TYPE), CTYPE (class type), and QUALS (the cv-qualifiers
that apply to the function). */
tree
build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
{
tree fntype = TREE_TYPE (function);
tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
int type_quals = TYPE_UNQUALIFIED;
int this_quals = TYPE_UNQUALIFIED;
tree raises;
int type_quals;
type_quals = quals & ~TYPE_QUAL_RESTRICT;
this_quals = quals & TYPE_QUAL_RESTRICT;
ctype = cp_build_qualified_type (ctype, type_quals);
fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
(TREE_CODE (fntype) == METHOD_TYPE
? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
: TYPE_ARG_TYPES (fntype)));
raises = TYPE_RAISES_EXCEPTIONS (fntype);
if (raises)
fntype = build_exception_variant (fntype, raises);
TREE_TYPE (function) = fntype;
return this_quals;
return fntype;
}
/* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE
......@@ -149,7 +144,7 @@ cp_build_parm_decl (tree name, tree type)
/* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
indicated NAME. */
static tree
tree
build_artificial_parm (tree name, tree type)
{
tree parm = cp_build_parm_decl (name, type);
......@@ -257,11 +252,9 @@ maybe_retrofit_in_chrg (tree fn)
QUALS are the qualifiers for the this pointer. */
void
grokclassfn (tree ctype, tree function, enum overload_flags flags,
cp_cv_quals quals)
grokclassfn (tree ctype, tree function, enum overload_flags flags)
{
tree fn_name = DECL_NAME (function);
cp_cv_quals this_quals = TYPE_UNQUALIFIED;
/* Even within an `extern "C"' block, members get C++ linkage. See
[dcl.link] for details. */
......@@ -274,28 +267,6 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags,
DECL_NAME (function) = fn_name;
}
if (quals)
this_quals = grok_method_quals (ctype, function, quals);
if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
{
/* Must add the class instance variable up front. */
/* Right now we just make this a pointer. But later
we may wish to make it special. */
tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (function)));
tree qual_type;
tree parm;
/* The `this' parameter is implicitly `const'; it cannot be
assigned to. */
this_quals |= TYPE_QUAL_CONST;
qual_type = cp_build_qualified_type (type, this_quals);
parm = build_artificial_parm (this_identifier, qual_type);
cp_apply_type_quals_to_decl (this_quals, parm);
TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
DECL_ARGUMENTS (function) = parm;
}
DECL_CONTEXT (function) = ctype;
if (flags == DTOR_FLAG)
......
......@@ -399,15 +399,11 @@ make_friend_class (tree type, tree friend_type, bool complain)
DECL is the FUNCTION_DECL that the friend is.
FLAGS is just used for `grokclassfn'.
QUALS say what special qualifies should apply to the object
pointed to by `this'. */
FLAGS is just used for `grokclassfn'. */
tree
do_friend (tree ctype, tree declarator, tree decl,
tree attrlist, enum overload_flags flags,
cp_cv_quals quals,
bool funcdef_flag)
{
/* Every decl that gets here is a friend of something. */
......@@ -456,8 +452,7 @@ do_friend (tree ctype, tree declarator, tree decl,
if (flags == NO_SPECIAL && declarator == cname)
DECL_CONSTRUCTOR_P (decl) = 1;
/* This will set up DECL_ARGUMENTS for us. */
grokclassfn (ctype, decl, flags, quals);
grokclassfn (ctype, decl, flags);
if (friend_depth)
{
......
......@@ -978,6 +978,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
tree fn_type;
tree raises = empty_except_spec;
tree rhs_parm_type = NULL_TREE;
tree this_parm;
tree name;
HOST_WIDE_INT saved_processing_template_decl;
......@@ -1067,8 +1068,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
}
/* Create the argument list. The call to "grokclassfn" will add the
"this" parameter and any other implicit parameters. */
/* Create the explicit arguments. */
if (rhs_parm_type)
{
/* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
......@@ -1077,9 +1077,12 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_ARGUMENTS (fn) = cp_build_parm_decl (NULL_TREE, rhs_parm_type);
TREE_READONLY (DECL_ARGUMENTS (fn)) = 1;
}
/* Add the "this" parameter. */
this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
TREE_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
DECL_ARGUMENTS (fn) = this_parm;
grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL,
TYPE_UNQUALIFIED);
grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
grok_special_member_properties (fn);
set_linkage_according_to_type (type, fn);
rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
......
2006-04-23 Mark Mitchell <mark@codesourcery.com>
PR c++/26912
* g++.dg/template/friend41.C: New test.
2006-04-23 David Edelsohn <edelsohn@gnu.org>
* g++.dg/opt/pr15551.C: Include cstdio.
// PR c++/26912
struct Foo {
template<class T> int func() const;
};
class Bar {
friend int Foo::func<int>() const;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment