summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/class.c83
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/decl.c26
-rw-r--r--gcc/cp/lex.c11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/shadow1.C19
6 files changed, 97 insertions, 70 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b994d6e42e5..6a05c558766 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+1998-12-16 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (resolve_address_of_overloaded_function): Do conversion
+ to correct type here, rather than ...
+ (instantiate_type): Here.
+
+ * cp-tree.h (DECL_TEMPLATE_PARM_P): New macro.
+ (DECL_TEMPLATE_TEMPLATE_PARM_P): Use it.
+ (decl_template_parm_p): Remove.
+ * decl.c (pushdecl): Don't set DECL_CONTEXT for a template
+ paramter.
+ * lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P.
+ (push_inline_template_parms_recursive): Set it.
+ (decl_template_parm_p): Remove.
+ (check_template_shadow): Use DECL_TEMPLATE_PARM_P.
+ (process_template_parm): Set it.
+
Wed Dec 16 16:33:58 1998 Dave Brolley <brolley@cygnus.com>
* lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e3f4544481b..694ac0b22ba 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5025,6 +5025,7 @@ resolve_address_of_overloaded_function (target_type,
are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
interoperability with most_specialized_instantiation. */
tree matches = NULL_TREE;
+ tree fn;
/* By the time we get here, we should be seeing only real
pointer-to-member types, not the internal POINTER_TYPE to
@@ -5212,8 +5213,20 @@ resolve_address_of_overloaded_function (target_type,
return error_mark_node;
}
- /* Good, exactly one match. */
- return TREE_PURPOSE (matches);
+ /* Good, exactly one match. Now, convert it to the correct type. */
+ fn = TREE_PURPOSE (matches);
+
+ if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
+ return build_unary_op (ADDR_EXPR, fn, 0);
+ else
+ {
+ /* The target must be a REFERENCE_TYPE. Above, build_unary_op
+ will mark the function as addressed, but here we must do it
+ explicitly. */
+ mark_addressable (fn);
+
+ return fn;
+ }
}
/* This function will instantiate the type of the expression given in
@@ -5291,33 +5304,31 @@ instantiate_type (lhstype, rhs, complain)
case COMPONENT_REF:
{
tree field = TREE_OPERAND (rhs, 1);
- if (TREE_CODE (field) == TREE_LIST)
- {
- tree function = instantiate_type (lhstype, field, complain);
- if (function == error_mark_node)
- return error_mark_node;
- my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185);
+ tree r;
+
+ my_friendly_assert (TREE_CODE (field) == TREE_LIST, 0);
- if (! DECL_STATIC_FUNCTION_P (function))
+ r = instantiate_type (lhstype, field, complain);
+
+ if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
+ {
+ tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
+ tree fn = TREE_VALUE (field);
+ if (TREE_CODE (fn) == OVERLOAD)
+ fn = OVL_FUNCTION (fn);
+ if (TREE_CODE (fn) == FUNCTION_DECL)
{
- tree t = TREE_TYPE (TREE_OPERAND (rhs, 0));
- if (TYPE_MAIN_VARIANT (t) == current_class_type)
- t = constructor_name (t);
-
- cp_error ("object-dependent reference to `%D' can only be used in a call",
- function);
- cp_error (" to form a pointer to member function, say `&%T::%D'",
- t, DECL_NAME (function));
- return error_mark_node;
+ cp_error ("object-dependent reference `%E' can only be used in a call",
+ DECL_NAME (fn));
+ cp_error (" to form a pointer to member function, say `&%T::%E'",
+ t, DECL_NAME (fn));
}
-
- mark_used (function);
- return function;
+ else
+ cp_error ("object-dependent reference can only be used in a call");
+ return error_mark_node;
}
-
- /* I could not trigger this code. MvL */
- my_friendly_abort (980326);
- return rhs;
+
+ return r;
}
case OFFSET_REF:
@@ -5469,27 +5480,7 @@ instantiate_type (lhstype, rhs, complain)
return rhs;
case ADDR_EXPR:
- {
- tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
- if (fn == error_mark_node)
- return error_mark_node;
- mark_addressable (fn);
- TREE_OPERAND (rhs, 0) = fn;
- TREE_CONSTANT (rhs) = staticp (fn);
- if (TYPE_PTRMEMFUNC_P (lhstype))
- {
- /* We must use the POINTER_TYPE to METHOD_TYPE on RHS here
- so that build_ptrmemfunc knows that RHS we have is not
- already a pointer-to-member constant. Instead, it is
- just a ADDR_EXPR over a FUNCTION_DECL. */
- TREE_TYPE (rhs) = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
- rhs = build_ptrmemfunc (TREE_TYPE (rhs), rhs, 0);
- }
- else
- /* Here, things our simple; we have exactly what we need. */
- TREE_TYPE (rhs) = lhstype;
- }
- return rhs;
+ return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
case ENTRY_VALUE_EXPR:
my_friendly_abort (184);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 395b24a2b40..cb55b0635da 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA. */
Usage of DECL_LANG_FLAG_?:
0: DECL_ERROR_REPORTED (in VAR_DECL).
+ DECL_TEMPLATE_PARM_P (in CONST_DECL, TYPE_DECL, or TEMPLATE_DECL)
1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL).
DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
@@ -1832,11 +1833,12 @@ extern int flag_new_for_scope;
#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE)
#define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE)
-/* Nonzero for TEMPLATE_DECL nodes that represents template template
- parameters */
+/* Nonzero for a DECL which is actually a template parameter. */
+#define DECL_TEMPLATE_PARM_P(NODE) \
+ DECL_LANG_FLAG_0 (NODE)
+
#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
- (TREE_CODE (NODE) == TEMPLATE_DECL && TREE_TYPE (NODE) \
- && TREE_CODE (TREE_TYPE (NODE)) == TEMPLATE_TEMPLATE_PARM)
+ (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))
#define DECL_FUNCTION_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL \
@@ -3070,7 +3072,6 @@ extern void do_pushlevel PROTO((void));
extern int is_member_template PROTO((tree));
extern int template_parms_equal PROTO((tree, tree));
extern int comp_template_parms PROTO((tree, tree));
-extern int decl_template_parm_p PROTO((tree));
extern int template_class_depth PROTO((tree));
extern int is_specialization_of PROTO((tree, tree));
extern int comp_template_args PROTO((tree, tree));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 356293ab97b..79c38f4323f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3514,15 +3514,23 @@ pushdecl (x)
register tree name = DECL_ASSEMBLER_NAME (x);
int need_new_binding = 1;
- if (current_function_decl && x != current_function_decl
- /* A local declaration for a function doesn't constitute nesting. */
- && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x))
- /* Don't change DECL_CONTEXT of virtual methods. */
- && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
- && !DECL_CONTEXT (x))
- DECL_CONTEXT (x) = current_function_decl;
- if (!DECL_CONTEXT (x))
- DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace);
+ if (DECL_TEMPLATE_PARM_P (x))
+ /* Template parameters have no context; they are not X::T even
+ when declared within a class or namespace. */
+ ;
+ else
+ {
+ if (current_function_decl && x != current_function_decl
+ /* A local declaration for a function doesn't constitute
+ nesting. */
+ && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x))
+ /* Don't change DECL_CONTEXT of virtual methods. */
+ && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
+ && !DECL_CONTEXT (x))
+ DECL_CONTEXT (x) = current_function_decl;
+ if (!DECL_CONTEXT (x))
+ DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace);
+ }
/* Type are looked up using the DECL_NAME, as that is what the rest of the
compiler wants to use. */
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index e6dd29fe31a..d3b01a94520 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -3051,16 +3051,7 @@ do_identifier (token, parsing, args)
cp_error ("enum `%D' is private", id);
/* protected is OK, since it's an enum of `this'. */
}
- if (!processing_template_decl
- /* Really, if we're processing a template, we just want to
- resolve template parameters, and not enumeration
- constants. But, they're hard to tell apart. (Note that
- a non-type template parameter may have enumeration type.)
- Fortunately, there's no harm in resolving *global*
- enumeration constants, since they can't depend on
- template parameters. */
- || (TREE_CODE (CP_DECL_CONTEXT (id)) == NAMESPACE_DECL
- && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_PARM_INDEX))
+ if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
id = DECL_INITIAL (id);
}
else
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/shadow1.C b/gcc/testsuite/g++.old-deja/g++.pt/shadow1.C
new file mode 100644
index 00000000000..dfe99c7b22d
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/shadow1.C
@@ -0,0 +1,19 @@
+// Build don't link:
+
+template <class T>
+struct S {
+ typedef T X;
+
+ class C {
+ typedef T X;
+ };
+};
+
+template <int I>
+struct S2 {
+ enum { A = I };
+
+ void f() {
+ int A;
+ }
+};
OpenPOWER on IntegriCloud