tree.c (handle_dll_attribute): Move here from i383/winnt.c.
authorMark Mitchell <mark@codesourcery.com>
Fri, 6 Aug 2004 02:03:29 +0000 (02:03 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 6 Aug 2004 02:03:29 +0000 (02:03 +0000)
* tree.c (handle_dll_attribute): Move here from i383/winnt.c.
Replace use of DECL_INLINE with DECL_DECLARED_INLINE_P.  Set
DECL_VISIBLITY.  Test TARGET_DLLIMPORT_DECL_ATTRIBUTES with #if.
* tree.h (handle_dll_attribute): Declare.  Test
TARGET_DLLIMPORT_DECL_ATTRIBUTES with #if.
* c-common.h (c_determine_visibility): Declare.
* c-common.c (c_determine_visibility): New function.
* c-decl.c (finish_decl): Use it.
(finish_function): Likewise.
* defaults.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define it to
zero, by default.  Use #if, not #ifdef, to test it.
* config/arm/arm.c (arm_attribute_table): Use
handle_dll_attribute.  Test TARGET_DLLIMPORT_DECL_ATTRIBUTES with
#if.
* config/arm/pe.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define to 1.
* config/i386/cygming.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define
to 1.
* config/i386/i386-protos.h (ix86_handle_dll_attribute): Remove.
* config/i386/i386.c (ix86_attribute_table): Use
handle_dll_attribute for dllimport/dllexport.  Test
TARGET_DLLIMPORT_DECL_ATTRIBUTES with #if.
* config/i386/winnt.c (ix86_handle_dll_attribute): Remove.
* config/mcore/mcore.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define
it to 1.
* config/mcore/mcore.c (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Test it
with #if.
* config/sh/symbian-pre.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define
it to 1.
* doc/extend.texi (dllexport): Clarify and correct documentation.
(dllimport): Likewise.
* doc/tm.texi (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Mention
handle_dll_attribute.

* decl.c (start_preparsed_function): Move determine_visibility
call.
* decl2.c (determine_visibility): Incorporate dllexport testing.

* g++.dg/ext/visibility/assign1.C: Use scan-hidden and
dg-require-visiblity.
* g++.dg/ext/visibility/fvisibility-inlines-hidden.C: Likewise.
* g++.dg/ext/visibility/fvisibility.C: Likewise.
* g++.dg/ext/visibility/memfuncts.C: Likewise.
* g++.dg/ext/visibility/new1.C: Likewise.
* g++.dg/ext/visibility/pragma.C: Likewise.
* g++.dg/ext/visibility/staticmemfuncts.C: Likewise.
* g++.dg/ext/visibility/virtual.C: Likewise.
* g++/dg/ext/visibility/visibility-1.C: Likewise.
* g++/dg/ext/visibility/visibility-2.C: Likewise.
* g++/dg/ext/visibility/visibility-3.C: Likewise.
* g++/dg/ext/visibility/visibility-4.C: Likewise.
* g++/dg/ext/visibility/visibility-5.C: Likewise.
* g++/dg/ext/visibility/visibility-6.C: Likewise.
* g++/dg/ext/visibility/visibility-7.C: Likewise.
* g++/dg/ext/visibility/visibility-8.C: New test.
* gcc.c-torture/compile/dll.x: Remove.
* gcc.dg/dll-2.c: Use dg-require-dll
* gcc.dg/visibility-10.c: New test.
* lib/gcc-dg.exp (dg-require-dll): Add Symbian to list of targets
supporting DLLs.
* testsuite/lib/scanasm.exp (scan_hidden): New function.
(scan_not_hidden): Likewise.

From-SVN: r85621

43 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/config/arm/arm.c
gcc/config/arm/pe.h
gcc/config/i386/cygming.h
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/winnt.c
gcc/config/mcore/mcore.c
gcc/config/mcore/mcore.h
gcc/config/sh/symbian-pre.h
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/defaults.h
gcc/doc/extend.texi
gcc/doc/tm.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/visibility/assign1.C
gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden.C
gcc/testsuite/g++.dg/ext/visibility/fvisibility.C
gcc/testsuite/g++.dg/ext/visibility/memfuncts.C
gcc/testsuite/g++.dg/ext/visibility/new1.C
gcc/testsuite/g++.dg/ext/visibility/pragma.C
gcc/testsuite/g++.dg/ext/visibility/staticmemfuncts.C
gcc/testsuite/g++.dg/ext/visibility/virtual.C
gcc/testsuite/g++.dg/ext/visibility/visibility-1.C
gcc/testsuite/g++.dg/ext/visibility/visibility-2.C
gcc/testsuite/g++.dg/ext/visibility/visibility-3.C
gcc/testsuite/g++.dg/ext/visibility/visibility-4.C
gcc/testsuite/g++.dg/ext/visibility/visibility-5.C
gcc/testsuite/g++.dg/ext/visibility/visibility-6.C
gcc/testsuite/g++.dg/ext/visibility/visibility-7.C
gcc/testsuite/g++.dg/ext/visibility/visibility-8.C [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/dll.x [deleted file]
gcc/testsuite/gcc.dg/dll-2.c
gcc/testsuite/gcc.dg/visibility-10.c [new file with mode: 0644]
gcc/testsuite/lib/gcc-dg.exp
gcc/testsuite/lib/scanasm.exp
gcc/tree.c
gcc/tree.h

index 33753a63bb66334771e4f150faca9c7437735b1b..d7d4abd4ff730ad9887105ff2ff2c1bbedd2b4cd 100644 (file)
@@ -1,3 +1,38 @@
+2004-08-05  Mark Mitchell  <mark@codesourcery.com>
+
+       * tree.c (handle_dll_attribute): Move here from i383/winnt.c.
+       Replace use of DECL_INLINE with DECL_DECLARED_INLINE_P.  Set
+       DECL_VISIBLITY.  Test TARGET_DLLIMPORT_DECL_ATTRIBUTES with #if.
+       * tree.h (handle_dll_attribute): Declare.  Test
+       TARGET_DLLIMPORT_DECL_ATTRIBUTES with #if.
+       * c-common.h (c_determine_visibility): Declare.
+       * c-common.c (c_determine_visibility): New function.
+       * c-decl.c (finish_decl): Use it.
+       (finish_function): Likewise.
+       * defaults.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define it to
+       zero, by default.  Use #if, not #ifdef, to test it.
+       * config/arm/arm.c (arm_attribute_table): Use
+       handle_dll_attribute.  Test TARGET_DLLIMPORT_DECL_ATTRIBUTES with
+       #if.
+       * config/arm/pe.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define to 1.
+       * config/i386/cygming.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define
+       to 1.
+       * config/i386/i386-protos.h (ix86_handle_dll_attribute): Remove.
+       * config/i386/i386.c (ix86_attribute_table): Use
+       handle_dll_attribute for dllimport/dllexport.  Test
+       TARGET_DLLIMPORT_DECL_ATTRIBUTES with #if.
+       * config/i386/winnt.c (ix86_handle_dll_attribute): Remove.
+       * config/mcore/mcore.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define
+       it to 1.
+       * config/mcore/mcore.c (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Test it
+       with #if.
+       * config/sh/symbian-pre.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define
+       it to 1.
+       * doc/extend.texi (dllexport): Clarify and correct documentation.
+       (dllimport): Likewise.
+       * doc/tm.texi (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Mention
+       handle_dll_attribute.
+       
 2004-08-05  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
 
        * tree-ssa-loop-manip.c: New file.
        * defaults.h (TARGET_DECLSPEC): New macro.
        * c-cppbuiltin.c (c_cpp_builtins): Handle TARGET_DECLSPEC.
        * config/arm/pe.h (SUBTARGET_CPP_SPEC): Remove __declspec support.
-       * config/arm/symbian. (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define.
+       * config/arm/symbian.h (TARGET_DLLIMPORT_DECL_ATTRIBUTES): Define.
        * config/i386/beof-elf.h (TARGET_OS_CPP_BUILTINS): Remove
        __declspec support.
        (TARGET_DECLSPEC): Define.
index 5e5bbad319d0016a43175da5ca28ba60ca461f46..c3dc4ea6359ce357481aaa5c21636c4d3c9cd36d 100644 (file)
@@ -4600,6 +4600,42 @@ handle_visibility_attribute (tree *node, tree name, tree args,
   return NULL_TREE;
 }
 
+/* Determine the ELF symbol visibility for DECL, which is either a
+   variable or a function.  It is an error to use this function if a
+   definition of DECL is not available in this translation unit.
+   Returns true if the final visibility has been determined by this
+   function; false if the caller is free to make additional
+   modifications.  */
+
+bool
+c_determine_visibility (tree decl)
+{
+  my_friendly_assert (TREE_CODE (decl) == VAR_DECL
+                     || TREE_CODE (decl) == FUNCTION_DECL, 
+                     20040805);
+
+  /* If the user explicitly specified the visibility with an
+     attribute, honor that.  DECL_VISIBILITY will have been set during
+     the processing of the attribute.  We check for an explicit
+     attribute, rather than just checking DECL_VISIBILITY_SPECIFIED,
+     to distinguish the use of an attribute from the use of a "#pragma
+     GCC visibility push(...)"; in the latter case we still want other
+     considerations to be able to overrule the #pragma.  */
+  if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)))
+    return true;
+
+  /* Anything that is exported must have default visibility.  */
+  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+      && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
+    {
+      DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+      DECL_VISIBILITY_SPECIFIED (decl) = 1;
+      return true;
+    }
+
+  return false;
+}
+
 /* Handle an "tls_model" attribute; arguments as in
    struct attribute_spec.handler.  */
 
index 6b9bd7559c6f8915c13d33b5b05b2b3769b22b81..e8d245c88b1407357eff7dd199d0f9a7874dbdfe 100644 (file)
@@ -654,6 +654,7 @@ extern void constant_expression_warning (tree);
 extern tree convert_and_check (tree, tree);
 extern void overflow_warning (tree);
 extern void unsigned_conversion_warning (tree, tree);
+extern bool c_determine_visibility (tree);
 
 #define c_sizeof(T)  c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 1)
 #define c_alignof(T) c_sizeof_or_alignof_type (T, ALIGNOF_EXPR, 1)
index ff535524c4e4f6a1c1e6990f1b2298f76dd491c9..c03c1262f3b5553548a4ac42a5c6db77296a7c10 100644 (file)
@@ -3000,6 +3000,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
   if (current_scope == file_scope)
     maybe_apply_pragma_weak (decl);
 
+  /* If this is a variable definition, determine its ELF visibility.  */
+  if (TREE_CODE (decl) == VAR_DECL 
+      && TREE_STATIC (decl) 
+      && !DECL_EXTERNAL (decl))
+    c_determine_visibility (decl);
+
   /* Output the assembler code and/or RTL code for variables and functions,
      unless the type is an undefined structure or union.
      If not, it will get done when the type is completed.  */
@@ -6347,6 +6353,9 @@ finish_function (void)
       && !targetm.have_ctors_dtors)
     static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
 
+  /* Finalize the ELF visibility for the function.  */
+  c_determine_visibility (fndecl);
+
   /* Genericize before inlining.  Delay genericizing nested functions
      until their parent function is genericized.  Since finalizing
      requires GENERIC, delay that as well.  */
index 8b1ae87f757eefb49b17b2d85cf52eb8a61cecd6..882824aa4ee72d4d64a4408ecb3226fe2bb47544 100644 (file)
@@ -172,7 +172,7 @@ static bool arm_cxx_cdtor_returns_this (void);
 
 \f
 /* Initialize the GCC target structure.  */
-#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
 #undef  TARGET_MERGE_DECL_ATTRIBUTES
 #define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
 #endif
@@ -2466,6 +2466,9 @@ const struct attribute_spec arm_attribute_table[] =
   { "dllimport",    0, 0, true,  false, false, NULL },
   { "dllexport",    0, 0, true,  false, false, NULL },
   { "interfacearm", 0, 0, true,  false, false, arm_handle_fndecl_attribute },
+#elif TARGET_DLLIMPORT_DECL_ATTRIBUTES
+  { "dllimport",    0, 0, false, false, false, handle_dll_attribute },
+  { "dllexport",    0, 0, false, false, false, handle_dll_attribute },
 #endif
   { NULL,           0, 0, false, false, false, NULL }
 };
index 7db549e68f31390106d3baac92f798b0540422f8..34e9457d7ce4a51e539e7245cf081feacf95eae7 100644 (file)
@@ -40,7 +40,7 @@
 
 /* Get tree.c to declare a target-specific specialization of
    merge_decl_attributes.  */
-#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#define TARGET_DLLIMPORT_DECL_ATTRIBUTES 1
 
 #undef  SUBTARGET_CPP_SPEC
 #define SUBTARGET_CPP_SPEC "-D__pe__"
index 9c2e22aa706cf3dd0587b08795e9b7d25b7a5785..bc690f74d4b89e8859a6d95e015a3a35b1f83fc3 100644 (file)
@@ -93,7 +93,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Get tree.c to declare a target-specific specialization of
    merge_decl_attributes.  */
-#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#define TARGET_DLLIMPORT_DECL_ATTRIBUTES 1
 
 /* This macro defines names of additional specifications to put in the specs
    that can be used in various specifications like CC1_SPEC.  Its definition
index aae3c7acb0f0e8e826a3071cb63574695d5949d5..4559abc26573883b241a957d928f2ed164a9fb2d 100644 (file)
@@ -205,7 +205,6 @@ extern int ix86_return_pops_args (tree, tree, int);
 extern int ix86_data_alignment (tree, int);
 extern int ix86_local_alignment (tree, int);
 extern int ix86_constant_alignment (tree, int);
-extern tree ix86_handle_dll_attribute (tree *, tree, tree, int, bool *);
 extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
 
 extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
index f05ff5e5ede975b7111609ce0e3e6675335d970d..22de6e362172bb835099338b676548426a5b38d9 100644 (file)
@@ -977,7 +977,7 @@ static void init_ext_80387_constants (void);
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
-#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
 #  undef TARGET_MERGE_DECL_ATTRIBUTES
 #  define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
 #endif
@@ -1609,9 +1609,9 @@ const struct attribute_spec ix86_attribute_table[] =
   /* Regparm attribute specifies how many integer arguments are to be
      passed in registers.  */
   { "regparm",   1, 1, false, true,  true,  ix86_handle_regparm_attribute },
-#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
-  { "dllimport", 0, 0, false, false, false, ix86_handle_dll_attribute },
-  { "dllexport", 0, 0, false, false, false, ix86_handle_dll_attribute },
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
+  { "dllimport", 0, 0, false, false, false, handle_dll_attribute },
+  { "dllexport", 0, 0, false, false, false, handle_dll_attribute },
   { "shared",    0, 0, true,  false, false, ix86_handle_shared_attribute },
 #endif
   { "ms_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute },
index f0b1aec08214bda9815f356cde84d5a7b4f04e78..08e7864371e14d8523f4b68b2088a19e3cea7f01 100644 (file)
@@ -63,80 +63,6 @@ static void i386_pe_mark_dllimport (tree);
 #define DLL_EXPORT_PREFIX "#e."
 #endif
 
-/* Handle a "dllimport" or "dllexport" attribute;
-   arguments as in struct attribute_spec.handler.  */
-tree
-ix86_handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
-                          bool *no_add_attrs)
-{
-  tree node = *pnode;
-
-  /* These attributes may apply to structure and union types being created,
-     but otherwise should pass to the declaration involved.  */
-  if (!DECL_P (node))
-    {
-      if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
-                  | (int) ATTR_FLAG_ARRAY_NEXT))
-       {
-         *no_add_attrs = true;
-         return tree_cons (name, args, NULL_TREE);
-       }
-      if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
-       {
-         warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
-         *no_add_attrs = true;
-       }
-
-      return NULL_TREE;
-    }
-
-  /* Report error on dllimport ambiguities seen now before they cause
-     any damage.  */
-  else if (is_attribute_p ("dllimport", name))
-    {
-      /* Like MS, treat definition of dllimported variables and
-        non-inlined functions on declaration as syntax errors.
-        We allow the attribute for function definitions if declared
-        inline, but just ignore it in i386_pe_dllimport_p.  */
-      if (TREE_CODE (node) == FUNCTION_DECL  && DECL_INITIAL (node)
-          && !DECL_INLINE (node))
-       {
-         error ("%Jfunction `%D' definition is marked dllimport.", node, node);
-         *no_add_attrs = true;
-       }
-
-      else if (TREE_CODE (node) == VAR_DECL)
-       {
-         if (DECL_INITIAL (node))
-           {
-             error ("%Jvariable `%D' definition is marked dllimport.",
-                    node, node);
-             *no_add_attrs = true;
-           }
-
-         /* `extern' needn't be specified with dllimport.
-            Specify `extern' now and hope for the best.  Sigh.  */
-         DECL_EXTERNAL (node) = 1;
-         /* Also, implicitly give dllimport'd variables declared within
-            a function global scope, unless declared static.  */
-         if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
-           TREE_PUBLIC (node) = 1;
-       }
-    }
-
-  /*  Report error if symbol is not accessible at global scope.  */
-  if (!TREE_PUBLIC (node)
-      && (TREE_CODE (node) == VAR_DECL
-         || TREE_CODE (node) == FUNCTION_DECL))
-    {
-      error ("%Jexternal linkage required for symbol '%D' because of "
-            "'%s' attribute.", node, node, IDENTIFIER_POINTER (name));
-      *no_add_attrs = true;
-    }
-
-  return NULL_TREE;
-}
-
 /* Handle a "shared" attribute;
    arguments as in struct attribute_spec.handler.  */
 tree
index bdf50ccfac2653762304ee970de95d3c38e005f0..69e05c89c17f85048b37ce31fef648d4286bc9cc 100644 (file)
@@ -156,7 +156,7 @@ static bool       mcore_return_in_memory    (tree, tree);
 #undef  TARGET_ASM_EXTERNAL_LIBCALL
 #define TARGET_ASM_EXTERNAL_LIBCALL    mcore_external_libcall
 
-#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
 #undef  TARGET_MERGE_DECL_ATTRIBUTES
 #define TARGET_MERGE_DECL_ATTRIBUTES   merge_dllimport_decl_attributes
 #endif
index dde4e093c50a9c94de22ebbe3814c34aae50c2a8..4e299e66c2194e699dcb331f1198316486d69c2a 100644 (file)
@@ -33,7 +33,7 @@
 
 /* Get tree.c to declare a target-specific specialization of
    merge_decl_attributes.  */
-#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#define TARGET_DLLIMPORT_DECL_ATTRIBUTES 1
 
 #define TARGET_CPU_CPP_BUILTINS()                                        \
   do                                                                     \
index 44fb4a939e288b494c2307bff54cecf8da30e9bb..53e2d92a1df5ca7b8d9656c4169572971308a821 100644 (file)
@@ -30,7 +30,7 @@
 #define SUBTARGET_CPP_SPEC ""
 
 /* Get tree.c to declare merge_dllimport_decl_attributes().  */
-#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#define TARGET_DLLIMPORT_DECL_ATTRIBUTES 1
 
 /* The Symbian OS currently does not support exception handling.  */
 #define SUBTARGET_CC1PLUS_SPEC "-fno-exceptions"
index 09f671844ae1563ce6ac0a755b0fe9acbd1fbba2..fda326ff20963f717c3269c36a6e7e96e299b1e1 100644 (file)
@@ -1,3 +1,9 @@
+2004-08-05  Mark Mitchell  <mark@codesourcery.com>
+
+       * decl.c (start_preparsed_function): Move determine_visibility
+       call.
+       * decl2.c (determine_visibility): Incorporate dllexport testing.
+
 2004-08-05  Geoffrey Keating  <geoffk@apple.com>
 
        * g++spec.c (lang_specific_driver): An -Xlinker or -Wl, option
index 9653436222609bc0da03fb92e21023d646a00200..1d5b78c12a009f5616cce699c4caafc3f22dd347 100644 (file)
@@ -9629,9 +9629,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       && lookup_attribute ("noinline", attrs))
     warning ("%Jinline function '%D' given attribute noinline", decl1, decl1);
 
-  /* Determine the ELF visibility attribute for the function.  */
-  determine_visibility (decl1);
-
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
     /* This is a constructor, we must ensure that any default args
        introduced by this definition are propagated to the clones
@@ -9769,6 +9766,12 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       fntype = TREE_TYPE (decl1);
     }
 
+  /* Determine the ELF visibility attribute for the function.  We must
+     not do this before calling "pushdecl", as we must allow
+     "duplicate_decls" to merge any attributes appropriately.  */
+  if (!DECL_CLONED_FUNCTION_P (decl1))
+    determine_visibility (decl1);
+
   /* Reset these in case the call to pushdecl changed them.  */
   current_function_decl = decl1;
   cfun->decl = decl1;
index 90f1cd176c5a039d758295078e5c3eed88dd84ca..ae4ccc871e9a2268c4b2dc75acf006e000b31486 100644 (file)
@@ -1611,7 +1611,8 @@ maybe_emit_vtables (tree ctype)
   return true;
 }
 
-/* Determine the ELF symbol visibility for DECL.  */
+/* Like c_determine_visibility, but with additional C++-specific
+   behavior.  */
 
 void
 determine_visibility (tree decl)
@@ -1621,9 +1622,14 @@ determine_visibility (tree decl)
   /* Cloned constructors and destructors get the same visibility as
      the underlying function.  That should be set up in
      maybe_clone_body.  */
-  if (DECL_CLONED_FUNCTION_P (decl))
+  my_friendly_assert (!DECL_CLONED_FUNCTION_P (decl), 20040804);
+
+  /* Give the common code a chance to make a determination.  */
+  if (c_determine_visibility (decl))
     return;
 
+  /* If DECL is a member of a class, visibility specifiers on the
+     class can influence the visibility of the DECL.  */
   if (DECL_CLASS_SCOPE_P (decl))
     class_type = DECL_CONTEXT (decl);
   else if (TREE_CODE (decl) == VAR_DECL
@@ -1643,11 +1649,16 @@ determine_visibility (tree decl)
 
   /* By default, static data members and function members receive
      the visibility of their containing class.  */
-  if (class_type
-      && (TREE_CODE (decl) == VAR_DECL 
-         || TREE_CODE (decl) == FUNCTION_DECL)
-      && !lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)))
+  if (class_type)
     {
+      if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+         && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class_type)))
+       {
+         DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+         DECL_VISIBILITY_SPECIFIED (decl) = 1;
+         return;
+       }
+
       if (TREE_CODE (decl) == FUNCTION_DECL
          && DECL_DECLARED_INLINE_P (decl)
          && visibility_options.inlines_hidden)
index 3cd779ca29dccde83aa1b5dbb261720e269ab460..a1e5300a006a730b5c15da534521649bedcfa9aa 100644 (file)
@@ -415,8 +415,12 @@ do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
 #define PIC_OFFSET_TABLE_REGNUM INVALID_REGNUM
 #endif
 
+#ifndef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#define TARGET_DLLIMPORT_DECL_ATTRIBUTES 0
+#endif
+
 #ifndef TARGET_DECLSPEC
-#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
 /* If the target supports the "dllimport" attribute, users are
    probably used to the "__declspec" syntax.  */
 #define TARGET_DECLSPEC 1
index 1b4b76b569f9efd6e3a13dc8d74d31d5f8c49a87..f563893317e12c50e97afdddf1b98478e20e70dc 100644 (file)
@@ -1610,40 +1610,49 @@ types (@pxref{Variable Attributes}, @pxref{Type Attributes}.)
 
 @item dllexport
 @cindex @code{__declspec(dllexport)}
-On Microsoft Windows targets and Symbian targets the @code{dllexport}
-attribute causes the compiler to provide a global pointer to a pointer
-in a dll, so that it can be referenced with the @code{dllimport}
-attribute. The pointer name is formed by combining @code{_imp__} and
-the function or variable name.
+On Microsoft Windows targets and Symbian OS targets the
+@code{dllexport} attribute causes the compiler to provide a global
+pointer to a pointer in a DLL, so that it can be referenced with the
+@code{dllimport} attribute.  On Microsoft Windows targets, the pointer
+name is formed by combining @code{_imp__} and the function or variable
+name.
+
+You can use @code{__declspec(dllexport)} as a synonym for
+@code{__attribute__ ((dllexport))} for compatibility with other
+compilers.
+
+On systems that support the @code{visibility} attribute, this
+attribute also implies ``default'' visibility, unless a
+@code{visibility} attribute is explicitly specified.  You should avoid
+the use of @code{dllexport} with ``hidden'' or ``internal''
+visibility; in the future GCC may issue an error for those cases.
 
-Currently, the @code{dllexport}attribute is ignored for inlined
-functions, but export can be forced by using the
-@option{-fkeep-inline-functions} flag. The attribute is also ignored for
-undefined symbols.
+Currently, the @code{dllexport} attribute is ignored for inlined
+functions, unless the @option{-fkeep-inline-functions} flag has been
+used.  The attribute is also ignored for undefined symbols.
 
 When applied to C++ classes. the attribute marks defined non-inlined
 member functions and static data members as exports. Static consts
 initialized in-class are not marked unless they are also defined
 out-of-class.
 
-On cygwin, mingw, arm-pe and sh-symbianelf targets,
-@code{__declspec(dllexport)} is recognized as a synonym for
-@code{__attribute__ ((dllexport))} for compatibility with other
-Microsoft Windows and Symbian compilers. 
-
 For Microsoft Windows targets there are alternative methods for
-including the symbol in the dll's export table such as using a
+including the symbol in the DLL's export table such as using a
 @file{.def} file with an @code{EXPORTS} section or, with GNU ld, using
 the @option{--export-all} linker flag.
 
 @item dllimport
 @cindex @code{__declspec(dllimport)}
-On Microsoft Windows and Symbian targets, the @code{dllimport}
+On Microsoft Windows and Symbian OS targets, the @code{dllimport}
 attribute causes the compiler to reference a function or variable via
-a global pointer to a pointer that is set up by the Microsoft Windows
-dll library. The pointer name is formed by combining @code{_imp__} and
-the function or variable name. The attribute implies @code{extern}
-storage.
+a global pointer to a pointer that is set up by the DLL exporting the
+symbol. The attribute implies @code{extern} storage.  On Microsoft
+Windows targets, the pointer name is formed by combining @code{_imp__}
+and the function or variable name.
+
+You can use @code{__declspec(dllimport)} as a synonym for
+@code{__attribute__ ((dllimport))} for compatibility with other
+compilers.
 
 Currently, the attribute is ignored for inlined functions. If the
 attribute is applied to a symbol @emph{definition}, an error is reported.
@@ -1657,31 +1666,27 @@ member functions and static data members as imports.  However, the
 attribute is ignored for virtual methods to allow creation of vtables
 using thunks.
 
-For Symbian targets the @code{dllimport} attribute also has another
-affect - it can cause the vtable and run-time type information for a
-class to be exported.  This happens when the class has a dllimport'ed
-constructor or a non-inline, non-pure virtual function and, for either
-of those two conditions, the class also has a inline constructor or
-destructor and has a key function that is defined in the current
-translation unit.
-
-On cygwin, mingw, arm-pe sh-symbianelf targets,
-@code{__declspec(dllimport)} is recognized as a synonym for
-@code{__attribute__ ((dllimport))} for compatibility with other
-Microsoft Windows and Symbian compilers. 
+On the SH Symbian OS target the @code{dllimport} attribute also has
+another affect - it can cause the vtable and run-time type information
+for a class to be exported.  This happens when the class has a
+dllimport'ed constructor or a non-inline, non-pure virtual function
+and, for either of those two conditions, the class also has a inline
+constructor or destructor and has a key function that is defined in
+the current translation unit.
 
 For Microsoft Windows based targets the use of the @code{dllimport}
 attribute on functions is not necessary, but provides a small
-performance benefit by eliminating a thunk in the dll. The use of the
+performance benefit by eliminating a thunk in the DLL. The use of the
 @code{dllimport} attribute on imported variables was required on older
-versions of GNU ld, but can now be avoided by passing the
-@option{--enable-auto-import} switch to ld. As with functions, using
-the attribute for a variable eliminates a thunk in the dll.
-
-One drawback to using this attribute is that a pointer to a function or
-variable marked as dllimport cannot be used as a constant address. The
-attribute can be disabled for functions by setting the
-@option{-mnop-fun-dllimport} flag.
+versions of the GNU linker, but can now be avoided by passing the
+@option{--enable-auto-import} switch to the GNU linker. As with
+functions, using the attribute for a variable eliminates a thunk in
+the DLL.
+
+One drawback to using this attribute is that a pointer to a function
+or variable marked as @code{dllimport} cannot be used as a constant
+address.  On Microsoft Windows targets, the attribute can be disabled
+for functions by setting the @option{-mnop-fun-dllimport} flag.
 
 @item eightbit_data
 @cindex eight bit data on the H8/300, H8/300H, and H8S
index 2a0147cfd4de0054b161cf625cd6e20aae21b504..a250742098c1a8eb8fdd991db9ca669c7317b1ec 100644 (file)
@@ -8338,12 +8338,16 @@ attribute is nullified by a subsequent definition.  This function may
 call @code{merge_attributes} to handle machine-independent merging.
 
 @findex TARGET_DLLIMPORT_DECL_ATTRIBUTES
-If the only target-specific handling you require is @samp{dllimport} for
-Microsoft Windows targets, you should define the macro
-@code{TARGET_DLLIMPORT_DECL_ATTRIBUTES}.  This links in a function
-called @code{merge_dllimport_decl_attributes} which can then be defined
-as the expansion of @code{TARGET_MERGE_DECL_ATTRIBUTES}.  This is done
-in @file{i386/cygwin.h} and @file{i386/i386.c}, for example.
+If the only target-specific handling you require is @samp{dllimport}
+for Microsoft Windows targets, you should define the macro
+@code{TARGET_DLLIMPORT_DECL_ATTRIBUTES} to @code{1}.  The compiler
+will then define a function called
+@code{merge_dllimport_decl_attributes} which can then be defined as
+the expansion of @code{TARGET_MERGE_DECL_ATTRIBUTES}.  You can also
+add @code{handle_dll_attribute} in the attribute table for your port
+to perform initial processing of the @samp{dllimport} and
+@samp{dllexport} attributes.  This is done in @file{i386/cygwin.h} and
+@file{i386/i386.c}, for example.
 @end deftypefn
 
 @defmac TARGET_DECLSPEC
index dd221c85ed08e7b23b9480650529b7b24f7f8b71..a04b598e47bb0e3f322951b187f087fcaea5c02b 100644 (file)
@@ -1,3 +1,30 @@
+2004-08-05  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.dg/ext/visibility/assign1.C: Use scan-hidden and
+       dg-require-visiblity.
+       * g++.dg/ext/visibility/fvisibility-inlines-hidden.C: Likewise.
+       * g++.dg/ext/visibility/fvisibility.C: Likewise.
+       * g++.dg/ext/visibility/memfuncts.C: Likewise.
+       * g++.dg/ext/visibility/new1.C: Likewise.
+       * g++.dg/ext/visibility/pragma.C: Likewise.
+       * g++.dg/ext/visibility/staticmemfuncts.C: Likewise.
+       * g++.dg/ext/visibility/virtual.C: Likewise.
+       * g++/dg/ext/visibility/visibility-1.C: Likewise.
+       * g++/dg/ext/visibility/visibility-2.C: Likewise.
+       * g++/dg/ext/visibility/visibility-3.C: Likewise.
+       * g++/dg/ext/visibility/visibility-4.C: Likewise.
+       * g++/dg/ext/visibility/visibility-5.C: Likewise.
+       * g++/dg/ext/visibility/visibility-6.C: Likewise.
+       * g++/dg/ext/visibility/visibility-7.C: Likewise.
+       * g++/dg/ext/visibility/visibility-8.C: New test.
+       * gcc.c-torture/compile/dll.x: Remove.
+       * gcc.dg/dll-2.c: Use dg-require-dll
+       * gcc.dg/visibility-10.c: New test.
+       * lib/gcc-dg.exp (dg-require-dll): Add Symbian to list of targets
+       supporting DLLs.
+       * testsuite/lib/scanasm.exp (scan_hidden): New function.
+       (scan_not_hidden): Likewise.
+
 2004-08-05  David Edelsohn  <edelsohn@gnu.org>
 
        * gcc.dg/sh4a-fprun.c: Fix dg-do typo.
index 6d7392fd04bcee628de20f4fa5e24bbecc3a1d68..cbd909ee1910a8d5cdd1dd46f96ee34de776bec0 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-require-visibility "" } */
-/* { dg-final { scan-assembler "\\.hidden.*_ZN1DaSERKS_" } } */
+/* { dg-final { scan-hidden "_ZN1DaSERKS_" } } */
 
 struct B {
   B& operator=(const B&);
index 4b610229b46c8e5469170f007d97cbd22109ecf1..2ee8f0767babbd6d02e0d5c8230baf4b17fcafb5 100644 (file)
@@ -2,7 +2,7 @@
 /* { dg-do compile } */
 /* { dg-require-visibility "" } */
 /* { dg-options "-fvisibility-inlines-hidden" } */
-/* { dg-final { scan-assembler "\\.hidden.*Foo.methodEv" } } */
+/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */
 
 class Foo
 {
index fd2c7e2fc3ebe01b21607957370402fd6dd7da52..4358d25a960f29bcc37c2a8b3bb7b1cdd6162ef9 100644 (file)
@@ -2,7 +2,7 @@
 /* { dg-do compile } */
 /* { dg-require-visibility "" } */
 /* { dg-options "-fvisibility=hidden" } */
-/* { dg-final { scan-assembler "\\.hidden.*Foo.methodEv" } } */
+/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */
 
 class Foo
 {
index 19a5c9d506b60c94ee8496e4b852f4b8f7818d12..45eb641b29e75065590dd6911eb8ff4194f613be 100644 (file)
@@ -1,7 +1,7 @@
 /* Test that setting visibility for class member functions works. */
 /* { dg-do compile } */
 /* { dg-require-visibility "" } */
-/* { dg-final { scan-assembler "\\.hidden.*Foo.methodEv" } } */
+/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */
 
 class __attribute__ ((visibility ("hidden"))) Foo
 {
index 0f0be5148da8ab76eb3ffac3fff85a0773892dad..ec201cbc20d01c05d119eb7000c06d14fca1dfb0 100644 (file)
@@ -1,7 +1,6 @@
-// { dg-require-visibility }
-// { dg-do compile }
+// { dg-require-visibility "" }
 // { dg-options "-fvisibility=hidden" }
-// { dg-final { scan-assembler-not "\\.hidden\[^\n\]*_Znwj" } }
+// { dg-final { scan-not-hidden "_Znwj" } }
 
 void f() {
   new int;
index 860b2284e1573f90ea96428aef553a0a628de1b9..98384c9c42ae7615c024e14457ba97d2142d7a03 100644 (file)
@@ -1,7 +1,7 @@
 /* Test that #pragma GCC visibility affects class members. */
 /* { dg-do compile } */
 /* { dg-require-visibility "" } */
-/* { dg-final { scan-assembler "\\.hidden.*Foo.methodEv" } } */
+/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */
 
 #pragma GCC visibility push(hidden)
 class Foo
index b49cbd5bab96094ae8ed6e15dfd798e68efccc0c..e745caa5a74545794fae040be5cfa8b2f97ac1e8 100644 (file)
@@ -1,7 +1,7 @@
 /* Test that setting visibility for static class member functions works. */
 /* { dg-do compile } */
 /* { dg-require-visibility "" } */
-/* { dg-final { scan-assembler "\\.hidden.*Foo.methodEv" } } */
+/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */
 
 class __attribute__ ((visibility ("hidden"))) Foo
 {
index 604c552bcb63282f0df5069e6a7590f9a1eb1d89..746c489d0b19607c4fe7287bdb200938d0d19cef 100644 (file)
@@ -1,7 +1,7 @@
 /* Test that setting visibility for class affects virtual table. */
 /* { dg-do compile } */
 /* { dg-require-visibility "" } */
-/* { dg-final { scan-assembler "\\.hidden.*ZTV3Foo" } } */
+/* { dg-final { scan-hidden "ZTV3Foo" } } */
 
 class __attribute__ ((visibility ("hidden"))) Foo
 {
index d579eb27206df83f2c987c1e69aef8bcafef9f1d..8ea270bf8c09a70e5ee4852dcee28ebaafa10144 100644 (file)
@@ -1,6 +1,6 @@
 /* Test visibility attribute on function definition. */
-/* { dg-do compile { target *86-*-linux* } } */
-/* { dg-final { scan-assembler "\\.hidden.*_Z3foov" } } */
+/* { dg-require-visibility "" }
+/* { dg-final { scan-hidden "_Z3foov" } } */
 
 void
 __attribute__((visibility ("hidden")))
index 89e853c4dc5ce7532a0335af6b2940648626a182..26272abb1f9026fff55841ce5f3d8bdacb8d10d8 100644 (file)
@@ -1,6 +1,6 @@
 /* Test that visibility attribute on declaration extends to definition. */
-/* { dg-do compile { target *86-*-linux* } } */
-/* { dg-final { scan-assembler "\\.hidden.*_Z3foov" } } */
+/* { dg-require-visibility "" }
+/* { dg-final { scan-hidden "_Z3foov" } } */
 
 void __attribute__((visibility ("hidden"))) foo();
 
index d0cc8912efb79eb3e3a291d4df7734afd0fc8a69..e4f499fccb011e26e688f0c80a35a7ad86f330ac 100644 (file)
@@ -1,6 +1,6 @@
 /* Test visibility attribute on forward declaration of global variable */
-/* { dg-do compile { target *86-*-linux* } } */
-/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+/* { dg-require-visibility "" }
+/* { dg-final { scan-hidden "xyzzy" } } */
 
 int
 __attribute__((visibility ("hidden")))
index d217bc9ec5dab06c4b0e71bf0e4a63d903dd7dec..f6765958709412a07c01a87f9511e1483e533423 100644 (file)
@@ -1,6 +1,6 @@
 /* Test visibility attribute on forward declaration of global variable */
-/* { dg-do compile { target *86-*-linux* } } */
-/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+/* { dg-require-visibility "" }
+/* { dg-final { scan-hidden "xyzzy" } } */
 
 extern int __attribute__ ((visibility ("hidden")))
 xyzzy;
index 9cdc8021e470df69c678b997d586c74698c32297..592529e665d6f65d323ed12060566e340639c255 100644 (file)
@@ -1,7 +1,7 @@
 /* Test visibility attribute on definition of a function that has
    already had a forward declaration. */
-/* { dg-do compile { target *86-*-linux* } } */
-/* { dg-final { scan-assembler "\\.hidden.*_Z3foov" } } */
+/* { dg-require-visibility "" }
+/* { dg-final { scan-hidden "_Z3foov" } } */
 
 void foo();
 
index 6e8f0ce1135a84ac7faf230c376c636125bcadf4..0fecf6b74e92738b89baeb42351b89e9a3ad30d2 100644 (file)
@@ -1,7 +1,7 @@
 /* Test visibility attribute on definition of global variable that has
    already had a forward declaration. */
-/* { dg-do compile { target *86-*-linux* } } */
-/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+/* { dg-require-visibility "" }
+/* { dg-final { scan-hidden "xyzzy" } } */
 
 extern int xyzzy;
 
index 40acb72463f35e60e2a4ae45f3baccbe220c928d..dbd7010d0288f820c03db7c04ee2e4f3727efc1a 100644 (file)
@@ -1,6 +1,6 @@
 /* Test warning from conflicting visibility specifications. */
-/* { dg-do compile { target *86-*-linux* } } */
-/* { dg-final { scan-assembler "\\.hidden.*xyzzy" } } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-hidden "xyzzy" } } */
 
 extern int 
 __attribute__((visibility ("hidden")))
diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-8.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-8.C
new file mode 100644 (file)
index 0000000..f648726
--- /dev/null
@@ -0,0 +1,45 @@
+// Test that a definition marked with dllexport has default
+// visibility.
+// { dg-require-visibility "" }
+// { dg-require-dll "" }
+// { dg-options "-fvisibility=hidden" }
+// { dg-final { scan-not-hidden "_ZN1A1fEv" } }
+// { dg-final { scan-not-hidden "_Z1gv" } }
+// { dg-final { scan-not-hidden "_Z1hv" } }
+// { dg-final { scan-not-hidden "_ZN1B1iEv" } }
+// { dg-final { scan-not-hidden "_ZN1B1jEv" } }
+// { dg-final { scan-not-hidden "_ZN1A1a" } }
+// { dg-final { scan-not-hidden "_ZN1B1b" } }
+// { dg-final { scan-not-hidden "k" } }
+// { dg-final { scan-not-hidden "l" } }
+
+struct __declspec(dllexport) A {
+  void f();
+  static int a;
+};
+
+void A::f() {}
+
+int A::a;
+
+__declspec(dllexport) void g() {}
+
+__declspec(dllexport) void h();
+void h() {}
+
+struct B {
+  void i();
+  __declspec(dllexport) void j();
+  __declspec(dllexport) static int b;
+};
+
+__declspec(dllexport) void B::i() {}
+
+void B::j() {}
+
+int B::b;
+
+__declspec(dllexport) int k;
+
+__declspec(dllexport) extern int l;
+int l;
diff --git a/gcc/testsuite/gcc.c-torture/compile/dll.x b/gcc/testsuite/gcc.c-torture/compile/dll.x
deleted file mode 100644 (file)
index 63a1e18..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# This test examines the attribute support for DLLs.
-# Only COFF/PE formats support DLLs, (plus, as a special case
-# the mcore-elf toolchain), so the code here tries to determine
-# the file format and decide whether the test should be marked
-# as unsupported.
-
-set torture_eval_before_compile {
-
-    if ![istarget "mcore-*-elf"] {
-       
-        set objformat [gcc_target_object_format]
-    
-        if { $objformat != "pe" } {
-            unsupported "dll.c"
-            return 1
-        }
-    }
-}
-
-return 0
index 45456ce8330249517791c382a6e6305c5e07a24f..00c683a728ca8dbca0d9f5c522f93ef8a8cf8ed3 100644 (file)
@@ -8,9 +8,7 @@
    In C, it's ok to redeclare a variable so this works for variables
    and functions.  In C++, it only works for functions.  */
 
-/* { dg-do compile { target arm*-*-pe* } } */
-/* { dg-do compile { target i?86-pc-cygwin } } */
-/* { dg-do compile { target i?86-pc-mingw* } } */
+/* { dg-require-dll } */
 
 __declspec (dllimport) int foo1 ();
 __declspec (dllexport) int foo1 ();
diff --git a/gcc/testsuite/gcc.dg/visibility-10.c b/gcc/testsuite/gcc.dg/visibility-10.c
new file mode 100644 (file)
index 0000000..d86ce1b
--- /dev/null
@@ -0,0 +1,19 @@
+/* Test that a definition marked with dllexport has default
+   visibility.  */
+/* { dg-require-visibility "" } */
+/* { dg-require-dll "" } */
+/* { dg-options "-fvisibility=hidden" } */
+/* { dg-final { scan-not-hidden "g" } } */
+/* { dg-final { scan-not-hidden "h" } } */
+/* { dg-final { scan-not-hidden "k" } } */
+/* { dg-final { scan-not-hidden "l" } } */
+
+__declspec(dllexport) void g() {}
+
+__declspec(dllexport) void h();
+void h() {}
+
+__declspec(dllexport) int k;
+
+__declspec(dllexport) extern int l;
+int l;
index 7080df8267b5f864767fd57c64bea4847d1b0fba..3f2d9aa701e5a67775a37ac7e4702ff8bdb39b6d 100644 (file)
@@ -338,8 +338,10 @@ proc dg-require-profiling { args } {
 
 proc dg-require-dll { args } {
     global target_triplet
-    # As a special case, the mcore-*-elf supports dllimport/dllexport.
-    if { [string match "mcore-*-elf" $target_triplet] } {
+    # As a special case, the mcore-*-elf supports these attributes.
+    # All Symbian OS targets also support these attributes.
+    if { [string match "mcore-*-elf" $target_triplet]
+         || [string match "*-*-symbianelf" $target_triplet]} {
        return
     }
     # PE/COFF targets support dllimport/dllexport.
index 79d93cbf089e9c7e0aad1c0089520a5f71f3eba1..9116afc1c41913b6fa16689777f35294cb171d59 100644 (file)
@@ -79,6 +79,32 @@ proc scan-assembler-not { args } {
     dg-scan "scan-assembler-not" 0 $testcase $output_file $args
 }
 
+# Check that a symbol is defined as a hidden symbol in the .s file
+# produced by the compiler.
+
+proc scan-hidden { args } {
+    upvar 2 name testcase
+    set output_file "[file rootname [file tail $testcase]].s"
+
+    set symbol [lindex $args 0]
+    set args [lreplace $args 0 0 "hidden\[ \t_\]*$symbol"]
+
+    dg-scan "scan-hidden" 1 $testcase $output_file $args
+}
+
+# Check that a symbol is not defined as a hidden symbol in the .s file
+# produced by the compiler.
+
+proc scan-not-hidden { args } {
+    upvar 2 name testcase
+    set output_file "[file rootname [file tail $testcase]].s"
+
+    set symbol [lindex $args 0]
+    set args [lreplace $args 0 0 "hidden\[ \t_\]*$symbol"]
+
+    dg-scan "scan-not-hidden" 0 $testcase $output_file $args
+}
+
 # Look for a pattern in OUTPUT_FILE.  See dg-scan for details.
 
 proc scan-file { output_file args } {
index ef73afdbe6ca808f98f8d195720bdaeb61205ae5..c8153b8f535c99d2593dcf05516dcecf40349f33 100644 (file)
@@ -2887,7 +2887,7 @@ merge_decl_attributes (tree olddecl, tree newdecl)
                           DECL_ATTRIBUTES (newdecl));
 }
 
-#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
 
 /* Specialization of merge_decl_attributes for various Windows targets.
 
@@ -2940,6 +2940,81 @@ merge_dllimport_decl_attributes (tree old, tree new)
   return a;
 }
 
+/* Handle a "dllimport" or "dllexport" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+tree
+handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
+                     bool *no_add_attrs)
+{
+  tree node = *pnode;
+
+  /* These attributes may apply to structure and union types being created,
+     but otherwise should pass to the declaration involved.  */
+  if (!DECL_P (node))
+    {
+      if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
+                  | (int) ATTR_FLAG_ARRAY_NEXT))
+       {
+         *no_add_attrs = true;
+         return tree_cons (name, args, NULL_TREE);
+       }
+      if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
+       {
+         warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+         *no_add_attrs = true;
+       }
+
+      return NULL_TREE;
+    }
+
+  /* Report error on dllimport ambiguities seen now before they cause
+     any damage.  */
+  if (is_attribute_p ("dllimport", name))
+    {
+      /* Like MS, treat definition of dllimported variables and
+        non-inlined functions on declaration as syntax errors.  We
+        allow the attribute for function definitions if declared
+        inline.  */
+      if (TREE_CODE (node) == FUNCTION_DECL  && DECL_INITIAL (node)
+          && !DECL_DECLARED_INLINE_P (node))
+       {
+         error ("%Jfunction `%D' definition is marked dllimport.", node, node);
+         *no_add_attrs = true;
+       }
+
+      else if (TREE_CODE (node) == VAR_DECL)
+       {
+         if (DECL_INITIAL (node))
+           {
+             error ("%Jvariable `%D' definition is marked dllimport.",
+                    node, node);
+             *no_add_attrs = true;
+           }
+
+         /* `extern' needn't be specified with dllimport.
+            Specify `extern' now and hope for the best.  Sigh.  */
+         DECL_EXTERNAL (node) = 1;
+         /* Also, implicitly give dllimport'd variables declared within
+            a function global scope, unless declared static.  */
+         if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
+           TREE_PUBLIC (node) = 1;
+       }
+    }
+
+  /*  Report error if symbol is not accessible at global scope.  */
+  if (!TREE_PUBLIC (node)
+      && (TREE_CODE (node) == VAR_DECL
+         || TREE_CODE (node) == FUNCTION_DECL))
+    {
+      error ("%Jexternal linkage required for symbol '%D' because of "
+            "'%s' attribute.", node, node, IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 #endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES  */
 \f
 /* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
index 49fcd0debb231e77522d9356192177b1df74d2e1..8bd1219240b4c2db006fd66c52bed6d618a2cd5f 100644 (file)
@@ -2894,10 +2894,13 @@ extern tree lookup_attribute (const char *, tree);
 
 extern tree merge_attributes (tree, tree);
 
-#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
 /* Given two Windows decl attributes lists, possibly including
    dllimport, return a list of their union .  */
 extern tree merge_dllimport_decl_attributes (tree, tree);
+
+/* Handle a "dllimport" or "dllexport" attribute.  */
+extern tree handle_dll_attribute (tree *, tree, tree, int, bool *);
 #endif
 
 /* Check whether CAND is suitable to be returned from get_qualified_type