* lang-options.h: Add -fms-extensions.
* cp-tree.h: Declare flag_ms_extensions.
* decl2.c: Define it.
* class.c (instantiate_type): Don't complain about taking the address
of a bound member function if -fms-extensions.
* typeck.c (build_unary_op): Likewise.
* decl.c (grokdeclarator): Or about implicit int.
* init.c (resolve_offset_ref): Or about implicit '&'.
From-SVN: r28684
+1999-08-11 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lang-options.h: Add -fms-extensions.
+ * cp-tree.h: Declare flag_ms_extensions.
+ * decl2.c: Define it.
+ * class.c (instantiate_type): Don't complain about taking the address
+ of a bound member function if -fms-extensions.
+ * typeck.c (build_unary_op): Likewise.
+ * decl.c (grokdeclarator): Or about implicit int.
+ * init.c (resolve_offset_ref): Or about implicit '&'.
+
1999-08-11 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (minimal_parse_mode): Remove.
case COMPONENT_REF:
{
- tree field = TREE_OPERAND (rhs, 1);
- tree r;
+ tree r = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
- r = instantiate_type (lhstype, field, flags);
-
- if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
+ if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)
+ && complain && !flag_ms_extensions)
{
- if (complain)
- {
- tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
-
- if (TREE_CODE (field) == OVERLOAD)
- field = OVL_FUNCTION (field);
- if (TREE_CODE (field) == FUNCTION_DECL)
- {
- cp_pedwarn ("object-dependent reference `%E' can only be used in a call",
- DECL_NAME (field));
- cp_pedwarn (" to form a pointer to member function, say `&%T::%E'",
- t, DECL_NAME (field));
- }
- else
- cp_pedwarn ("object-dependent reference can only be used in a call");
- }
- return r;
+ /* Note: we check this after the recursive call to avoid
+ complaining about cases where overload resolution fails. */
+
+ tree t = TREE_TYPE (TREE_OPERAND (rhs, 0));
+ tree fn = PTRMEM_CST_MEMBER (r);
+
+ my_friendly_assert (TREE_CODE (r) == PTRMEM_CST, 990811);
+
+ cp_pedwarn
+ ("object-dependent reference to `%E' can only be used in a call",
+ DECL_NAME (fn));
+ cp_pedwarn
+ (" to form a pointer to member function, say `&%T::%E'",
+ t, DECL_NAME (fn));
}
-
+
return r;
}
applies, use the value of the label. */
extern int flag_labels_ok;
+/* Nonzero means allow Microsoft extensions without a pedwarn. */
+extern int flag_ms_extensions;
+
/* Non-zero means to collect statistics which might be expensive
and to print them when we are done. */
extern int flag_detailed_statistics;
&& in_namespace == NULL_TREE
&& current_namespace == global_namespace);
- if (in_system_header)
+ if (in_system_header || flag_ms_extensions)
/* Allow it, sigh. */;
else if (pedantic || ! is_main)
cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type",
int flag_labels_ok;
+/* Nonzero means allow Microsoft extensions without a pedwarn. */
+
+int flag_ms_extensions;
+
/* Non-zero means to collect statistics which might be expensive
and to print them when we are done. */
int flag_detailed_statistics;
{"implicit-inline-templates", &flag_implicit_inline_templates, 1},
{"implicit-templates", &flag_implicit_templates, 1},
{"labels-ok", &flag_labels_ok, 1},
+ {"ms-extensions", &flag_ms_extensions, 1},
{"nonansi-builtins", &flag_no_nonansi_builtin, 0},
{"operator-names", &flag_operator_names, 1},
{"optional-diags", &flag_optional_diags, 1},
if (BASELINK_P (member))
{
- cp_pedwarn ("assuming & on overloaded member function");
+ if (! flag_ms_extensions)
+ cp_pedwarn ("assuming & on overloaded member function");
return build_unary_op (ADDR_EXPR, exp, 0);
}
if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
{
- cp_pedwarn ("assuming & on `%E'", member);
+ if (! flag_ms_extensions)
+ cp_pedwarn ("assuming & on `%E'", member);
return build_unary_op (ADDR_EXPR, exp, 0);
}
{ "-fno-labels-ok", "" },
{ "-fmemoize-lookups", "" },
{ "-fno-memoize-lookups", "" },
+ { "-fms-extensions", "Don't pedwarn about uses of Microsoft extensions" },
+ { "-fno-ms-extensions", "" },
{ "-fname-mangling-version-", "" },
{ "-fnew-abi", "Enable experimental ABI changes" },
{ "-fno-new-abi", "" },
&& OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
{
/* They're trying to take the address of a unique non-static
- member function. This is ill-formed, but let's try to DTRT. */
- tree base, name;
+ member function. This is ill-formed, but let's try to DTRT.
+ Note: We only handle unique functions here because we don't
+ want to complain if there's a static overload; non-unique
+ cases will be handled by instantiate_type. But we need to
+ handle this case here to allow casts on the resulting PMF. */
- if (current_class_type
- && TREE_OPERAND (arg, 0) == current_class_ref)
- /* An expression like &memfn. */
- pedwarn ("taking the address of a non-static member function");
- else
- pedwarn ("taking the address of a bound member function");
+ tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
+ tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
- base = TREE_TYPE (TREE_OPERAND (arg, 0));
- name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
+ if (! flag_ms_extensions)
+ {
+ if (current_class_type
+ && TREE_OPERAND (arg, 0) == current_class_ref)
+ /* An expression like &memfn. */
+ pedwarn ("taking the address of a non-static member function");
+ else
+ pedwarn ("taking the address of a bound member function");
+
+ cp_pedwarn
+ (" to form a pointer to member function, say `&%T::%D'",
+ base, name);
+ }
- cp_pedwarn (" to form a pointer to member function, say `&%T::%D'",
- base, name);
arg = build_offset_ref (base, name);
}