This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Minor cleanups
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH: Minor cleanups
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Mon, 22 May 2000 16:04:44 -0700
- Reply-to: mark at codesourcery dot com
We were marking member functions of classes declared in extern "C"
regions as extern "C", contract to [dcl.link]. Fixed with this patch.
I also changed the way IDENTIFIER_TYPENAME_P is computed; it's just
too ugly for words to be doing strncmps there. In the long run we
shouldn't be depending on the identifier name at all for this, but
that will take more work.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2000-05-22 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (IDENTIFIER_TYPENAME_P): Use a flag, not strncmp.
(DECL_CONV_FN_P): Simplify.
(DECL_OPERATOR): Remove.
(language_to_string): Declare.
* decl.c (duplicate_decls): Fix typo in comment.
(grokdeclarator): Adjust use of IDENTIFIER_TYPENAME_P.
(grok_op_properties): Use DECL_CONV_FN_P instead of
IDENTIFIER_TYPENAME_P.
* dump.c (dequeue_and_dump): Dump the language linkage of
declarations.
* error.c (language_to_string): Give it external linkage.
* method.c (build_typename_overload): Set IDENTIFIER_TYPENAME_P.
(implicitly_declare_fn): Set DECL_LANGUAGE.
* pt.c (check_explicit_specialization): Use DECL_CONV_FN_P, not
IDENTIFIER_TYPENAME_P.
(tsubst_decl): Likewise.
(tsubst_copy): Adjust use of IDENTIFIER_TYPENAME_P.
* semantics.c (finish_member_declaration): Don't mark members of
classes declared in an extern "C" region as extern "C".
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.457
diff -c -p -r1.457 cp-tree.h
*** cp-tree.h 2000/05/22 01:08:45 1.457
--- cp-tree.h 2000/05/22 22:34:12
*************** Boston, MA 02111-1307, USA. */
*** 73,78 ****
--- 73,79 ----
or FIELD_DECL).
NEED_TEMPORARY_P (in REF_BIND, BASE_CONV)
SCOPE_PARTIAL_P (in SCOPE_STMT)
+ IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
5: BINFO_PRIMARY_MARKED_P (in BINFO)
6: BINFO_VBASE_PRIMARY_P (in BINFO)
*************** struct tree_srcloc
*** 484,493 ****
/* Nonzero if this identifier is the name of a type-conversion
operator. */
! #define IDENTIFIER_TYPENAME_P(NODE) \
! (! strncmp (IDENTIFIER_POINTER (NODE), \
! OPERATOR_TYPENAME_FORMAT, \
! strlen (OPERATOR_TYPENAME_FORMAT)))
/* Nonzero if this identifier is the name of a constructor or
destructor. */
--- 485,492 ----
/* Nonzero if this identifier is the name of a type-conversion
operator. */
! #define IDENTIFIER_TYPENAME_P(NODE) \
! (TREE_LANG_FLAG_4 (NODE))
/* Nonzero if this identifier is the name of a constructor or
destructor. */
*************** struct lang_decl
*** 1972,1979 ****
(DECL_LANG_SPECIFIC (NODE)->cloned_function)
/* Non-zero if NODE is a user-defined conversion operator. */
! #define DECL_CONV_FN_P(NODE) \
! (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)) && TREE_TYPE (DECL_NAME (NODE)))
/* Non-zero if NODE is an overloaded operator. */
#define DECL_OVERLOADED_OPERATOR_P(NODE) \
--- 1971,1978 ----
(DECL_LANG_SPECIFIC (NODE)->cloned_function)
/* Non-zero if NODE is a user-defined conversion operator. */
! #define DECL_CONV_FN_P(NODE) \
! (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)))
/* Non-zero if NODE is an overloaded operator. */
#define DECL_OVERLOADED_OPERATOR_P(NODE) \
*************** extern int flag_new_for_scope;
*** 2684,2694 ****
#define DECL_THIS_STATIC(NODE) \
DECL_LANG_FLAG_6 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE))
- /* Nonzero in FUNCTION_DECL means it is really an operator.
- Just used to communicate formatting information to dbxout.c. */
- #define DECL_OPERATOR(NODE) \
- (DECL_LANG_SPECIFIC(FUNCTION_DECL_CHECK (NODE))->decl_flags.operator_attr)
-
/* Nonzero if TYPE is an anonymous union or struct type. We have to use a
flag for this because "A union for which objects or pointers are
declared is not an anonymous union" [class.union]. */
--- 2683,2688 ----
*************** extern const char *context_as_string
*** 4084,4089 ****
--- 4078,4084 ----
extern const char *lang_decl_name PARAMS ((tree, int));
extern const char *cp_file_of PARAMS ((tree));
extern int cp_line_of PARAMS ((tree));
+ extern const char *language_to_string PARAMS ((enum languages, int));
/* in except.c */
extern void init_exception_processing PARAMS ((void));
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.608
diff -c -p -r1.608 decl.c
*** decl.c 2000/05/22 07:23:25 1.608
--- decl.c 2000/05/22 22:34:21
*************** duplicate_decls (newdecl, olddecl)
*** 3126,3134 ****
DECL_THIS_STATIC (olddecl) = 1;
TREE_PUBLIC (olddecl) = 0;
! /* Make the olddeclaration consistent with the new one so that
! all remnants of the builtin-ness of this function will be
! banished. */
DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
DECL_RTL (olddecl) = DECL_RTL (newdecl);
DECL_ASSEMBLER_NAME (olddecl) = DECL_ASSEMBLER_NAME (newdecl);
--- 3126,3134 ----
DECL_THIS_STATIC (olddecl) = 1;
TREE_PUBLIC (olddecl) = 0;
! /* Make the old declaration consistent with the new one so
! that all remnants of the builtin-ness of this function
! will be banished. */
DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
DECL_RTL (olddecl) = DECL_RTL (newdecl);
DECL_ASSEMBLER_NAME (olddecl) = DECL_ASSEMBLER_NAME (newdecl);
*************** grokdeclarator (declarator, declspecs, d
*** 9643,9651 ****
dname);
name = IDENTIFIER_POINTER (dname);
}
! if (! IDENTIFIER_OPNAME_P (dname)
! /* GNU/Linux headers use '__op'. Arrgh. */
! || (IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname)))
name = IDENTIFIER_POINTER (dname);
else
{
--- 9643,9651 ----
dname);
name = IDENTIFIER_POINTER (dname);
}
!
! else if (IDENTIFIER_OPNAME_P (dname)
! && !IDENTIFIER_TYPENAME_P (dname))
name = IDENTIFIER_POINTER (dname);
else
{
*************** grokdeclarator (declarator, declspecs, d
*** 9656,9661 ****
--- 9656,9662 ----
ctor_return_type = TREE_TYPE (dname);
sfk = sfk_conversion;
}
+
name = operator_name_string (dname);
}
break;
*************** grok_op_properties (decl, virtualp, frie
*** 12183,12189 ****
an enumeration, or a reference to an enumeration. 13.4.0.6 */
if (! methodp || DECL_STATIC_FUNCTION_P (decl))
{
! if (IDENTIFIER_TYPENAME_P (name)
|| name == ansi_opname[(int) CALL_EXPR]
|| name == ansi_opname[(int) MODIFY_EXPR]
|| name == ansi_opname[(int) COMPONENT_REF]
--- 12184,12190 ----
an enumeration, or a reference to an enumeration. 13.4.0.6 */
if (! methodp || DECL_STATIC_FUNCTION_P (decl))
{
! if (DECL_CONV_FN_P (decl)
|| name == ansi_opname[(int) CALL_EXPR]
|| name == ansi_opname[(int) MODIFY_EXPR]
|| name == ansi_opname[(int) COMPONENT_REF]
Index: dump.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/dump.c,v
retrieving revision 1.43
diff -c -p -r1.43 dump.c
*** dump.c 2000/05/03 22:25:20 1.43
--- dump.c 2000/05/22 22:34:25
*************** dequeue_and_dump (di)
*** 395,400 ****
--- 395,402 ----
dump_string (di, "artificial");
if (TREE_CHAIN (t))
dump_child ("chan", TREE_CHAIN (t));
+ if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus)
+ dump_string (di, language_to_string (DECL_LANGUAGE (t), 0));
}
else if (code_class == 't')
{
Index: error.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/error.c,v
retrieving revision 1.112
diff -c -p -r1.112 error.c
*** error.c 2000/04/11 16:56:13 1.112
--- error.c 2000/05/22 22:34:26
*************** static const char *cv_to_string PARAMS
*** 64,70 ****
static const char *decl_to_string PARAMS ((tree, int));
static const char *expr_to_string PARAMS ((tree, int));
static const char *fndecl_to_string PARAMS ((tree, int));
- static const char *language_to_string PARAMS ((enum languages, int));
static const char *op_to_string PARAMS ((enum tree_code, int));
static const char *parm_to_string PARAMS ((int, int));
static const char *type_to_string PARAMS ((tree, int));
--- 64,69 ----
*************** code_to_string (c, v)
*** 2267,2273 ****
return tree_code_name [c];
}
! static const char *
language_to_string (c, v)
enum languages c;
int v ATTRIBUTE_UNUSED;
--- 2266,2272 ----
return tree_code_name [c];
}
! const char *
language_to_string (c, v)
enum languages c;
int v ATTRIBUTE_UNUSED;
Index: method.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/method.c,v
retrieving revision 1.156
diff -c -p -r1.156 method.c
*** method.c 2000/05/22 01:08:46 1.156
--- method.c 2000/05/22 22:34:28
*************** build_typename_overload (type)
*** 1766,1771 ****
--- 1766,1772 ----
build_mangled_name (type, 0, 1);
id = get_identifier (obstack_base (&scratch_obstack));
IDENTIFIER_OPNAME_P (id) = 1;
+ IDENTIFIER_TYPENAME_P (id) = 1;
TREE_TYPE (id) = type;
end_squangling ();
return id;
*************** implicitly_declare_fn (kind, type, const
*** 2580,2585 ****
--- 2581,2589 ----
DECL_NOT_REALLY_EXTERN (fn) = 1;
DECL_THIS_INLINE (fn) = 1;
DECL_INLINE (fn) = 1;
+ /* Even within an `extern "C"' block, members get C++ linkage. See
+ [dcl.link] for details. */
+ DECL_LANGUAGE (fn) = lang_cplusplus;
defer_fn (fn);
return fn;
Index: pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.426
diff -c -p -r1.426 pt.c
*** pt.c 2000/05/09 19:55:50 1.426
--- pt.c 2000/05/22 22:34:33
*************** check_explicit_specialization (declarato
*** 1392,1398 ****
name = is_constructor ? ctor_identifier : dtor_identifier;
}
! if (!IDENTIFIER_TYPENAME_P (name))
{
idx = lookup_fnfields_1 (ctype, name);
if (idx >= 0)
--- 1392,1398 ----
name = is_constructor ? ctor_identifier : dtor_identifier;
}
! if (!DECL_CONV_FN_P (decl))
{
idx = lookup_fnfields_1 (ctype, name);
if (idx >= 0)
*************** tsubst_decl (t, args, type, in_decl)
*** 5687,5693 ****
/*complain=*/1, t,
/*entering_scope=*/1);
! if (member && IDENTIFIER_TYPENAME_P (DECL_NAME (r)))
/* Type-conversion operator. Reconstruct the name, in
case it's the name of one of the template's parameters. */
DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
--- 5687,5693 ----
/*complain=*/1, t,
/*entering_scope=*/1);
! if (member && DECL_CONV_FN_P (r))
/* Type-conversion operator. Reconstruct the name, in
case it's the name of one of the template's parameters. */
DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
*************** tsubst_copy (t, args, complain, in_decl)
*** 7055,7066 ****
return tsubst (t, args, complain, in_decl);
case IDENTIFIER_NODE:
! if (IDENTIFIER_TYPENAME_P (t)
! /* Make sure it's not just a variable named `__opr', for instance,
! which can occur in some existing code. */
! && TREE_TYPE (t))
! return build_typename_overload
! (tsubst (TREE_TYPE (t), args, complain, in_decl));
else
return t;
--- 7055,7063 ----
return tsubst (t, args, complain, in_decl);
case IDENTIFIER_NODE:
! if (IDENTIFIER_TYPENAME_P (t))
! return (build_typename_overload
! (tsubst (TREE_TYPE (t), args, complain, in_decl)));
else
return t;
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.142
diff -c -p -r1.142 semantics.c
*** semantics.c 2000/05/21 17:01:22 1.142
--- semantics.c 2000/05/22 22:34:35
*************** finish_member_declaration (decl)
*** 2004,2009 ****
--- 2004,2016 ----
/* Mark the DECL as a member of the current class. */
DECL_CONTEXT (decl) = current_class_type;
+ /* [dcl.link]
+
+ A C language linkage is ignored for the names of class members
+ and the member function type of class member functions. */
+ if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)
+ DECL_LANGUAGE (decl) = lang_cplusplus;
+
/* Put functions on the TYPE_METHODS list and everything else on the
TYPE_FIELDS list. Note that these are built up in reverse order.
We reverse them (to obtain declaration order) in finish_struct. */