From: Danny S. <dan...@cl...> - 2007-06-25 21:44:48
|
-----Original Message----- From: gcc...@gc... [mailto:gcc...@gc...] On Behalf Of Geoffrey Keating Sent: Tuesday, 26 June 2007 7:44 a.m. To: gcc...@gc... Subject: New option for linkage compatibility with Visual Studio This adds a new option in an attempt to provide compatibility with the shared library linkage behaviour of Microsoft Visual Studio targeting Windows. A description of what it does, from the user point of view, is in the documentation, although of course the aim is to provide compatibility and so the correct test for "is it working" is to compare the behaviour against VS. There has been some traffic on the GCC lists that indicate that at least some people wanted this, and even thought that -fvisibility=hidden would do it (but it doesn't). The feature has been in Apple's compiler for a while and hasn't caused any problems. What do people think about putting it in FSF GCC? -- - Geoffrey Keating <ge...@ap...> ===File ~/patches/gcc-cp-msvis.patch======================== Index: gcc/ChangeLog 2007-06-21 Geoffrey Keating <ge...@ap...> * doc/invoke.texi (C++ Dialect Options): Document fvisibility-ms-compat. * c.opt (fvisibility-ms-compat): New. Index: gcc/cp/ChangeLog 2007-06-21 Geoffrey Keating <ge...@ap...> * decl2.c (determine_visibility): Implement flag_visibility_ms_compat effect on type info. * decl.c (cxx_init_decl_processing): Implement global effect of flag_visibility_ms_compat. Index: gcc/testsuite/ChangeLog 2007-06-21 Geoffrey Keating <ge...@ap...> * g++.dg/ext/visibility/ms-compat-1.C: New. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 125926) +++ gcc/doc/invoke.texi (working copy) @@ -191,6 +191,7 @@ -frepo -fno-rtti -fstats -ftemplate-depth-@var{n} @gol -fno-threadsafe-statics -fuse-cxa-atexit -fno-weak -nostdinc++ @gol -fno-default-inline -fvisibility-inlines-hidden @gol +-fvisibility-ms-compat @gol -Wabi -Wctor-dtor-privacy @gol -Wnon-virtual-dtor -Wreorder @gol -Weffc++ -Wno-deprecated -Wstrict-null-sentinel @gol @@ -1830,6 +1831,33 @@ as their linkage might otherwise cross a shared library boundary. @xref{Template Instantiation}. +@item -fvisibility-ms-compat +@opindex fvisibility-ms-compat +This flag attempts to use visibility settings to make GCC's C++ +linkage model compatible with that of Microsoft Visual Studio. + +The flag makes these changes to GCC's linkage model: + +1. It sets the default visibility to 'hidden', like +@option{-fvisibility=hidden}. +2. Types, but not their members, are not hidden by default. +3. The One Definition Rule is relaxed for types without explicit +visibility specifications which are defined in more than one different +shared object: those declarations are permitted if they would have +been permitted when this option was not used. + +In new code it is better to use @option{-fvisibility=hidden} and +export those classes which are intended to be externally visible. +Unfortunately it is possible for code to rely, perhaps accidentally, +on the Visual Studio behaviour. + +Among the consequences of these changes are that static data members +of the same type with the same name but defined in different shared +objects will be different, so changing one will not change the other; +and that pointers to function members defined in different shared +objects may not compare equal. When this flag is given, it is a +violation of the ODR to define types with the same name differently. + @item -fno-weak @opindex fno-weak Do not use weak symbol support, even if it is provided by the linker. Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 125926) +++ gcc/tree.h (working copy) @@ -2602,8 +2602,7 @@ (DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from) /* Nonzero for a given ..._DECL node means that the name of this node should - be ignored for symbolic debug purposes. Moreover, for a FUNCTION_DECL, - the body of the function should also be ignored. */ + be ignored for symbolic debug purposes. */ #define DECL_IGNORED_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.ignored_flag) /* Nonzero for a given ..._DECL node means that this node represents an Index: gcc/cgraphunit.c =================================================================== --- gcc/cgraphunit.c (revision 125926) +++ gcc/cgraphunit.c (working copy) @@ -1049,8 +1049,6 @@ static void cgraph_expand_function (struct cgraph_node *node) { - enum debug_info_type save_write_symbols = NO_DEBUG; - const struct gcc_debug_hooks *save_debug_hooks = NULL; tree decl = node->decl; /* We ought to not compile any inline clones. */ @@ -1061,14 +1059,6 @@ gcc_assert (node->lowered); - if (DECL_IGNORED_P (decl)) - { - save_write_symbols = write_symbols; - write_symbols = NO_DEBUG; - save_debug_hooks = debug_hooks; - debug_hooks = &do_nothing_debug_hooks; - } - /* Generate RTL for the body of DECL. */ lang_hooks.callgraph.expand_function (decl); @@ -1076,12 +1066,6 @@ /* ??? Can happen with nested function of extern inline. */ gcc_assert (TREE_ASM_WRITTEN (node->decl)); - if (DECL_IGNORED_P (decl)) - { - write_symbols = save_write_symbols; - debug_hooks = save_debug_hooks; - } - current_function_decl = NULL; if (!cgraph_preserve_function_body_p (node->decl)) { Index: gcc/testsuite/g++.dg/ext/visibility/ms-compat-1.C =================================================================== --- gcc/testsuite/g++.dg/ext/visibility/ms-compat-1.C (revision 0) +++ gcc/testsuite/g++.dg/ext/visibility/ms-compat-1.C (revision 0) @@ -0,0 +1,28 @@ +/* { dg-require-visibility "" } */ +/* { dg-options "-fvisibility-ms-compat" } */ + +/* { dg-final { scan-not-hidden "__ZTI1S" } } */ +/* { dg-final { scan-hidden "__ZTI1T" } } */ +/* { dg-final { scan-not-hidden "__ZTI1U" } } */ +/* { dg-final { scan-not-hidden "__ZN1U6hide_4Ev" } } */ + +class S { + virtual void hide_2(); +} hide_1; + +void S::hide_2() { +} + +class __attribute__((visibility("hidden"))) T { + virtual void hide_4(); +} hide_3; + +void T::hide_4() { +} + +class __attribute__((visibility("default"))) U { + virtual void hide_4(); +}; + +void U::hide_4() { +} Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 125926) +++ gcc/cp/decl.c (working copy) @@ -3179,6 +3179,9 @@ current_lang_name = NULL_TREE; + if (flag_visibility_ms_compat) + default_visibility = VISIBILITY_HIDDEN; + /* Force minimum function alignment if using the least significant bit of function pointers to store the virtual bit. */ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn Index: gcc/cp/decl2.c =================================================================== --- gcc/cp/decl2.c (revision 125926) +++ gcc/cp/decl2.c (working copy) @@ -1727,6 +1727,19 @@ but have no TEMPLATE_INFO, so don't try to check it. */ use_template = 0; } + else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl) + && flag_visibility_ms_compat) + { + /* Under -fvisibility-ms-compat, types are visible by default, + even though their contents aren't. */ + tree underlying_type = TREE_TYPE (DECL_NAME (decl)); + int underlying_vis = type_visibility (underlying_type); + if (underlying_vis == VISIBILITY_ANON + || CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type)) + constrain_visibility (decl, underlying_vis); + else + DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; + } else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl)) { /* tinfo visibility is based on the type it's for. */ Index: gcc/c.opt =================================================================== --- gcc/c.opt (revision 125926) +++ gcc/c.opt (working copy) @@ -767,6 +767,10 @@ C++ ObjC++ Marks all inlined methods as having hidden visibility +fvisibility-ms-compat +C++ ObjC++ Var(flag_visibility_ms_compat) +Changes visibility to match Microsoft Visual Studio by default + fvtable-gc C++ ObjC++ Discard unused virtual functions ============================================================ |