Index: mangle.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/mangle.c,v retrieving revision 1.85 diff -c -3 -p -r1.85 mangle.c *** mangle.c 16 Jul 2003 00:09:45 -0000 1.85 --- mangle.c 17 Jul 2003 19:28:36 -0000 *************** static void write_discriminator (const i *** 201,212 **** --- 201,214 ---- static void write_local_name (const tree, const tree, const tree); static void dump_substitution_candidates (void); static const char *mangle_decl_string (const tree); + static bool write_link_name (tree); /* Control functions. */ static inline void start_mangling (const tree); static inline const char *finish_mangling (const bool); static tree mangle_special_for_type (const tree, const char *); + static const char* link_name (tree); /* Foreign language functions. */ *************** dump_substitution_candidates () *** 316,321 **** --- 318,371 ---- } } + /* If there is a link_name attribute, return the linking + name. Otherwise, return NULL. */ + static const char* + link_name (tree decl) + { + if (!decl) + return NULL; + + if (TREE_CODE (decl) == TEMPLATE_DECL) + decl = DECL_TEMPLATE_RESULT (decl); + + if (TREE_CODE (decl) != TYPE_DECL) + return NULL; + + /* Find the __link_name__ attribute. */ + tree attributes = TYPE_ATTRIBUTES ( TYPE_MAIN_VARIANT( TREE_TYPE (decl))); + while (attributes + && strcmp(IDENTIFIER_POINTER (TREE_PURPOSE (attributes)), + "__link_name__") + && strcmp(IDENTIFIER_POINTER (TREE_PURPOSE (attributes)), + "link_name")) + attributes = TREE_CHAIN (attributes); + + if (attributes) + /* Name buried in a STRING_CST node. */ + return TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attributes))); + else + return NULL; + } + + /* If there is a link_name attribute, write it and return + nonzero. Otherwise, return zero. */ + static bool + write_link_name (tree decl) + { + const char* name = link_name (decl); + + if (name) + { + write_unsigned_number (strlen (name)); + write_identifier (name); + return 1; + } + else + return 0; + } + + /* Both decls and types can be substitution candidates, but sometimes they refer to the same thing. For instance, a TYPE_DECL and RECORD_TYPE for the same class refer to the same thing, and should *************** is_std_substitution (const tree node, *** 403,413 **** /* These are not the droids you're looking for. */ return 0; return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)) && TYPE_LANG_SPECIFIC (type) && TYPE_TEMPLATE_INFO (type) ! && (DECL_NAME (TYPE_TI_TEMPLATE (type)) ! == subst_identifiers[index])); } /* Helper function for find_substitution. Returns nonzero if NODE, --- 453,466 ---- /* These are not the droids you're looking for. */ return 0; + const char* name = link_name (decl); return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)) && TYPE_LANG_SPECIFIC (type) && TYPE_TEMPLATE_INFO (type) ! && ((name && get_identifier(name) == subst_identifiers[index]) ! || (!name ! && (DECL_NAME (TYPE_TI_TEMPLATE (type)) ! == subst_identifiers[index])))); } /* Helper function for find_substitution. Returns nonzero if NODE, *************** write_unqualified_name (const tree decl) *** 1015,1021 **** write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name); } ! else write_source_name (DECL_NAME (decl)); } --- 1068,1074 ---- write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name); } ! else if (!write_link_name (decl)) write_source_name (DECL_NAME (decl)); } Index: pt.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v retrieving revision 1.730 diff -c -3 -p -r1.730 pt.c *** pt.c 17 Jul 2003 04:31:40 -0000 1.730 --- pt.c 17 Jul 2003 19:28:37 -0000 *************** lookup_template_class (tree d1, *** 4283,4288 **** --- 4283,4289 ---- CLASSTYPE_GOT_SEMICOLON (t) = 1; SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t); TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type); + TYPE_ATTRIBUTES (t) = TYPE_ATTRIBUTES (template_type); /* A local class. Make sure the decl gets registered properly. */ if (context == current_function_decl) *************** instantiate_class_template (tree type) *** 5217,5222 **** --- 5218,5225 ---- TYPE_ALIGN (type) = TYPE_ALIGN (pattern); TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern); TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray */ + TYPE_ATTRIBUTES (type) = TYPE_ATTRIBUTES (pattern); + if (ANON_AGGR_TYPE_P (pattern)) SET_ANON_AGGR_TYPE_P (type); Index: tree.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v retrieving revision 1.337 diff -c -3 -p -r1.337 tree.c *** tree.c 16 Jul 2003 00:09:45 -0000 1.337 --- tree.c 17 Jul 2003 19:28:37 -0000 *************** static tree find_tree_r (tree *, int *, *** 53,58 **** --- 53,59 ---- static tree handle_java_interface_attribute (tree *, tree, tree, int, bool *); static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *); static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *); + static tree handle_link_name_attribute (tree *, tree, tree, int, bool *); /* If REF is an lvalue, returns the kind of lvalue that REF is. Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is *************** const struct attribute_spec cxx_attribut *** 1813,1818 **** --- 1814,1820 ---- { "java_interface", 0, 0, false, false, false, handle_java_interface_attribute }, { "com_interface", 0, 0, false, false, false, handle_com_interface_attribute }, { "init_priority", 1, 1, true, false, false, handle_init_priority_attribute }, + { "link_name", 1, 1, false, true, false, handle_link_name_attribute }, { NULL, 0, 0, false, false, false, NULL } }; *************** handle_init_priority_attribute (tree* no *** 1942,1947 **** --- 1944,1970 ---- *no_add_attrs = true; return NULL_TREE; } + } + + /* Handle a "link_name" attribute; arguments as in + struct attribute_spec.handler. */ + static tree + handle_link_name_attribute (tree* node, + tree name, + tree args, + int flags ATTRIBUTE_UNUSED , + bool* no_add_attrs) + { + tree name_expr = TREE_VALUE (args); + if (!name_expr || TREE_CODE(name_expr) != STRING_CST) + { + error ("`%s' attribute requires a string literal", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + return NULL_TREE; + } + + return NULL_TREE; } /* Return a new PTRMEM_CST of the indicated TYPE. The MEMBER is the