* 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
+2001-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ * 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 <jakub@redhat.com>
* decl.c (push_class_binding): Use context_for_name_lookup instead
`#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)
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);
{
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
{
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;
\f
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)
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);
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);
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))
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
}
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;
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);
}
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;
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;