From: <dan...@us...> - 2009-08-18 19:42:22
|
Revision: 1357 http://cegcc.svn.sourceforge.net/cegcc/?rev=1357&view=rev Author: dannybackx Date: 2009-08-18 19:42:13 +0000 (Tue, 18 Aug 2009) Log Message: ----------- Import a patch for (C++ DLL) typeinfo comparison from gcc svn. Author : Jason Merrill. Modified Paths: -------------- trunk/cegcc/src/gcc-4.4.0/ChangeLog.ce trunk/cegcc/src/gcc-4.4.0/gcc/config/i386/mingw32ce.h trunk/cegcc/src/gcc-4.4.0/gcc/cp/cp-tree.h trunk/cegcc/src/gcc-4.4.0/gcc/cp/mangle.c trunk/cegcc/src/gcc-4.4.0/gcc/cp/name-lookup.c trunk/cegcc/src/gcc-4.4.0/gcc/cp/rtti.c trunk/cegcc/src/gcc-4.4.0/libstdc++-v3/libsupc++/typeinfo Modified: trunk/cegcc/src/gcc-4.4.0/ChangeLog.ce =================================================================== --- trunk/cegcc/src/gcc-4.4.0/ChangeLog.ce 2009-08-15 13:49:22 UTC (rev 1356) +++ trunk/cegcc/src/gcc-4.4.0/ChangeLog.ce 2009-08-18 19:42:13 UTC (rev 1357) @@ -1,3 +1,22 @@ +2009-08-18 Danny Backx dan...@us...> + + * gcc/config/i386/mingw32ce.h (__GXX_MERGED_TYPEINFO_NAMES) : Remove + to match the requirements of the patch by Jason Merrill. + +2009-07-22 Jason Merrill <ja...@re...> + + * Fix imported from gcc svn, see + http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01239.html . + + * mangle.c (mangle_type_string_for_rtti): Rename to be clearer. + (needs_fake_anon): New. + (write_name): Check it. + (write_nested_name): Add a fake anonymous namespace scope if true. + * name-lookup.c (get_anonymous_namespace_name): No longer static. + * rtti.c, cp-tree.h: Adjust. + + * libsupc++/typeinfo (__GXX_MERGED_TYPEINFO_NAMES): Default to 0. + 2009-08-08 Danny Backx dan...@us...> * gcc/config.gcc : Add soft-fp configuration files to our build. Modified: trunk/cegcc/src/gcc-4.4.0/gcc/config/i386/mingw32ce.h =================================================================== --- trunk/cegcc/src/gcc-4.4.0/gcc/config/i386/mingw32ce.h 2009-08-15 13:49:22 UTC (rev 1356) +++ trunk/cegcc/src/gcc-4.4.0/gcc/config/i386/mingw32ce.h 2009-08-18 19:42:13 UTC (rev 1357) @@ -64,8 +64,7 @@ } \ /* Even though linkonce works with static libs, this is needed \ to compare typeinfo symbols across dll boundaries. */ \ - builtin_define ("__GXX_MERGED_TYPEINFO_NAMES=1"); \ - } \ + } \ while (0) /* Link with coredll, the main libc in the native SDK, Modified: trunk/cegcc/src/gcc-4.4.0/gcc/cp/cp-tree.h =================================================================== --- trunk/cegcc/src/gcc-4.4.0/gcc/cp/cp-tree.h 2009-08-15 13:49:22 UTC (rev 1356) +++ trunk/cegcc/src/gcc-4.4.0/gcc/cp/cp-tree.h 2009-08-18 19:42:13 UTC (rev 1357) @@ -4301,6 +4301,9 @@ /* decl.c */ extern tree poplevel (int, int, int); extern void insert_block (tree); + +/* in name-lookup.c */ +extern tree get_anonymous_namespace_name (void); extern tree pushdecl (tree); extern tree pushdecl_maybe_friend (tree, bool); extern void cxx_init_decl_processing (void); @@ -5029,7 +5032,7 @@ /* in mangle.c */ extern void init_mangle (void); extern void mangle_decl (tree); -extern const char *mangle_type_string (tree); +extern const char *mangle_type_string_for_rtti (tree); extern tree mangle_typeinfo_for_type (tree); extern tree mangle_typeinfo_string_for_type (tree); extern tree mangle_vtbl_for_type (tree); Modified: trunk/cegcc/src/gcc-4.4.0/gcc/cp/mangle.c =================================================================== --- trunk/cegcc/src/gcc-4.4.0/gcc/cp/mangle.c 2009-08-15 13:49:22 UTC (rev 1356) +++ trunk/cegcc/src/gcc-4.4.0/gcc/cp/mangle.c 2009-08-18 19:42:13 UTC (rev 1357) @@ -106,6 +106,10 @@ static GTY (()) globals G; +/* Whether or not to pretend that a static function is in an anonymous + namespace. */ +static bool fake_anon_scope; + /* The obstack on which we build mangled names. */ static struct obstack *mangle_obstack; @@ -722,6 +726,20 @@ } } +/* Since we now use strcmp to compare typeinfos on all targets because of + the RTLD_LOCAL problem, we need to munge the typeinfo name used for + local classes of static functions to fix g++.dg/abi/local1.C. We do + that by pretending that the function is in an anonymous namespace. */ + +static bool +needs_fake_anon (const_tree decl) +{ + /* Pretend there's an anonymous namespace right around a static + function if we're mangling for RTTI. */ + return (fake_anon_scope && !TREE_PUBLIC (decl) + && TREE_CODE (decl) == FUNCTION_DECL); +} + /* <name> ::= <unscoped-name> ::= <unscoped-template-name> <template-args> ::= <nested-name> @@ -745,18 +763,23 @@ /* In case this is a typedef, fish out the corresponding TYPE_DECL for the main variant. */ decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); - context = TYPE_CONTEXT (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); + context = CP_TYPE_CONTEXT (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); } else - context = (DECL_CONTEXT (decl) == NULL) ? NULL : CP_DECL_CONTEXT (decl); + context = CP_DECL_CONTEXT (decl); + gcc_assert (context != NULL_TREE); + + /* If we need a fake anonymous namespace, force the nested name path. */ + if (needs_fake_anon (decl) && context == global_namespace) + context = error_mark_node; + /* A decl in :: or ::std scope is treated specially. The former is mangled using <unscoped-name> or <unscoped-template-name>, the latter with a special substitution. Also, a name that is directly in a local function scope is also mangled with <unscoped-name> rather than a full <nested-name>. */ - if (context == NULL - || context == global_namespace + if (context == global_namespace || DECL_NAMESPACE_STD_P (context) || (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL)) { @@ -774,6 +797,9 @@ } else { + if (context == error_mark_node) + context = global_namespace; + /* Handle local names, unless we asked not to (that is, invoked under <local-name>, to handle only the part of the name under the local scope). */ @@ -786,10 +812,10 @@ directly in that function's scope, either decl or one of its enclosing scopes. */ tree local_entity = decl; - while (context != NULL && context != global_namespace) + while (context != global_namespace) { /* Make sure we're always dealing with decls. */ - if (context != NULL && TYPE_P (context)) + if (TYPE_P (context)) context = TYPE_NAME (context); /* Is this a function? */ if (TREE_CODE (context) == FUNCTION_DECL) @@ -833,7 +859,6 @@ /* If not, it should be either in the global namespace, or directly in a local function scope. */ gcc_assert (context == global_namespace - || context == NULL || TREE_CODE (context) == FUNCTION_DECL); write_unqualified_name (decl); @@ -905,6 +930,9 @@ { /* No, just use <prefix> */ write_prefix (DECL_CONTEXT (decl)); + if (needs_fake_anon (decl)) + /* Pretend this static function is in an anonymous namespace. */ + write_source_name (get_anonymous_namespace_name ()); write_unqualified_name (decl); } write_char ('E'); @@ -2801,15 +2829,18 @@ SET_DECL_ASSEMBLER_NAME (decl, id); } -/* Generate the mangled representation of TYPE. */ +/* Generate the mangled representation of TYPE for the typeinfo name. */ const char * -mangle_type_string (const tree type) +mangle_type_string_for_rtti (const tree type) { const char *result; start_mangling (type); + /* Mangle in a fake anonymous namespace if necessary. */ + fake_anon_scope = true; write_type (type); + fake_anon_scope = false; result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_type_string = '%s'\n\n", result); Modified: trunk/cegcc/src/gcc-4.4.0/gcc/cp/name-lookup.c =================================================================== --- trunk/cegcc/src/gcc-4.4.0/gcc/cp/name-lookup.c 2009-08-15 13:49:22 UTC (rev 1356) +++ trunk/cegcc/src/gcc-4.4.0/gcc/cp/name-lookup.c 2009-08-18 19:42:13 UTC (rev 1357) @@ -62,19 +62,14 @@ /* Initialize anonymous_namespace_name if necessary, and return it. */ -static tree -get_anonymous_namespace_name(void) +tree +get_anonymous_namespace_name (void) { if (!anonymous_namespace_name) { /* The anonymous namespace has to have a unique name if typeinfo objects are being compared by name. */ - if (! flag_weak || ! SUPPORTS_ONE_ONLY) - anonymous_namespace_name = get_file_function_name ("N"); - else - /* The demangler expects anonymous namespaces to be called - something starting with '_GLOBAL__N_'. */ - anonymous_namespace_name = get_identifier ("_GLOBAL__N_1"); + anonymous_namespace_name = get_file_function_name ("N"); } return anonymous_namespace_name; } Modified: trunk/cegcc/src/gcc-4.4.0/gcc/cp/rtti.c =================================================================== --- trunk/cegcc/src/gcc-4.4.0/gcc/cp/rtti.c 2009-08-15 13:49:22 UTC (rev 1356) +++ trunk/cegcc/src/gcc-4.4.0/gcc/cp/rtti.c 2009-08-18 19:42:13 UTC (rev 1357) @@ -357,7 +357,7 @@ const char *name; tree name_string; - name = mangle_type_string (type); + name = mangle_type_string_for_rtti (type); name_string = fix_string_type (build_string (strlen (name) + 1, name)); return name_string; } Modified: trunk/cegcc/src/gcc-4.4.0/libstdc++-v3/libsupc++/typeinfo =================================================================== --- trunk/cegcc/src/gcc-4.4.0/libstdc++-v3/libsupc++/typeinfo 2009-08-15 13:49:22 UTC (rev 1356) +++ trunk/cegcc/src/gcc-4.4.0/libstdc++-v3/libsupc++/typeinfo 2009-08-18 19:42:13 UTC (rev 1357) @@ -43,32 +43,29 @@ } // namespace __cxxabiv1 // Determine whether typeinfo names for the same type are merged (in which -// case comparison can just compare pointers) or not (in which case -// strings must be compared and g++.dg/abi/local1.C will fail), and -// whether comparison is to be implemented inline or not. By default we -// use inline pointer comparison if weak symbols are available, and -// out-of-line strcmp if not. Out-of-line pointer comparison is used -// where the object files are to be portable to multiple systems, some of -// which may not be able to use pointer comparison, but the particular -// system for which libstdc++ is being built can use pointer comparison; -// in particular for most ARM EABI systems, where the ABI specifies -// out-of-line comparison. Inline strcmp is not currently supported. The -// compiler's target configuration can override the defaults by defining -// __GXX_TYPEINFO_EQUALITY_INLINE to 1 or 0 to indicate whether or not -// comparison is inline, and __GXX_MERGED_TYPEINFO_NAMES to 1 or 0 to -// indicate whether or not pointer comparison can be used. +// case comparison can just compare pointers) or not (in which case strings +// must be compared), and whether comparison is to be implemented inline or +// not. We used to do inline pointer comparison by default if weak symbols +// are available, but even with weak symbols sometimes names are not merged +// when objects are loaded with RTLD_LOCAL, so now we always use strcmp by +// default. For ABI compatibility, we do the strcmp inline if weak symbols +// are available, and out-of-line if not. Out-of-line pointer comparison +// is used where the object files are to be portable to multiple systems, +// some of which may not be able to use pointer comparison, but the +// particular system for which libstdc++ is being built can use pointer +// comparison; in particular for most ARM EABI systems, where the ABI +// specifies out-of-line comparison. The compiler's target configuration +// can override the defaults by defining __GXX_TYPEINFO_EQUALITY_INLINE to +// 1 or 0 to indicate whether or not comparison is inline, and +// __GXX_MERGED_TYPEINFO_NAMES to 1 or 0 to indicate whether or not pointer +// comparison can be used. #ifndef __GXX_MERGED_TYPEINFO_NAMES - #if !__GXX_WEAK__ - // If weak symbols are not supported, typeinfo names are not merged. - #define __GXX_MERGED_TYPEINFO_NAMES 0 - #else - // On platforms that support weak symbols, typeinfo names are merged. - #define __GXX_MERGED_TYPEINFO_NAMES 1 - #endif +// By default, typeinfo names are not merged. +#define __GXX_MERGED_TYPEINFO_NAMES 0 #endif -// By default follow the same rules as for __GXX_MERGED_TYPEINFO_NAMES. +// By default follow the old inline rules to avoid ABI changes. #ifndef __GXX_TYPEINFO_EQUALITY_INLINE #if !__GXX_WEAK__ #define __GXX_TYPEINFO_EQUALITY_INLINE 0 @@ -100,25 +97,35 @@ { return __name; } #if !__GXX_TYPEINFO_EQUALITY_INLINE - bool before(const type_info& __arg) const; - // In old abi, or when weak symbols are not supported, there can // be multiple instances of a type_info object for one // type. Uniqueness must use the _name value, not object address. + bool before(const type_info& __arg) const; bool operator==(const type_info& __arg) const; #else #if !__GXX_MERGED_TYPEINFO_NAMES - #error "Inline implementation of type_info comparision requires merging of type_info objects" - #endif /** Returns true if @c *this precedes @c __arg in the implementation's * collation order. */ - // In new abi we can rely on type_info's NTBS being unique, + // Even with the new abi, on systems that support dlopen + // we can run into cases where type_info names aren't merged, + // so we still need to do string comparison. + bool before(const type_info& __arg) const + { return __builtin_strcmp (__name, __arg.__name) < 0; } + + bool operator==(const type_info& __arg) const + { + return ((__name == __arg.__name) + || __builtin_strcmp (__name, __arg.__name) == 0); + } + #else + // On some targets we can rely on type_info's NTBS being unique, // and therefore address comparisons are sufficient. bool before(const type_info& __arg) const { return __name < __arg.__name; } bool operator==(const type_info& __arg) const { return __name == __arg.__name; } + #endif #endif bool operator!=(const type_info& __arg) const { return !operator==(__arg); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |