From 97458258b8e196f88ba17d4ed985aece3ec5675c Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sun, 4 Feb 2001 08:35:11 +0000 Subject: [PATCH] cp-tree.h (CLASSTYPE_INTERFACE_UNKNOWN): Fix formatting. * cp-tree.h (CLASSTYPE_INTERFACE_UNKNOWN): Fix formatting. Document. (CLASSTYPE_INTERFACE_KNOWN): Likewise. (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise. (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise. (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise. * decl.c (maybe_commonize_var): Use the new name-mangling where appropriate. * decl2.c (comdat_linkage): Enhance comments. Make all compiler-generated things static, if COMDAT is not available. (get_tinfo_decl): Do not make typeinfo objects that belong in the library COMDAT. (tinfo_base_init): Use the correct mangled name for typeinfo strings, and push them into the global scope. (typeinfo_in_lib_p): New function. (synthesize_tinfo_var): Use it. (create_real_tinfo_var): Likewise. From-SVN: r39437 --- gcc/cp/ChangeLog | 20 +++++++++++++ gcc/cp/cp-tree.h | 23 ++++++++++---- gcc/cp/decl.c | 9 ++++-- gcc/cp/decl2.c | 22 ++++++++++---- gcc/cp/rtti.c | 78 ++++++++++++++++++++++++++++++++---------------- 5 files changed, 112 insertions(+), 40 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b9d81e1daa5..66746f08df1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2001-02-04 Mark Mitchell + + * cp-tree.h (CLASSTYPE_INTERFACE_UNKNOWN): Fix formatting. + Document. + (CLASSTYPE_INTERFACE_KNOWN): Likewise. + (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise. + (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise. + (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise. + * decl.c (maybe_commonize_var): Use the new name-mangling where + appropriate. + * decl2.c (comdat_linkage): Enhance comments. Make all + compiler-generated things static, if COMDAT is not available. + (get_tinfo_decl): Do not make typeinfo objects that belong in the + library COMDAT. + (tinfo_base_init): Use the correct mangled name for typeinfo + strings, and push them into the global scope. + (typeinfo_in_lib_p): New function. + (synthesize_tinfo_var): Use it. + (create_real_tinfo_var): Likewise. + 2001-02-03 Jakub Jelinek * decl.c (push_class_binding): Use context_for_name_lookup instead diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 60421a391b6..9077671bb60 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1615,12 +1615,23 @@ struct lang_type `#pragma interface', and it is not included in its implementation file. */ #define CLASSTYPE_INTERFACE_ONLY(NODE) (TYPE_LANG_SPECIFIC(NODE)->interface_only) -/* Same as above, but for classes whose purpose we do not know. */ -#define CLASSTYPE_INTERFACE_UNKNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->interface_unknown) -#define CLASSTYPE_INTERFACE_KNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->interface_unknown == 0) -#define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) (TYPE_LANG_SPECIFIC(NODE)->interface_unknown = !!(X)) -#define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->interface_unknown = 1) -#define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->interface_unknown = 0) +/* True if we have already determined whether or not vtables, VTTs, + typeinfo, and other similar per-class data should be emitted in + this translation unit. This flag does not indicate whether or not + these items should be emitted; it only indicates that we know one + way or the other. */ +#define CLASSTYPE_INTERFACE_KNOWN(NODE) \ + (TYPE_LANG_SPECIFIC(NODE)->interface_unknown == 0) +/* The opposite of CLASSTYPE_INTERFANCE_KNOWN. */ +#define CLASSTYPE_INTERFACE_UNKNOWN(NODE) \ + (TYPE_LANG_SPECIFIC(NODE)->interface_unknown) + +#define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) \ + (TYPE_LANG_SPECIFIC(NODE)->interface_unknown = !!(X)) +#define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) \ + (TYPE_LANG_SPECIFIC(NODE)->interface_unknown = 1) +#define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) \ + (TYPE_LANG_SPECIFIC(NODE)->interface_unknown = 0) /* Nonzero if a _DECL node requires us to output debug info for this class. */ #define CLASSTYPE_DEBUG_REQUESTED(NODE) (TYPE_LANG_SPECIFIC(NODE)->debug_requested) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 44a3b3b947d..a250e67c68c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7517,8 +7517,13 @@ maybe_commonize_var (decl) which we can't if it has been initialized. */ if (TREE_PUBLIC (decl)) - DECL_ASSEMBLER_NAME (decl) - = build_static_name (current_function_decl, DECL_NAME (decl)); + { + if (flag_new_abi) + DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl); + else + DECL_ASSEMBLER_NAME (decl) + = build_static_name (current_function_decl, DECL_NAME (decl)); + } else { cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 6088e1073e4..2c3dbc78daf 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2396,14 +2396,24 @@ comdat_linkage (decl) { if (flag_weak) make_decl_one_only (decl); - else if (TREE_CODE (decl) == FUNCTION_DECL || DECL_VIRTUAL_P (decl)) - /* We can just emit functions and vtables statically; having - multiple copies is (for the most part) only a waste of space. - There is at least one correctness issue, however: the address - of a template instantiation with external linkage should be the + else if (TREE_CODE (decl) == FUNCTION_DECL + || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl))) + /* We can just emit function and compiler-generated variables + statically; having multiple copies is (for the most part) only + a waste of space. + + There are two correctness issues, however: the address of a + template instantiation with external linkage should be the same, independent of what translation unit asks for the address, and this will not hold when we emit multiple copies of - the function. However, there's little else we can do. */ + the function. However, there's little else we can do. + + Also, by default, the typeinfo implementation for the new ABI + assumes that there will be only one copy of the string used as + the name for each type. Therefore, if weak symbols are + unavailable, the run-time library should perform a more + conservative check; it should perform a string comparison, + rather than an address comparison. */ TREE_PUBLIC (decl) = 0; else { diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index f105649262b..8be6f7e1087 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -68,10 +68,11 @@ static tree dfs_class_hint_unmark PARAMS ((tree, void *)); static int class_hint_flags PARAMS((tree)); static tree class_initializer PARAMS((tree, tree, tree)); static tree synthesize_tinfo_var PARAMS((tree, tree)); -static tree create_real_tinfo_var PARAMS((tree, tree, tree, int)); +static tree create_real_tinfo_var PARAMS((tree, tree, tree, tree, int)); static tree create_pseudo_type_info PARAMS((const char *, int, ...)); static tree get_vmi_pseudo_type_info PARAMS((int)); static void create_tinfo_types PARAMS((void)); +static int typeinfo_in_lib_p PARAMS((tree)); static int doing_runtime = 0; @@ -394,7 +395,7 @@ tinfo_name (type) returned decl, to save the decl. To use the decl call tinfo_from_decl. You must arrange that the decl is mark_used, if actually use it --- decls in vtables are only used if the vtable is - output. */ + output. */ tree get_tinfo_decl (type) @@ -443,7 +444,8 @@ get_tinfo_decl (type) TREE_STATIC (d) = 1; DECL_EXTERNAL (d) = 1; TREE_PUBLIC (d) = 1; - comdat_linkage (d); + if (flag_weak || !typeinfo_in_lib_p (d)) + comdat_linkage (d); DECL_ASSEMBLER_NAME (d) = DECL_NAME (d); cp_finish_decl (d, NULL_TREE, NULL_TREE, 0); @@ -1327,7 +1329,7 @@ tinfo_base_init (desc, target) tree name_string = tinfo_name (target); if (flag_new_abi) - name_name = mangle_typeinfo_for_type (target); + name_name = mangle_typeinfo_string_for_type (target); else name_name = build_overload_with_type (tinfo_var_id, target); name_decl = build_lang_decl (VAR_DECL, name_name, name_type); @@ -1347,6 +1349,7 @@ tinfo_base_init (desc, target) DECL_ASSEMBLER_NAME (name_decl) = DECL_NAME (name_decl); DECL_INITIAL (name_decl) = name_string; cp_finish_decl (name_decl, name_string, NULL_TREE, 0); + pushdecl_top_level (name_decl); } if (TINFO_VTABLE_DECL (desc)) @@ -1538,6 +1541,34 @@ class_initializer (desc, target, trail) return init; } +/* Returns non-zero if the typeinfo for type should be placed in + the runtime library. */ + +static int +typeinfo_in_lib_p (type) + tree type; +{ + /* The typeinfo objects for `T*' and `const T*' are in the runtime + library for simple types T. */ + if (TREE_CODE (type) == POINTER_TYPE + && (CP_TYPE_QUALS (TREE_TYPE (type)) == TYPE_QUAL_CONST + || CP_TYPE_QUALS (TREE_TYPE (type)) == TYPE_UNQUALIFIED)) + type = TREE_TYPE (type); + + switch (TREE_CODE (type)) + { + case INTEGER_TYPE: + case BOOLEAN_TYPE: + case CHAR_TYPE: + case REAL_TYPE: + case VOID_TYPE: + return 1; + + default: + return 0; + } +} + /* Generate a pseudo_type_info VAR_DECL suitable for the supplied TARGET_TYPE and given the REAL_NAME. This is the structure expected by the runtime, and therefore has additional fields. If we need not emit a @@ -1565,14 +1596,7 @@ synthesize_tinfo_var (target_type, real_name) } else { - int code = TREE_CODE (TREE_TYPE (target_type)); - - if ((CP_TYPE_QUALS (TREE_TYPE (target_type)) | TYPE_QUAL_CONST) - == TYPE_QUAL_CONST - && (code == INTEGER_TYPE || code == BOOLEAN_TYPE - || code == CHAR_TYPE || code == REAL_TYPE - || code == VOID_TYPE) - && !doing_runtime) + if (typeinfo_in_lib_p (target_type) && !doing_runtime) /* These are in the runtime. */ return NULL_TREE; var_type = ptr_desc_type_node; @@ -1675,23 +1699,23 @@ synthesize_tinfo_var (target_type, real_name) var_init = class_initializer (var_type, target_type, base_inits); } break; - case INTEGER_TYPE: - case BOOLEAN_TYPE: - case CHAR_TYPE: - case REAL_TYPE: - case VOID_TYPE: - if (!doing_runtime) - /* These are guaranteed to be in the runtime. */ - return NULL_TREE; - var_type = bltn_desc_type_node; - var_init = generic_initializer (var_type, target_type); - break; + default: + if (typeinfo_in_lib_p (target_type)) + { + if (!doing_runtime) + /* These are guaranteed to be in the runtime. */ + return NULL_TREE; + var_type = bltn_desc_type_node; + var_init = generic_initializer (var_type, target_type); + break; + } my_friendly_abort (20000117); } - return create_real_tinfo_var (real_name, TINFO_PSEUDO_TYPE (var_type), + return create_real_tinfo_var (target_type, + real_name, TINFO_PSEUDO_TYPE (var_type), var_init, non_public); } @@ -1699,7 +1723,8 @@ synthesize_tinfo_var (target_type, real_name) make this variable public (comdat). */ static tree -create_real_tinfo_var (name, type, init, non_public) +create_real_tinfo_var (target_type, name, type, init, non_public) + tree target_type; tree name; tree type; tree init; @@ -1725,7 +1750,8 @@ create_real_tinfo_var (name, type, init, non_public) if (!non_public) { TREE_PUBLIC (decl) = 1; - comdat_linkage (decl); + if (flag_weak || !typeinfo_in_lib_p (target_type)) + comdat_linkage (decl); } DECL_ASSEMBLER_NAME (decl) = name; DECL_INITIAL (decl) = init; -- 2.30.2